Simulation Framework (Backtest)
Fill Probability
For a limit order at distance \(\delta\) from mid, with base intensity \(\lambda_t\):
\[p_{\text{fill}} = 1 - \exp(-\lambda_t e^{-k\delta} \Delta t)\]
Fill events are independent Bernoulli trials per side per tick.
Implementation: engine::backtest
Terminal Liquidation
At \(t = T\), remaining inventory can be liquidated by crossing the spread:
\[X_T = X_{T^-} + q_T(S_T - \delta_{\text{liq}})\]
The liquidation_half_spread parameter is passed externally (e.g. to
run_backtest_with_liquidation). In solver models with
TerminalCondition::LiquidationCost, the terminal value function is
\(V(T,q) = -|q| \cdot \text{base_spread}\) where
\(\text{base_spread} = \frac{1}{\gamma}\ln(1 + \frac{\gamma}{k})\).
Implementation:
engine::backtest,
solver::models
PnL Decomposition
\[ \begin{aligned} \text{PnL}\_\text{spread} &= \sum_{i=1}^{N_{\text{fills}}} (P_i - S_{t_i}) \\ \text{PnL}\_\text{dir} &= \sum_{t=1}^T q_{t-1}(S_t - S_{t-1}) \end{aligned} \]
PnL_spread uses signed edge: positive when filled passively (bought below mid / sold above mid), negative when filled aggressively (crossed the spread). Terminal liquidation cost is subtracted from PnL_spread.
Implementation: engine::backtest
Sharpe Ratio
The Sharpe ratio [@sharpe1966mutual] is the standard risk-adjusted return metric. For backtest robustness, the Sortino ratio [@sortino1994performance] (penalizing only downside deviation) is also available.
\[\text{SR} = \frac{\bar{R}}{\sigma_R}, \qquad \bar{R} = \frac{1}{K}\sum_{k=1}^K R_k, \qquad \sigma_R = \sqrt{\frac{1}{K}\sum_{k=1}^K (R_k - \bar{R})^2}\]
Hawkes Matcher Parameters
The StochasticMatcher with Hawkes uses the fluid limit for intensity evolution
[@hawkes2018hawkes]:
\[\frac{d\lambda_t}{dt} = \beta(\lambda_\infty - \lambda_t) + \alpha\lambda_t\]
Bilateral variant tracks separate \(\lambda_t^b\), \(\lambda_t^a\) with independent self-excitation on fill events.
Implementation: engine::matcher::stochastic