# How the Telegraph Process Models Jump-Diffusion for Options Pricing in optionstratlib

> Discover how the telegraph process models jump-diffusion for options pricing. Learn about abrupt asset price changes and Markov chains in optionstratlib without complex machinery.

- Repository: [Joaquin Bejar Garcia/optionstratlib](https://github.com/joaquinbejar/optionstratlib)
- Tags: deep-dive
- Published: 2026-03-04

---

**The telegraph process models jump-diffusion for options pricing by switching between high and low volatility regimes via a continuous-time two-state Markov chain, creating abrupt changes in asset price trajectories without requiring Lévy process machinery.**

The `optionstratlib` Rust library implements a novel approach to stochastic volatility modeling through the telegraph process, which provides a computationally tractable alternative to traditional jump-diffusion models. By treating volatility as a regime-switching process rather than a continuous stochastic variable, this implementation in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) captures sudden market shifts while maintaining analytical simplicity. Understanding how the telegraph process models jump-diffusion for options pricing enables quantitative analysts to simulate realistic price paths that exhibit both continuous diffusion and discrete jumps.

## Two-State Markov Chain Foundation

### State Definitions and Transition Rates

The telegraph process operates through a continuous-time two-state Markov chain defined by:

- **State `+1`** – Represents the high-volatility regime
- **State `-1`** – Represents the low-volatility regime

The regime switches occur according to exponential waiting times governed by two transition rates:

- **`lambda_up`** – The rate of transition from state `-1` to `+1`
- **`lambda_down`** – The rate of transition from state `+1` to `-1`

Higher transition rates increase the frequency of regime switches, effectively creating the "jump" component in the jump-diffusion framework.

### Core Data Structure in telegraph.rs

The `TelegraphProcess` struct in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) encapsulates this state machine:

```rust
pub struct TelegraphProcess {
    lambda_up: Decimal,   // transition rate from -1 → +1
    lambda_down: Decimal, // transition rate from +1 → -1
    current_state: i8,    // -1 or +1
}

```

[TelegraphProcess struct source](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs#L103-L115)

## State Evolution and Transition Probabilities

### The next_state Method

State transitions follow an exponential distribution where the probability of changing states within a time step `dt` is:

\[
P(\text{change}) = 1 - e^{-\lambda \, dt}
\]

The `next_state` method in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) implements this logic:

```rust
pub fn next_state(&mut self, dt: Decimal) -> i8 {
    let lambda = if self.current_state == 1 {
        self.lambda_down
    } else {
        self.lambda_up
    };
    let lambda_dt = -lambda * dt;
    let probability = if lambda_dt < dec!(11.7) {
        Decimal::ONE
    } else {
        Decimal::ONE - lambda_dt.exp()
    };
    if random::<f64>() < probability.to_f64().unwrap() {
        self.current_state *= -1;
    }
    self.current_state
}

```

[State update source](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs#L138-L165)

## Embedding Jump-Diffusion in Price Paths

### The telegraph Monte-Carlo Simulation

The `telegraph` function in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) embeds the regime-switching mechanism into asset price simulation. It treats the current state as a **volatility multiplier**: state `+1` multiplies volatility by `+1`, while state `-1` multiplies it by `-1`, effectively flipping the sign of the diffusion term.

```rust
let state = telegraph_process.next_state(dt);
let drift = option.risk_free_rate - dec!(0.5) * option.implied_volatility.powi(2);
let volatility = option.implied_volatility.to_dec() * Decimal::from_f64(state as f64).unwrap();

let rh = Decimal::from_f64(dt.sqrt().unwrap().to_f64().unwrap() * random::<f64>()).unwrap();
let lhs = drift * dt + volatility;
let update = (lhs * rh).exp();
price *= update;

```

[Price update source](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs#L28-L36)

Because the volatility sign flips at random exponentially-distributed times, the resulting log-price behaves like a **jump-diffusion**: a continuous diffusion component punctuated by discrete regime switches that cause sudden changes in the asset price trajectory.

## Automatic Parameter Estimation

### Estimating lambda_up and lambda_down

When transition rates are not explicitly provided, `optionstratlib` estimates them from historical return data through the `estimate_telegraph_parameters` function:

1. **Classification**: Each return is classified as `+1` (return > threshold) or `-1` (return ≤ threshold)
2. **Duration tracking**: The algorithm records the duration (in steps) of consecutive identical states
3. **Rate calculation**: 
   - `λ_up = N_down / Σ(duration_down)`
   - `λ_down = N_up / Σ(duration_up)`

The implementation in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs):

```rust
let lambda_up = Decimal::ONE / sum_down * Decimal::from_usize(down_durations.len()).unwrap();
let lambda_down = Decimal::ONE / sum_up * Decimal::from_usize(up_durations.len()).unwrap();

```

[Estimator source](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs#L64-L67)

## Implementation Workflow

To utilize the telegraph process for jump-diffusion options pricing in `optionstratlib`:

1. **Initialize** a `TelegraphProcess` with explicit `lambda_up` and `lambda_down` values, or allow automatic estimation from historical data
2. **Configure** the `Options` struct with standard parameters (strike, volatility, risk-free rate, etc.)
3. **Execute** the `telegraph` Monte-Carlo simulation, which:
   - Updates the volatility regime each time step `dt` using `next_state`
   - Applies drift-volatility steps conditioned on the current regime
   - Compounds price updates to generate the final trajectory
4. **Discount** the terminal payoff at the risk-free rate to obtain the option price

## Summary

- The **telegraph process** in `optionstratlib` implements jump-diffusion through a two-state Markov chain that switches between high and low volatility regimes
- **Transition rates** `lambda_up` and `lambda_down` control the frequency of regime switches, with higher rates producing more frequent "jumps" in volatility
- The `next_state` method in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) implements exponential waiting times for realistic state transitions
- **Monte-Carlo integration** treats the state as a volatility multiplier, flipping the diffusion term's sign to create discontinuous price paths
- **Automatic parameter estimation** derives transition rates from historical return classifications when explicit values are not provided

## Frequently Asked Questions

### What is the telegraph process in options pricing?

The telegraph process is a stochastic model that represents asset price dynamics as a two-state Markov chain switching between distinct volatility regimes. Unlike continuous stochastic volatility models, it creates jump-diffusion effects through discrete regime transitions, making it computationally tractable while capturing sudden market shifts. In `optionstratlib`, this is implemented in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs) as the `TelegraphProcess` struct.

### How does the telegraph process differ from standard jump-diffusion models?

Standard jump-diffusion models typically add a Poisson jump process to geometric Brownian motion, creating random discontinuities in price levels. The telegraph process achieves similar price trajectory characteristics through **regime-switching volatility** rather than direct price jumps. By flipping the sign of the volatility multiplier between `+1` and `-1` states, it creates sudden changes in the diffusion direction, effectively simulating jump-like behavior while maintaining a simpler mathematical structure that avoids Lévy process machinery.

### Can the telegraph process parameters be estimated from historical data?

Yes, `optionstratlib` provides automatic parameter estimation through the `estimate_telegraph_parameters` function in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs). When transition rates `lambda_up` and `lambda_down` are not explicitly provided to the `telegraph` pricing function, the library classifies historical returns into `+1` and `-1` states based on a threshold, measures the duration of consecutive regimes, and calculates the transition rates as the inverse of mean state durations. This allows the model to adapt to empirical market data without manual calibration.

### Where is the telegraph process implemented in optionstratlib?

The core implementation resides in [`src/pricing/telegraph.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/pricing/telegraph.rs), which contains the `TelegraphProcess` struct, the `next_state` method for Markov chain evolution, the `telegraph` Monte-Carlo pricing function, and the `estimate_telegraph_parameters` utility. The process integrates with the broader simulation framework through `WalkType::Telegraph` defined in [`src/simulation/traits.rs`](https://github.com/joaquinbejar/optionstratlib/blob/main/src/simulation/traits.rs), allowing it to be used within unified pricing engines alongside other stochastic models.