Start Here — Price, Then Differentiate

Record, Tape, Replay: Anatomy of a Run

The Java source records the selected payoff, inspects its NablaTensor tape, then replays the compiled CPU kernel over the requested scenarios.

Product
Market data
SimulationOptional

Default 20,000 scenario workload keeps browser runs interactive; the source uses the portable CPU engine.

Java source
RecordTapeReplayRiskStudio.java

This exact source runs in TeaVM. Form changes update its Java literals and reset manual edits.

import com.nablatensor.engine.AadTape;
import com.nablatensor.engine.Nabla;
import com.nablatensor.quant.EquityMarket;
import com.nablatensor.quant.Product;
import com.nablatensor.quant.Products;
import com.nablatensor.quant.TimeGrid;

public final class RecordTapeReplayRiskStudio {
  private RecordTapeReplayRiskStudio() {}

  public static void main(String[] args) {
    EquityMarket market = EquityMarket.of()
        .spot(100)
        .strike(100)
        .vol(20 / 100.0)
        .rate(3 / 100.0)
        .maturity(1)
        .build();
    Product<EquityMarket> product = Products.asianCall();
    int steps = 32;
    long scenarios = 20000L, seed = 42L;
    long start = System.nanoTime();
    Nabla.TypedModel<EquityMarket> model = Nabla.model(market, (rec, in) -> product.record(rec,
        in, TimeGrid.uniform(steps)))
        .fp64()
        .greeks()
        .on("cpu");
    double recordSeconds = (System.nanoTime() - start) / 1.0e9;
    AadTape tape = model.tape();
    int active = 0;
    for (int n = 0; n < tape.size(); n++) if (tape.isActive(n)) active++;
    System.out.println("STAGE|1|WRITE|" + product.label() + "|" + steps);
    System.out.println("STAGE|2|RECORD|" + recordSeconds);
    System.out.println("STAGE|3|TAPE|" + tape.size() + "|" + tape.inputCount() + "|" + active + "|"
        + (tape.size() - active));
    System.out.println("STAGE|4|BACKEND|cpu");
    try (Nabla.TypedPricer<EquityMarket> pricer = model.build()) {
      Nabla.TypedValuation<EquityMarket> v = pricer.value()
          .with(market)
          .scenarios(scenarios)
          .seed(seed)
          .run();
      System.out.println("STAGE|5|REPLAY|" + scenarios + "|" + seed + "|" + v.seconds() + "|" + v.scenariosPerSecond()
          + "|" + v.price());
      System.out.println("RESULT|" + recordSeconds + "|" + tape.size() + "|" + active + "|" + v.seconds()
          + "|" + v.scenariosPerSecond() + "|" + v.price());
    }
  }
}
TeaVM compiles and runs the Java source above in this browser.
Implementation guide

From valuation code to a replayable graph

A tape separates the structure of a valuation from the numerical market data fed into it on each run.

Core mechanism

During recording, each active arithmetic operation becomes a node with references to its operands. Replay evaluates that fixed operation sequence efficiently; the reverse replay walks the same sequence backwards to accumulate derivatives.

Practical workflow

Keep trade logic expressed through active values at the market-data boundary. Record once for a stable product structure, replay across scenarios, and discard or checkpoint intermediates according to the backend's memory plan.

Scope and review point

A changed control-flow path, product shape or active-input set can require a new recording. The tape is a program representation, not a substitute for product-model governance.