Exit Policies in the Monte Carlo Simulation Module: A Complete Guide to optionstratlib
The optionstratlib crate supports 16 distinct exit policy variants—including profit targets, stop losses, time limits, underlying price triggers, and composite AND/OR logic—for controlling when positions close during Monte Carlo strategy simulations.
The Monte Carlo simulation engine in joaquinbejar/optionstratlib provides robust risk management through configurable exit policies defined in src/simulation/exit.rs. These policies determine exactly when a position should be closed during strategy testing, allowing traders to model stop-loss, take-profit, and time-decay scenarios with precision. Understanding the available exit policies in the Monte Carlo simulation module is essential for building realistic backtests and optimizing option strategies.
What Are Exit Policies in Monte Carlo Simulation?
Exit policies are rules that trigger the automatic closure of an option position during a Monte Carlo simulation run. In optionstratlib, the core ExitPolicy enum defines these triggers, and the check_exit_policy function evaluates them against the current simulation state—including initial premium, current premium, step number, days to expiration, and underlying price.
When a policy condition is met, the simulation loop records the exit reason and halts further price updates for that position, capturing the profit or loss at that exact moment.
Supported Exit Policy Variants in optionstratlib
The ExitPolicy enum in src/simulation/exit.rs provides 16 variants organized into profit/loss controls, price thresholds, time constraints, underlying asset conditions, and composite logic.
Profit and Loss Controls
ProfitPercent closes positions when profit reaches a specified percentage of the initial premium. For long positions, the trigger is current ≥ initial × (1 + pct); for short positions, current ≤ initial × (1 - pct).
LossPercent acts as a stop-loss, closing when loss exceeds a percentage of the initial premium. For long positions: current ≤ initial × (1 - pct); for short: current ≥ initial × (1 + pct).
Price-Based Triggers
FixedPrice exits when the option premium hits an exact target price within a $0.01 tolerance: |current - price| < 0.01.
MinPrice closes when the premium falls below a specified floor: current ≤ price.
MaxPrice closes when the premium rises above a specified ceiling: current ≥ price.
Time-Based Constraints
TimeSteps exits after a specific number of simulation steps: step_num ≥ steps.
DaysToExpiration closes when remaining days to expiration drop below a threshold: days_left ≤ days.
Underlying Asset Conditions
UnderlyingPrice triggers when the underlying asset price matches a target within $0.01: |underlying - price| < 0.01.
UnderlyingBelow closes when the underlying falls below a level: underlying < price.
UnderlyingAbove closes when the underlying rises above a level: underlying > price.
Special and Composite Policies
Expiration holds the position until expiration with no automatic trigger. The check_exit_policy function returns None for this variant, allowing the simulation to run its full course.
DeltaThreshold is reserved for delta-based exits but is not yet implemented in the current version—check_exit_policy always returns None for this variant.
And creates a composite policy requiring all enclosed policies to trigger simultaneously. The function recursively checks each child policy and returns None if any fail.
Or creates a composite policy where any one enclosed policy triggers an exit. The function returns the first child policy that evaluates to Some.
How Exit Policies Work Under the Hood
The evaluation logic resides in src/simulation/exit.rs within the check_exit_policy function (lines 34-75). This function receives the simulation context—including initial premium, current premium, step number, days remaining, underlying price, and a boolean flag indicating long or short positioning—and returns Option<ExitPolicy>.
When the returned value is Some(policy), the simulation engine in src/strategies/*.rs records the exit reason and terminates the position update loop. When None is returned, the simulation continues to the next time step. Composite policies (And/Or) leverage this same mechanism through recursive evaluation, enabling complex exit logic without modifying the core simulation loop.
Practical Code Examples
1. Simple Profit Target Exit
Close the position when the trade has earned 50% of the premium paid:
use optionstratlib::simulation::ExitPolicy;
use rust_decimal_macros::dec;
let policy = ExitPolicy::ProfitPercent(dec!(0.5));
2. Stop-Loss Plus Profit Target (OR Composite)
Exit on either a 50% profit or a 100% loss (double the premium):
let policy = ExitPolicy::Or(vec![
ExitPolicy::ProfitPercent(dec!(0.5)),
ExitPolicy::LossPercent(dec!(1.0)),
]);
3. Time-Limited Trade
Combine profit target with a maximum holding period of 2,880 steps (assuming 1 step = 1 minute, this equals 2 days):
let policy = ExitPolicy::Or(vec![
ExitPolicy::ProfitPercent(dec!(0.5)),
ExitPolicy::TimeSteps(2_880),
]);
4. Underlying Price Condition (AND Composite)
Require both a 50% profit and the underlying asset falling below $3,900:
let policy = ExitPolicy::And(vec![
ExitPolicy::ProfitPercent(dec!(0.5)),
ExitPolicy::UnderlyingBelow(pos_or_panic!(3900.0)),
]);
5. Hold to Expiration
Explicitly hold the position until expiration with no automatic triggers:
let policy = ExitPolicy::Expiration;
All policies integrate directly with strategy simulation methods (e.g., short_put.simulate(), long_call.simulate()), with the engine automatically evaluating conditions at each time step.
Summary
- The
ExitPolicyenum insrc/simulation/exit.rsdefines 16 distinct exit strategies for Monte Carlo simulations inoptionstratlib. - Profit/Loss controls (
ProfitPercent,LossPercent) manage risk through percentage-based thresholds that differ for long and short positions. - Price triggers (
FixedPrice,MinPrice,MaxPrice) close positions when premiums hit specific levels. - Time constraints (
TimeSteps,DaysToExpiration) enforce maximum holding periods. - Underlying conditions (
UnderlyingPrice,UnderlyingBelow,UnderlyingAbove) link exits to asset price movements. - Composite policies (
And,Or) enable complex logic by combining multiple exit conditions recursively. - The
check_exit_policyfunction evaluates these conditions against simulation state, returningSome(policy)when triggers fire orNoneto continue the simulation.
Frequently Asked Questions
How do I combine multiple exit conditions in optionstratlib?
Use the composite And or Or variants of ExitPolicy. Wrap your individual policies in a vector and pass them to ExitPolicy::And(vec![...]) for conditions that must all trigger simultaneously, or ExitPolicy::Or(vec![...]) for conditions where any single trigger closes the position. The check_exit_policy function evaluates these recursively, making it easy to express complex risk management rules like "take profit at 50% OR stop loss at 100%."
What is the difference between TimeSteps and DaysToExpiration exit policies?
TimeSteps closes a position after a specific number of simulation iterations (e.g., 2,880 steps), regardless of calendar time, making it useful for high-frequency or intraday simulations where you control the temporal resolution. DaysToExpiration closes when the remaining days to the option's expiration date drops below a threshold, aligning with calendar-based risk management. Both are evaluated in src/simulation/exit.rs within the check_exit_policy function, but they reference different fields of the simulation state (step count vs. days remaining).
Where is the exit policy logic implemented in the source code?
The exit policy definitions and evaluation logic reside in src/simulation/exit.rs. This file contains the ExitPolicy enum with all 16 variants (including composites), the check_exit_policy function (lines 34-75) that evaluates trigger conditions against simulation state, and implementations for display formatting. Strategy implementations in src/strategies/*.rs import these types and invoke check_exit_policy within their simulation loops to determine when to close positions.
Why does the DeltaThreshold exit policy return None?
The DeltaThreshold variant is a placeholder for future functionality and is not yet implemented in the current version of optionstratlib. When check_exit_policy encounters this variant, it unconditionally returns None, meaning the policy never triggers an exit. This allows the API to reserve the variant name for future delta-greek-based risk management without breaking existing code. For delta-sensitive exits, users currently need to implement custom logic outside the standard ExitPolicy enum or monitor delta values manually within their simulation callbacks.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →