- Introduction
- Features
- Project Structure
- Core Components
- Strategies Classification
- Setup Instructions
- Library Usage
- Usage Examples
- Testing
- Contribution and Contact
OptionStratLib is a comprehensive Rust library for options trading and strategy development across multiple asset classes. This versatile toolkit enables traders, quants, and developers to model, analyze, and visualize options strategies with a robust, type-safe approach. The library focuses on precision with decimal-based calculations, extensive test coverage, and a modular architecture.
- Valuation Models:
- Black-Scholes model for European options pricing
- Binomial tree model for American and European options
- Monte Carlo simulations for complex pricing scenarios
- Telegraph process model for advanced stochastic modeling
- Greeks Calculation:
- Delta, gamma, theta, vega, and rho calculations
- Custom Greeks implementation with adjustable parameters
- Greeks visualization for risk analysis
- Sensitivity analysis tools
- Option Types:
- European and American options
- Calls and puts with customizable parameters
- Support for exotic options (Asian, Barrier, Binary, etc.)
- Comprehensive validation and error handling
- Volatility Models:
- Constant volatility implementation
- EWMA (Exponentially Weighted Moving Average)
- GARCH implementation for volatility forecasting
- Heston stochastic volatility model
- Volatility surface interpolation techniques
- Option Chain Management:
- Chain construction and analysis tools
- Strike price generation algorithms
- Chain data import/export (CSV/JSON)
- Filtering and selection tools
- Trading Strategies:
- Bull Call/Put Spreads
- Bear Call/Put Spreads
- Butterfly Spreads (Long/Short)
- Iron Condor/Butterfly
- Straddles and Strangles
- Covered Calls and Protective Puts
- Strategy optimization framework
- Custom strategy development tools
- Risk Management:
- SPAN margin calculation
- Position tracking and management
- Break-even analysis
- Profit/Loss calculations at various price points
- Risk profiles and visualizations
- Simulation Tools:
- Random Walk simulation
- Telegraph process implementation
- Monte Carlo methods for scenario analysis
- Custom simulation frameworks for strategy testing
- Parametrized simulations with adjustable inputs
- Visualization:
- Strategy payoff diagrams
- Greeks visualization
- Binomial trees
- Risk profiles
- Interactive charts (powered by
plotly.rs) - Robust generation of various plot types (scatter, surface) for different data representations
- Comprehensive test coverage for visualization components, ensuring reliability
- Data Management:
- CSV/JSON import/export functionality
- Option chain data handling and processing
- Historical data analysis tools
- Price series management and manipulation
- Efficient decimal-based storage
- Geometry and Curve Tools:
- Curve interpolation techniques
- Surface construction and analysis
- 3D visualization of option surfaces
- Custom geometric operations
- Backtesting (In Development):
- Historical strategy performance evaluation
- Parameter optimization
- Performance metrics calculation
- Performance Metrics (In Development):
- Sharpe ratio, Sortino ratio
- Maximum drawdown analysis
- Win/loss ratio calculations
- Return distributions
The project is organized into the following key modules:
- Model (
model/):
option.rs: Core option structures and methodsposition.rs: Position managementexpiration.rs: Expiration date handlingpositive.rs: Non-negative number type implementationtypes.rs: Common enums and types
- Pricing Models (
pricing/):
binomial_model.rs: Binomial tree implementationblack_scholes_model.rs: Black-Scholes pricingmonte_carlo.rs: Monte Carlo simulationstelegraph.rs: Telegraph process modelpayoff.rs: Payoff function implementations
- Greeks (
greeks/):
- Base trait definition for Greeks calculations
- Implementation for different option models
- Sensitivity analysis tools
- Volatility (
volatility/):
constant.rs: Constant volatility modelewma.rs: EWMA implementationgarch.rs: GARCH modelheston.rs: Heston modelsurface.rs: Volatility surface handlingtraits.rs: Common interfaces for volatility models
- Strategies (
strategies/):
base.rs: Strategy base traits and interfaces- Individual strategy implementations:
bear_put_spread.rs,bull_call_spread.rs, etc.build/: Strategy construction toolscustom.rs: Custom strategy frameworkprobabilities/: Probability analysis for strategies
- Risk Management (
risk/):
span.rs: SPAN margin calculationmargin.rs: Margin requirements computationposition.rs: Position risk metrics
- Simulation (
simulation/):
random_walk.rs: Random walk implementationstelegraph.rs: Telegraph process modelingmonte_carlo.rs: Monte Carlo simulation toolssteps/: Step generation for simulationsparams.rs: Simulation parameters
- Visualization (
visualization/):
plotly.rs: Plotly integration for interactive charts- Graph trait implementations
- Utility functions for visualization
- Geometrics (
geometrics/):
construction/: Tools for building geometric structuresinterpolation/: Interpolation techniquesanalysis/: Analysis tools for curves and surfacesvisualization/: Visualization of geometric structures
- Error Handling (
error/):
- Comprehensive error types for each module
- Error propagation and handling utilities
classDiagram
class Options {
+option_type: OptionType
+side: Side
+underlying_symbol: String
+strike_price: Positive
+expiration_date: ExpirationDate
+implied_volatility: Positive
+quantity: Positive
+underlying_price: Positive
+risk_free_rate: Decimal
+option_style: OptionStyle
+dividend_yield: Positive
+exotic_params: Option~ExoticParams~
+calculate_price_black_scholes()
+calculate_price_binomial()
+time_to_expiration()
+is_long()
+is_short()
+validate()
+to_plot()
+calculate_implied_volatility()
+delta()
+gamma()
+theta()
+vega()
+rho()
}
class Position {
+option: Options
+position_cost: Positive
+entry_date: DateTime<Utc>
+open_fee: Positive
+close_fee: Positive
+net_cost()
+net_premium_received()
+unrealized_pnl()
+pnl_at_expiration()
+validate()
}
class ExpirationDate {
+Days(Positive)
+Date(NaiveDate)
+get_years()
+get_date()
+get_date_string()
+from_string()
}
class Positive {
+value: Decimal
+ZERO: Positive
+ONE: Positive
+format_fixed_places()
+round_to_nice_number()
+is_positive()
}
class OptionStyle {
<<enumeration>>
Call
Put
}
class OptionType {
<<enumeration>>
European
American
}
class Side {
<<enumeration>>
Long
Short
}
class Graph {
<<interface>>
+graph_data()
+graph_config()
+to_plot()
+write_html()
+write_png()
+write_svg()
+write_jpeg()
}
class Greeks {
<<interface>>
+delta()
+gamma()
+theta()
+vega()
+rho()
+calculate_all_greeks()
}
Options --|> Greeks : implements
Options --|> Graph : implements
Position o-- Options : contains
Options *-- OptionStyle : has
Options *-- OptionType : has
Options *-- Side : has
Options *-- ExpirationDate : has
Options *-- Positive : uses
classDiagram
class Strategy {
+name: String
+strategy_type: StrategyType
+description: String
+legs: Vec~Position~
+new()
+validate()
+add_leg()
}
class Strategies {
<<interface>>
+get_volume()
+get_net_premium_received()
+get_max_profit()
+get_max_loss()
+get_profit_ratio()
+get_profit_area()
+get_break_even_points()
+get_fees()
+get_title()
+get_profit_loss_at_price()
+get_positions()
+get_options()
}
class BullCallSpread {
+underlying_symbol: String
+underlying_price: Positive
+long_call: Position
+short_call: Position
+new()
+validate()
}
class BearPutSpread {
+underlying_symbol: String
+underlying_price: Positive
+long_put: Position
+short_put: Position
+new()
+validate()
}
class LongCall {
+underlying_symbol: String
+underlying_price: Positive
+long_call: Position
+new()
+validate()
}
class LongPut {
+underlying_symbol: String
+underlying_price: Positive
+long_put: Position
+new()
+validate()
}
class ShortCall {
+underlying_symbol: String
+underlying_price: Positive
+short_call: Position
+new()
+validate()
}
class ShortPut {
+underlying_symbol: String
+underlying_price: Positive
+short_put: Position
+new()
+validate()
}
class IronCondor {
+underlying_symbol: String
+underlying_price: Positive
+long_put: Position
+short_put: Position
+short_call: Position
+long_call: Position
+new()
+validate()
}
class BasicAble {
<<interface>>
+get_underlying_symbol()
+get_underlying_price()
+one_option()
}
class BreakEvenable {
<<interface>>
+get_break_even_points()
+get_profit_loss_zones()
}
class Validable {
<<interface>>
+validate()
}
class Optimizable {
<<interface>>
+get_best_ratio()
+get_best_profit()
+get_best_loss()
+get_best_premium()
+find_optimal()
}
Strategy ..|> Strategies : implements
BullCallSpread ..|> Strategies : implements
BearPutSpread ..|> Strategies : implements
LongCall ..|> Strategies : implements
LongPut ..|> Strategies : implements
ShortCall ..|> Strategies : implements
ShortPut ..|> Strategies : implements
IronCondor ..|> Strategies : implements
Strategies ..> BasicAble : requires
Strategies ..> BreakEvenable : requires
Strategies ..> Validable : requires
Optimizable ..> Validable : requires
Optimizable ..> Strategies : requires
classDiagram
class StrategyType {
<<enumeration>>
Custom
BullCallSpread
BearPutSpread
LongCall
LongPut
ShortCall
ShortPut
CallButterfly
LongButterflySpread
ShortButterflySpread
IronButterfly
IronCondor
Straddle
LongStraddle
ShortStraddle
Strangle
LongStrangle
ShortStrangle
CoveredCall
ProtectivePut
PoorMansCoveredCall
Collar
}
class DirectionalBias {
<<enumeration>>
Bullish
Bearish
Neutral
}
class VolatilityOutlook {
<<enumeration>>
High
Low
Neutral
}
class ComplexityLevel {
<<enumeration>>
Basic
Intermediate
Advanced
}
class RiskProfile {
<<enumeration>>
DefinedRisk
UndefinedRisk
LimitedProfit
UnlimitedProfit
}
DirectionalBias <-- StrategyType : categorized by
VolatilityOutlook <-- StrategyType : categorized by
ComplexityLevel <-- StrategyType : categorized by
RiskProfile <-- StrategyType : categorized by
class BullishStrategies {
BullCallSpread
LongCall
CoveredCall
PoorMansCoveredCall
}
class BearishStrategies {
BearPutSpread
LongPut
ShortCall
}
class NeutralStrategies {
IronCondor
IronButterfly
ButterflySpread
Straddle
Strangle
}
class HighVolatilityStrategies {
LongStraddle
LongStrangle
LongCall
LongPut
}
class LowVolatilityStrategies {
ShortStraddle
ShortStrangle
IronCondor
ButterflySpread
CoveredCall
}
DirectionalBias <.. BullishStrategies : implements
DirectionalBias <.. BearishStrategies : implements
DirectionalBias <.. NeutralStrategies : implements
VolatilityOutlook <.. HighVolatilityStrategies : implements
VolatilityOutlook <.. LowVolatilityStrategies : implements
- Rust 1.65 or higher
- Cargo
Add OptionStratLib to your Cargo.toml:
[dependencies]
optionstratlib = "0.5.1"Or use cargo to add it to your project:
cargo add optionstratlibThe library includes several optional features that can be enabled:
[dependencies]
optionstratlib = { version = "0.5.1", features = ["plotly", "kaleido", "full"] }plotly: Enables visualization using plotly.rskaleido: Enables saving static images (requires plotly)full: Enables all features
Clone the repository and build using Cargo:
git clone https://github.com/joaquinbejar/OptionStratLib.git
cd OptionStratLib
cargo build --releaseRun tests:
cargo test --all-featuresGenerate documentation:
cargo doc --openuse optionstratlib::{Options, OptionStyle, OptionType, Side, ExpirationDate};
use optionstratlib::pos;
use rust_decimal_macros::dec;
use tracing::info;
use optionstratlib::greeks::Greeks;
// Create a basic European call option
let option = Options::new(
OptionType::European,
Side::Long,
"AAPL".to_string(),
pos!(100.0), // strike_price
ExpirationDate::Days(pos!(30.0)),
pos!(0.2), // implied_volatility
pos!(1.0), // quantity
pos!(105.0), // underlying_price
dec!(0.05), // risk_free_rate
OptionStyle::Call,
pos!(0.02), // dividend_yield
None, // exotic_params
);
// Calculate option price using Black-Scholes
let price = option.calculate_price_black_scholes().unwrap();
info!("Option price: {}", price);
// Calculate Greeks
let delta = option.delta().unwrap();
let gamma = option.gamma().unwrap();
let theta = option.theta().unwrap();
info!("Delta: {}, Gamma: {}, Theta: {}", delta, gamma, theta);use optionstratlib::{Positive, ExpirationDate, pos};
use optionstratlib::strategies::Strategies;
use optionstratlib::strategies::bull_call_spread::BullCallSpread;
use optionstratlib::visualization::Graph;
use rust_decimal_macros::dec;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
use tracing::info;
use optionstratlib::strategies::base::BreakEvenable;
use optionstratlib::strategies::BasicAble;
let underlying_price = pos!(5781.88);
// Create a Bull Call Spread strategy
let strategy = BullCallSpread::new("SP500".to_string(), underlying_price, pos!(5750.0), pos!(5820.0), ExpirationDate::Days(pos!(2.0)), pos!(0.18), dec!(0.01), pos!(0.78), pos!(0.78), pos!(0.73), pos!(0.73), Default::default(), Default::default(), Default::default(), Default::default());
// Get information about the strategy
info!("Title: {}", strategy.get_title());
info!("Break Even Points: {:?}", strategy.get_break_even_points()?);
info!("Net Premium Received: ${:.2}", strategy.get_net_premium_received()?);
info!("Max Profit: ${:.2}", strategy.get_max_profit().unwrap_or(Positive::ZERO));
info!("Max Loss: ${:0.2}", strategy.get_max_loss().unwrap_or(Positive::ZERO));
info!("Total Fees: ${:.2}", strategy.get_fees()?);
info!("Profit Area: {:.2}%", strategy.get_profit_area()?);
info!("Profit Ratio: {:.2}%", strategy.get_profit_ratio()?);
// Generate visualization and save to HTML file
#[cfg(feature = "static_export")]
{
let file_path = "Draws/Strategy/bull_call_spread_profit_loss_chart.html".as_ref();
strategy.write_html(file_path)?;
}
Ok(())
}use optionstratlib::visualization::{Graph, GraphData, Series2D, TraceMode, GraphConfig};
use optionstratlib::error::GraphError;
use std::path::PathBuf;
use rust_decimal_macros::dec;
struct SimpleChart {
series: Series2D
}
impl Graph for SimpleChart {
fn graph_data(&self) -> GraphData {
GraphData::Series(self.series.clone())
}
fn graph_config(&self) -> GraphConfig {
use optionstratlib::visualization::{ColorScheme, LineStyle};
GraphConfig {
title: "Interactive Chart Example".into(),
width: 800,
height: 600,
x_label: Some("X Axis".into()),
y_label: Some("Y Axis".into()),
z_label: None,
line_style: LineStyle::Solid,
color_scheme: ColorScheme::Viridis,
legend: Some(vec!["My Data".to_string()]),
show_legend: true,
}
}
}
fn main() -> Result<(), GraphError> {
let series = Series2D {
x: vec![dec!(1.0), dec!(2.0), dec!(3.0)],
y: vec![dec!(4.0), dec!(5.0), dec!(6.0)],
name: "Series 1".to_string(),
mode: TraceMode::Lines,
line_color: Some("#1f77b4".to_string()),
line_width: Some(2.0),
};
#[cfg(feature = "static_export")]
{
let chart = SimpleChart { series };
let filename: PathBuf = PathBuf::from("interactive_chart.html");
chart.write_html(&filename)?;
}
Ok(())
}To run the test suite:
make testFor running tests with specific features:
cargo test --features "plotly kaleido"To generate a test coverage report:
make coverageWe welcome contributions to this project! If you would like to contribute, please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bug fix.
- Make your changes and ensure that the project still builds and all tests pass.
- Commit your changes and push your branch to your forked repository.
- Submit a pull request to the main repository.
If you have any questions, issues, or would like to provide feedback, please feel free to contact the project maintainer:
Joaquín Béjar García
- Email: jb@taunais.com
- GitHub: joaquinbejar
We appreciate your interest and look forward to your contributions!
Licensed under MIT license
