Documentation
Getting started
Stratify speaks MCP over HTTP. Sign in,
generate a key, and point a client at https://stratify-mcp.aeon-labs.site/mcp.
Claude Code
claude mcp add --transport http stratify https://stratify-mcp.aeon-labs.site/mcp \ --header "Authorization: Bearer sk_live_..."
Claude Desktop / claude.ai
{
"mcpServers": {
"stratify": {
"type": "http",
"url": "https://stratify-mcp.aeon-labs.site/mcp",
"headers": {
"Authorization": "Bearer sk_live_..."
}
}
}
}OpenCode
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"stratify": {
"type": "remote",
"url": "https://stratify-mcp.aeon-labs.site/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer {env:STRATIFY_API_KEY}"
}
}
}
}Gemini CLI
{
"mcpServers": {
"stratify": {
"httpUrl": "https://stratify-mcp.aeon-labs.site/mcp",
"headers": {
"Authorization": "Bearer sk_live_..."
},
"timeout": 120000
}
}
}Codex
[mcp_servers.stratify]
url = "https://stratify-mcp.aeon-labs.site/mcp"
http_headers = { Authorization = "Bearer sk_live_..." }
ChatGPT · Gemini · Claude (web)
https://stratify-mcp.aeon-labs.site/mcp Paste that URL as a custom connector and sign in when prompted — no API key needed, and no key to leak. ChatGPT Settings > Apps > Advanced > Developer mode, then add it Gemini Settings & help > Connected Apps > custom app Claude Settings > Connectors > Add custom connector You can disconnect it again from your Stratify dashboard at any time.
Anything else
curl -s https://stratify-mcp.aeon-labs.site/mcp \
-H 'Authorization: Bearer sk_live_...' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'How a strategy is written
A strategy is three things: what to open (`legs`), when to open it (`entry`), and what to do about it while it is open (`rules`). Everything else is optional. It is JSON, drawn from a closed vocabulary — nothing is evaluated as code, so a strategy is data you can store, diff and share.
{
"name": "my strategy",
"legs": [
"..."
],
"entry": {
"cadence": "weekly | daily | monthly",
"dte": 3,
"time": "09:30",
"when": "optional condition"
},
"rules": [
"optional, up to 24"
],
"exit": {
"time": "optional hard square-off",
"when": "optional condition"
},
"max_adjustments": 4,
"portfolio": "optional rules over the sequence of trades"
}
Legs
Up to 12. Each names a side, a type, an optional quantity, an optional expiry, and a strike. Leg order defines the indices that rules refer to.
Strike selectors
atm | the at-the-money strike |
24000 | an absolute strike, as a bare number |
{"pct_offset": 1.5} | 1.5% from spot |
{"points_offset": 300} | 300 index points from spot |
{"premium_near": 50} | the strike trading nearest ₹50 |
{"delta_near": 0.2} | the 20-delta strike, solved from the real traded price |
{"from_leg": {"leg": 0, "pct": 1.0}} | 1% beyond another leg's strike |
Expiry
near | the nearest expiry at entry (the default) |
next | the one after it — this is how a calendar is written |
far | the one after that |
Entry
One entry per cycle. `when` is the gate — the reason for taking the trade — and it is the only place the market fields below mean anything, since nothing else exists yet.
weekly | one entry per weekly expiry, `dte` days out (default 4) |
monthly | one per monthly expiry — the last of its calendar month (default `dte` 21) |
daily | one per session; `max_dte` skips sessions further than that from expiry |
Entry and exit may be ANY minute of the session, not a fixed grid.
Rules
Checked every minute while the position is open, in order; the first match fires. A rule is a condition and an action.
Actions
"close" | end the trade |
{"close_legs": [0, 1]} | close some legs, keep the rest |
{"open": [leg, ...]} | add legs to the live position |
{"roll": {"legs": [0], "to": strike}} | close those legs and reopen them at a new strike |
{"close_and_open": {"close": [0], "open": [leg]}} | both at once — how a position changes shape mid-trade |
Comparators: gt, gte, lt, lte, eq, between.
Combine with all, any, not.
Up to 12 legs, 24 rules and
50 adjustments per trade.
Book rules
Rules over the SEQUENCE of trades, which no per-trade condition can express because they depend on trades that have already closed.
max_trades, resume_after_days, skip_after_loss, stop_after_drawdown_pct, stop_after_losses, stop_after_profit_pct
Field reference
Every quantity a condition can test.
The position
pnl_pts | running mark-to-market P&L of the whole position, in points |
pnl_rupees | the same, in rupees at this lot size and lot count |
pnl_frac_of_credit | P&L as a fraction of the credit collected at entry: 0.6 is 60% of it, and -1.0 means the position has given back everything it took in (the premium has doubled) |
pnl_frac_of_max | P&L as a fraction of the most this position could ever make |
combined_premium | what it would cost to close the position right now, in points |
credit_kept_frac | fraction of the entry credit still unspent (1.0 at entry, 0.0 at break-even) |
A single leg
leg_mark | the current price of one leg, in points |
leg_mark_delta | that leg's price minus what it opened at, in points |
leg_mark_mult | that leg's price divided by what it opened at |
leg_pnl_pts | one leg's own contribution to P&L, in points |
spot_beyond_strike | how far the index is past a given leg's strike, in points (negative while the strike is still out of the money) |
The market
day_of_week | 1 = Monday through 5 = Friday |
gap_pct | this morning's open against yesterday's close, in per cent |
prev_day_move_pct | yesterday's close-to-close move in the index, in per cent |
realised_vol_20d | annualised volatility of the index over the 20 sessions ENDING YESTERDAY, in per cent |
vix | India VIX right now, at the minute being evaluated |
vix_change_pct | how far VIX has moved today, in per cent of yesterday's close |
vix_prev_close | India VIX at the previous session's close |
rsi_N | Wilder RSI of the index over N sessions ending YESTERDAY, 0-100. rsi_14 is the usual one |
close_vs_sma_N_pct | yesterday's close against the N-session simple moving average, in per cent (positive = above the average) |
close_vs_ema_N_pct | the same against the N-session exponential average |
ema_F_vs_S_pct | the F-session EMA against the S-session EMA, in per cent (positive = the fast average is above the slow one). ema_9_vs_21_pct > 0 is 'the 9 is over the 21' |
sma_F_vs_S_pct | the same with simple averages |
The underlying
spot | the index, in points |
spot_move_pct | the index's move from where the trade opened, in per cent |
spot_move_pts | the same, in index points |
The clock
time | wall clock, HH:MM |
minutes_held | minutes of WALL CLOCK since the position opened, so an overnight position counts the 17.5 hours the market was shut. For 'a few hours into the session' use `time` instead |
dte | days to expiry of the nearest leg |
Path
drawdown_from_peak | points given back from the best mark-to-market so far |
runup_from_trough | points recovered from the worst mark-to-market so far |
adjustments_done | how many rules have fired on this position already |
Worked examples
A weekly iron condor
Sell a 1%-wide iron condor every week, three days before expiry.
{
"legs": [
{
"side": "sell",
"type": "CE",
"strike": {
"pct_offset": 1.0
}
},
{
"side": "buy",
"type": "CE",
"strike": {
"pct_offset": 2.0
}
},
{
"side": "sell",
"type": "PE",
"strike": {
"pct_offset": -1.0
}
},
{
"side": "buy",
"type": "PE",
"strike": {
"pct_offset": -2.0
}
}
],
"entry": {
"cadence": "weekly",
"dte": 3,
"time": "09:30"
}
}Only when volatility is worth selling
The same idea, but skip the week unless India VIX is above 15.
{
"legs": [
{
"side": "sell",
"type": "CE",
"strike": {
"delta_near": 0.2
}
},
{
"side": "sell",
"type": "PE",
"strike": {
"delta_near": 0.2
}
}
],
"entry": {
"cadence": "weekly",
"dte": 3,
"time": "09:30",
"when": {
"vix": {
"gte": 15
}
}
}
}Managed while it is open
Take profit at 60% of the credit, roll the tested side if it doubles, and stop the book after three losers.
{
"legs": [
{
"side": "sell",
"type": "CE",
"strike": {
"pct_offset": 1.2
}
},
{
"side": "sell",
"type": "PE",
"strike": {
"pct_offset": -1.2
}
}
],
"entry": {
"cadence": "weekly",
"dte": 4,
"time": "09:20"
},
"rules": [
{
"when": {
"pnl_frac_of_credit": {
"gte": 0.6
}
},
"then": "close"
},
{
"when": {
"leg_mark_mult": {
"gte": 2.0,
"leg": 0
}
},
"then": {
"roll": {
"legs": [
0
],
"to": {
"pct_offset": 2.0
}
}
},
"max_times": 2
}
],
"max_adjustments": 3,
"portfolio": {
"stop_after_losses": 3,
"resume_after_days": 30
}
}An intraday 0-DTE trade
Sell the at-the-money straddle on expiry morning and square off at 15:10, with a 25% target and a 60% stop.
{
"legs": [
{
"side": "sell",
"type": "CE",
"strike": "atm"
},
{
"side": "sell",
"type": "PE",
"strike": "atm"
}
],
"entry": {
"cadence": "daily",
"max_dte": 0,
"time": "09:16"
},
"rules": [
{
"when": {
"pnl_frac_of_credit": {
"gte": 0.25
}
},
"then": "close"
},
{
"when": {
"pnl_frac_of_credit": {
"lte": -0.6
}
},
"then": "close"
}
],
"exit": {
"time": "15:10"
}
}Two expiries at once
Sell this week's at-the-money call and buy next week's against it.
{
"legs": [
{
"side": "sell",
"type": "CE",
"strike": "atm"
},
{
"side": "buy",
"type": "CE",
"strike": "atm",
"expiry": "next"
}
],
"entry": {
"cadence": "weekly",
"dte": 4,
"time": "09:30"
}
}
Limits and honesty
| Tier | History | Backtests | Other calls | CPU s/h | Concurrent |
|---|---|---|---|---|---|
| free | 1 year (2025-07-01 to 2026-06-30) | 100/h | 1000/h | 60.0 | 2 |
| plus | 5 years (2021-01-01 to 2026-06-30) | 1000/h | 10000/h | 900.0 | 6 |
| pro | 7 years (2019-01-01 to 2026-06-30) | 10000/h | 100000/h | 7200.0 | 16 |
Backtests and built reports spend the first column. Reading coverage, methodology, search or your own history spends the second — so checking what the data covers before you run never costs you a run.
- Option prices are real one-minute prints. Nothing is modelled — Black-Scholes is run backwards only to turn 'the 20-delta strike' into a strike.
- Brokerage and taxes are charged per leg on real turnover. Slippage is charged by moneyness, and twice on a trade that is closed rather than settled.
- Naked margin is a Fyers SPAN ratio calibrated today and applied to the past, so return on margin for an uncovered short is optimistic by an unknown amount. Every response that uses it says so.
- Market gates read only what was settled before the session opened. None of them can see the day's own close.
- A cycle whose option chain is too thin to locate the money is skipped, and the count of skipped cycles is reported with the result.