optopsy-mcp
Rust-based rewrite of Optopsy: An options backtesting engine exposed via Model Context Protocol (MCP)
optopsy-mcp
A high-performance options and stock backtesting engine exposed as an MCP server. Connect it to Claude Desktop, Claude Code, or any MCP-compatible client and backtest strategies, optimize parameters, and analyze price patterns through natural language.
[!NOTE]
This project is under active development. Breaking changes to the API and configuration may occur between minor versions. Pin to a specific release tag for stability.
What You Can Do
Write Custom Strategies
Describe a strategy in plain English and Claude generates a Rhai script that runs against historical data. Define entry logic, exit rules, position sizing, and stateful multi-phase strategies in a single script — or use the built-in wheel strategy script with parameter injection.
"Write a strategy that sells puts on SPY when VIX > 20 and RSI < 30, with a 50% stop loss"
"Build a custom mean-reversion strategy that buys QQQ on 3 consecutive down days and exits after a 2% gain or 5-day hold"
"Run the wheel script on SPY with 30-delta puts at 45 DTE and 25-delta calls at 30 DTE"
Backtest Options and Stocks
Run event-driven simulations across 32 built-in options strategies — singles, spreads, iron condors, butterflies, calendars, diagonals, and stock-leg combos. Signal-driven stock backtesting on OHLCV data. Full position management with stop-loss, take-profit, max-hold exits, and 5 dynamic sizing methods.
"Backtest an iron condor on SPY with $100k capital, 30-delta wings, and a 50% stop loss"
"Backtest buying SPY when RSI drops below 30 and selling when it crosses above 70"
"Run the wheel on SPY with 30-delta puts at 45 DTE and 30-delta calls at 30 DTE"
Optimize and Validate
Grid-search across delta, DTE, slippage, and signal combinations with out-of-sample validation. Walk-forward analysis with rolling train/test windows. Permutation testing for statistical significance.
"Sweep DTE and delta for short puts on SPY — find the best risk-adjusted setup"
"Run walk-forward on this strategy with 4 windows to check if it holds up over time"
"Is this backtest result statistically significant or just luck?"
Analyze Markets
Discover seasonality, regime shifts, and price patterns. Gate entries using HMM regime detection. Cross-symbol correlation, rolling metrics, and distribution analysis.
"Show me SPY's average return by day of week — are any statistically significant?"
"Only enter covered calls when SPY is in a bullish HMM regime"
"Detect volatility regimes in SPY and show when they shift"
REST API
When running in HTTP mode (PORT=8000 cargo run), a REST API is available alongside the MCP endpoint for direct integration with frontends and agents.
| Method | Endpoint | Description |
|---|---|---|
POST |
/backtests |
Run a strategy and persist the result |
GET |
/backtests |
List backtests with summary metrics (filterable by strategy, symbol) |
GET |
/backtests/{id} |
Full backtest result (same shape as MCP run_script response) |
GET |
/backtests/{id}/trades |
Trade log for a specific run |
DELETE |
/backtests/{id} |
Remove a backtest |
GET |
/strategies |
List available Rhai strategy scripts |
GET |
/prices/{symbol} |
Load OHLCV price data |
# Run a backtest
curl -X POST http://localhost:8000/backtests \
-H 'Content-Type: application/json' \
-d '{"strategy":"bb_mean_reversion","params":{"SYMBOL":"SPY","CAPITAL":100000}}'
# List all backtests
curl http://localhost:8000/backtests
# Filter by strategy
curl "http://localhost:8000/backtests?strategy=bb_mean_reversion"
Backtest results are persisted to SQLite ({DATA_ROOT}/backtests.db) for retrieval and comparison.
MCP Tools
| Tool | Description |
|---|---|
| Backtesting | |
run_script |
Execute a Rhai backtest script (strategy file or inline) |
| Statistics | |
aggregate_prices |
Time-based aggregation with significance testing |
distribution |
Distribution analysis with normality testing |
correlate |
Cross-symbol or cross-metric correlation matrices |
rolling_metric |
Rolling window calculations (Sharpe, volatility, returns, etc.) |
regime_detect |
Market regime detection (volatility clustering, trend state, HMM) |
generate_hypotheses |
Auto-scan for statistically significant patterns with FDR correction |
| Risk & Portfolio | |
drawdown_analysis |
Full drawdown distribution with episode tracking and Ulcer Index |
cointegration_test |
Engle-Granger cointegration test for pairs/stat-arb strategies |
monte_carlo |
Block-bootstrap Monte Carlo simulation with ruin probabilities |
factor_attribution |
Multi-factor regression decomposing returns into factor exposures |
portfolio_optimize |
Optimal portfolio weights via risk parity, min variance, or max Sharpe |
benchmark_analysis |
Benchmark-relative metrics: alpha, beta, Information Ratio, capture ratios |
Quick Start
git clone https://github.com/goldspanlabs/optopsy-mcp.git
cd optopsy-mcp
cargo build --release
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"optopsy": {
"command": "/path/to/optopsy-mcp/target/release/optopsy-mcp"
}
}
}
Place your Parquet data files in ~/.optopsy/cache/ before your first session — see the Data section below.
To change the cache directory, set DATA_ROOT in the config:
{
"mcpServers": {
"optopsy": {
"command": "/path/to/optopsy-mcp/target/release/optopsy-mcp",
"env": {
"DATA_ROOT": "/your/custom/cache/dir"
}
}
}
}
Key Capabilities
32 Options Strategies
Singles, verticals, straddles, strangles, butterflies, condors, iron condors/butterflies, calendars, diagonals, and stock-leg strategies (covered call, protective put) — with multi-expiration support for calendar and diagonal spreads.
4 Slippage Models
Mid, spread (bid/ask worst-case), liquidity-based (volume-scaled), and per-leg fixed.
5 Position Sizing Methods
Fixed quantity, fixed fractional, risk per trade, Kelly criterion, and volatility targeting.
Rhai Scripting Engine
Write backtests as Rhai scripts with a callback-driven API. The engine provides a BarContext (ctx) object with access to OHLCV data, pre-computed indicators (SMA, EMA, RSI, ATR, MACD, Bollinger Bands, Stochastic, CCI, OBV), options chain lookup, portfolio state, and cross-symbol data. Scripts are fully sandboxed with no file or network access.
fn config() {
#{ symbol: params.SYMBOL, capital: params.CAPITAL,
data: #{ ohlcv: true, options: true, indicators: ["rsi:14", "sma:50"] } }
}
fn on_bar(ctx) {
if ctx.position_count >= 3 { return []; }
let spread = ctx.short_put(0.30, 45);
if spread == () { return []; }
[spread]
}
fn on_exit_check(ctx, pos) {
if pos.dte <= 7 { return close_position("dte_exit"); }
hold_position()
}
32 named helpers are available (bull_put_spread, iron_condor, short_strangle, etc.) along with action builders (hold_position(), close_position(), buy_stock()). See scripts/SCRIPTING_REFERENCE.md for the full API.
A built-in wheel strategy script is included and parameterized via constant injection.
67 Indicators and Signal DSL
RSI, MACD, Stochastic, Bollinger Bands, Keltner Channels, Supertrend, ATR, OBV, MFI, IV Rank, HMM regime filter, and more. Available as pre-computed O(1) lookups in Rhai scripts (ctx.rsi(14), ctx.sma(50)) and as a formula DSL for the built-in backtest tools (rsi(close, 14) < 30 and VIX > 20).
Data
optopsy-mcp reads options chains and OHLCV prices from a local Parquet cache. Place your Parquet files directly into the cache directory — any file matching the expected schema will be picked up automatically.
The default cache directory is ~/.optopsy/cache/. To use a different location, set the DATA_ROOT environment variable.
Cache layout
~/.optopsy/cache/
├── options/ # required — options chain data
│ ├── SPY.parquet
│ └── ...
└── <category>/ # any subfolder name works for OHLCV data
├── SPY.parquet
└── ...
options/ is the fixed folder for options chain data. For OHLCV price data, you can organize files into any subfolder name you like (e.g. stocks/, etf/, futures/, indices/, or your own). The engine searches all non-options subdirectories when resolving a symbol's price data.
Parquet schemas
Options data (options/*.parquet)
| Column | Type | Description |
|---|---|---|
datetime |
Datetime | Quote timestamp (intraday resolution supported) |
expiration |
Date/Datetime | Option expiration date |
strike |
Float64 | Strike price |
option_type |
String | "call" or "put" |
bid |
Float64 | Bid price |
ask |
Float64 | Ask price |
delta |
Float64 | Option delta |
Note: If your data has a
date(Date) column instead ofdatetime, it will be automatically cast to a Datetime at 15:59:00 on load.
Price data (<category>/*.parquet)
| Column | Type | Description |
|---|---|---|
datetime |
Datetime | Bar timestamp (intraday resolution supported) |
open |
Float64 | Open price |
high |
Float64 | High price |
low |
Float64 | Low price |
close |
Float64 | Close price |
volume |
Int64/Float64 | Volume |
Development
After cloning, configure git to use the project's shared hooks:
git config core.hooksPath .githooks
This enables a pre-push hook that runs cargo fmt --check, cargo clippy --all-targets, cargo build, and cargo test before every push, matching the CI checks.
cargo build # Build
cargo test # Run all tests
cargo clippy --all-targets # Lint
cargo fmt --check # Check formatting
PORT=8000 cargo run # Run as HTTP server (optional)
Tech Stack
- Polars — DataFrame engine for data processing
- rmcp — MCP server framework (v0.17)
- Tokio — Async runtime
- Axum — HTTP server and REST API (via
PORTenv var) - rusqlite — SQLite storage for backtest persistence
- rust_ti — Technical analysis indicators
- Rhai — Embedded scripting language for custom strategies
- garde — Input validation
- serde + schemars — JSON serialization and MCP schema generation
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found