Optimal Stopping

Longstaff-Schwartz algorithm for optimal exit timing

Optimal stopping answers: given your current position and stochastic market dynamics, should you exit now or wait? Horizon implements the Longstaff-Schwartz least-squares Monte Carlo algorithm, computing the optimal exit boundary by backward regression on simulated price paths.

API

Generate simulated paths

python
paths = hz.generate_gbm_paths(
    S0=0.55,          # current price (or probability)
    mu=0.0,           # drift
    sigma=0.20,       # volatility
    T=30.0,           # time horizon (days)
    n_steps=100,      # time steps per path
    n_paths=10_000,   # number of Monte Carlo paths
)

# paths shape: (n_paths, n_steps + 1)

Longstaff-Schwartz backward regression

python
def payoff_fn(price, t):
    """Payoff from exiting at price `price` at time `t`."""
    return price - 0.55  # simple P&L from entry at 0.55

model = hz.longstaff_schwartz(
    paths=paths,
    payoff_fn=payoff_fn,
    discount=0.99,      # per-step discount factor
    n_basis=3,          # number of basis functions for regression
)

model.continuation_values  # estimated continuation values at each step
model.exercise_boundary    # price threshold per time step
model.expected_payoff      # expected payoff under optimal policy

Real-time exit decision

python
should_exit = hz.should_exit(
    current_state={"price": 0.62, "time_remaining": 15.0},
    model=model,
)

should_exit.exit       # True/False
should_exit.cont_val   # estimated value of continuing
should_exit.exit_val   # value of exiting now

How it works

The Longstaff-Schwartz algorithm works backward from expiry:

  1. At the final step, the exercise value is payoff_fn(S_T, T).
  2. At each earlier step, regress the discounted future value against basis functions of the current state (e.g., polynomials of price).
  3. The regression gives an estimate of the continuation value. Exercise whenever payoff_fn(S_t, t) > continuation_value(S_t, t).
  4. The exercise boundary is the price at each time step where the payoff equals the continuation value.

Example: exiting a prediction market position

python
# You bought YES at 0.55. When should you sell?
paths = hz.generate_gbm_paths(S0=0.55, mu=0.0, sigma=0.25, T=14.0,
                               n_steps=50, n_paths=5000)

def pnl(price, t):
    return price - 0.55

model = hz.longstaff_schwartz(paths, pnl, discount=0.995)

# Current situation: price is 0.68 with 7 days left
decision = hz.should_exit({"price": 0.68, "time_remaining": 7.0}, model)

if decision.exit:
    print(f"Exit now. Exit value: {decision.exit_val:.3f}, "
          f"continuation: {decision.cont_val:.3f}")
else:
    print(f"Hold. Continuation value {decision.cont_val:.3f} > "
          f"exit value {decision.exit_val:.3f}")

When to use

  • Profit taking: determine the price level at which taking profit now is better than waiting for more upside.
  • Stop loss placement: compute the boundary below which holding has negative expected continuation value.
  • Event markets: prediction markets with a known resolution date map directly to the finite-horizon stopping problem.
  • Options-like positions: any position with time decay or a known expiry benefits from optimal stopping analysis.

The model is most useful when the position has a finite horizon and the payoff structure is path-dependent or nonlinear.

Next