FNOTrader · Algo
← Back to Builder

FNOTrader Algo — Help

A no-code builder for F&O algos. Author multi-leg strategies, backtest them against minute-bar history, and ship the exact same recipe to live trading through your broker. This page documents every feature in the builder, the backtest engine, and the live runtime — with worked examples for each.

Welcome

The execution engine is a standalone Go service that runs configurable multi-leg F&O strategies on your behalf. It pairs three pieces:

Trader's mental model

Think of a strategy as a sentence

WHEN some condition is true on these WATCH instruments, FIRE these legs, MONITOR them under these stop/target rules, and EXIT when this other condition is true (or at square-off time).

Builder is laid out the same way: Step 1–2 define your universe, Step 3 defines triggers, Step 4–5 define legs and risk, Step 6 defines how orders go out.

Five-minute quick-start

  1. Open the builder and pick a Template in Step 1 — e.g. Short Straddle. It seeds the legs for you.
  2. Skip straight to Step 6 → press ▶ Run Backtest. You'll get a full report in 10–20 seconds covering the last month.
  3. Tweak the SL/TG in Step 4 → re-run. Compare results in the Backtest History tab.
  4. Press 💾 Save Strategy. The recipe is now reusable in live trading too.
  5. From the home screen, attach the saved strategy to a Broker Account and press ▶ Start.

✨ New — build & backtest by just asking your AI

FNOTrader MCP

You can now simply ask Claude, ChatGPT or any AI assistant to create a strategy and backtest it using FNOTrader MCP — no Builder clicks needed. Connect once, then talk to it like a colleague:

“Backtest a NIFTY 09:20 short straddle with 30% stop-loss per leg for 2023–2025 and show me the worst days.”
“Try the same on RELIANCE. Then sweep the stop-loss at 20 / 30 / 40% and tell me which wins on drawdown.”

The AI understands every feature in this manual — all strike-selection modes, stop types, ladders, adjustments, sweeps — and runs on the same engine, data and credits as the Backtest page. Indices and 200+ F&O stocks, plus mutual-fund research.

Get started in two minutes: mcp.fnotrader.com — see what's possible, generate your personal token, and copy-paste the setup for your AI of choice.

Colors & conventions

Blue — CE sideCall options, primary actions, primary buttons.
Amber — PE sidePut options, ATM rows in tables.
Green — bullish / fillBUY legs, profitable trades, day-up.
Red — bearish / lossSELL legs, losing trades, kill-switch tripped.
Accent blue — interactiveLinks, active dropdowns, focus rings.
Muted grey — informationalHelper text, inactive controls, captions.

Badges: BACKTEST works in backtest, LIVE works in live trading, BETA accepted but not fully wired, TODO deferred.

Step 1 · Strategy identity

Three fields define what the strategy is and where it trades.

FieldWhat it does
Strategy Name Free-form label — appears in the Strategies tab, save modal, and backtest history. Autofill is disabled so the browser doesn't accidentally fill your login email here.
Symbol The instrument the strategy trades. Searchable dropdown of every F&O index (NIFTY / BANKNIFTY / FINNIFTY / MIDCPNIFTY / SENSEX / BANKEX) plus every F&O stock. The chosen symbol drives ATM-strike resolution, lot-size lookup, and weekly-vs-monthly expiry eligibility.
Template Pre-built recipes you can use as a starting point: short_straddle, iron_condor, BTST, STBT, rolling_straddle, rolling_strangle, or custom (blank slate). Picking one seeds Steps 4–6.
Tip Weekly expiries are only available on NIFTY and SENSEX (SEBI 2024 rule). For BANKNIFTY / FINNIFTY / RELIANCE etc., the Expiry dropdown on legs will only offer monthly options.
MCX commodities Beyond NSE/BSE F&O, the builder supports MCX — options on crude oil, natural gas, gold & silver (plus their minis) and futures-only metals (zinc, copper, aluminium, lead…). Quantities are entered in LOTS with the real contract multiplier; MCX MIS square-off runs at 23:25 IST. Agri commodities are not supported. Backtesting currently covers NIFTY & SENSEX only — use a paper Forward Test for MCX and other underlyings (free, live prices).

Step 2 · Instruments to Watch

The "vocabulary" your conditions can use. Anything you name here is readable in Step 3 conditions via ALIAS.METRIC.

Scope dropdown

ScopeWhat it resolves toExample alias
SpotUnderlying spot index/stockNIFTY.CLOSE
OptionOne specific strike + CE/PEOPT_ATM_CE.LTP, OPT_OTM2_PE.IV
Rolling ATM StraddleThe platform's published rolling-ATM straddle instrument — the same series the Rolling ATM Straddle chart plotsROLL_STRDL.VWAP, ROLL_STRDL.STRIKE
ATM Straddle (locked strike)Sum of ATM CE + ATM PE LTPs, at a strike that locks at start or at a chosen timeATM_STRADDLE.LTP
StrangleSum of OTMn CE + OTMn PE LTPsOTM2_STRANGLE.LTP
Custom CombinerArbitrary linear combination of legs (synthetic)MY_SYNTH.LTP

Rolling ATM Straddle

This scope binds a real instrument rather than summing two legs locally, and the difference is not cosmetic. The published series re-picks the ATM continuously as MIN(CE+PE) across the ±5 strikes around spot — the strike market makers re-price first, which is regularly one or two strikes away from the arithmetic nearest — and it carries real traded volume with intraday history.

Because it is a real instrument it seeds from 09:15 like any other, so VWAP, DAY_HIGH and DAY_LOW on this alias are the session's values, not "since the strategy started". A locally combined straddle can give you none of that.

<Alias>.STRIKE is the strike the series is built from right now. It rolls many times a session (18–47 times on a typical day), so if you enter on a signal from this series, set the leg's Strike Mode to Rolling ATM — the legs then sell exactly the strike the signal was computed on. Without that watch the engine refuses a Rolling ATM leg rather than falling back to the spot-derived ATM, which would fill a different contract than the one that triggered.

Availability is per underlying, and the expiry dropdown only ever offers expiries that actually have an instrument. NIFTY and SENSEX publish four (current weekly, next weekly, current monthly, next monthly); BANKNIFTY publishes monthly only — it has weekly options but no weekly straddle; the eight optionable MCX commodities publish two each. FINNIFTY, MIDCPNIFTY, BANKEX and stocks publish none — for those, use ATM Straddle (locked strike).

The expiry is always a relative selector, never a date. A saved strategy keeps working after the contract rolls; a hard-coded date would keep pointing at a dead contract, and a dead contract does not error — the feed serves its frozen last price, so the strategy would sit there trading a straddle that had stopped moving. The row shows which contract the selector resolves to today underneath it.

Configuring it — a short straddle on the VWAP break

  1. Step 2 — add an instrument, Scope = Rolling ATM Straddle, Expiry = current weekly, Alias = ROLL_STRDL. (Timeframe only affects bar-based indicators like EMA/ATR on this alias; LTP, VWAP, DAY_HIGH/DAY_LOW and STRIKE aren't bucketed.)
  2. Step 3A — entry condition, expression: ROLL_STRDL.LTP < ROLL_STRDL.VWAP
  3. Step 4 — two legs, both SELL, one CE and one PE, Strike Mode Rolling ATM, Distance ATM. For a wider body use OTM1/OTM2 — the distance applies on top of the rolling anchor, not on top of spot.
  4. Per-leg SL / target and a square-off time as usual.
Two things worth setting deliberately Gate the open. A session-anchored VWAP is only as old as the session: the first cross frequently lands around 09:16, when VWAP is two bars of data and the signal carries almost no information. Add a time condition (e.g. after 09:30) or an N-bar filter unless you specifically want to trade the open.
Decide what the exit watches. ROLL_STRDL keeps rolling after you are filled — 18–47 times in a session — while the straddle you sold stays pinned to its strike. An exit condition written against the alias therefore drifts away from the position it is supposed to be protecting. Prefer per-leg SL/target, or a combined-MTM exit, for anything that must track what you actually hold.

In a backtest

Fully supported on NIFTY, SENSEX and BANKNIFTY. The replay recomputes the straddle from archived per-strike bars using the same rule — one value per minute, min(CE close + PE close) across the ±5 strikes around the forward — so the alias, its VWAP/DAY_HIGH/DAY_LOW, its STRIKE, and Rolling ATM legs all behave as they do live. The expiry selector is re-resolved against each replay day's expiry ladder, so "current weekly" means that day's weekly, not today's.

It is not a replay of live, and every report using it says so in its Warnings panel. The strike is re-picked once a minute; live re-picks continuously (~250 ms), so the two diverge intrabar — which is exactly when a straddle signal tends to fire. And DAY_HIGH/DAY_LOW here are extremes of per-minute closes, not intrabar extremes, so they read narrower than live. Treat the result as directionally indicative, then confirm on a paper Forward Test.

Per-row fields

Worked example

Add Scope = Option, Alias = OPT_ATM_CE, Option Type = CE, Distance = ATM, TF = 5m. Now in Step 3A you can write:

OPT_ATM_CE.CLOSE > OPT_ATM_CE.EMA(10)

Entry only when ATM CE breaks above its own 10-bar (5m) EMA.

Step 3A · Entry conditions

Multi-row builder. Each row is one boolean clause; rows combine with AND or OR (your choice). The full expression is evaluated every bar (or throttled — see Check Frequency) and the strategy enters on the first true.

Per-row fields

FieldPurpose
SymbolStep-1 instrument the metric reads from. Defaults to the strategy underlying.
MetricIndicator to evaluate. 40+ choices — see catalog.
Metric argsInline numeric inputs for parameters (e.g. EMA period, MACD fast/slow). All values are user-editable.
OperatorHow LHS is compared (full list below).
RHSA literal value, another metric on the same instrument, or an instrument — a metric on a DIFFERENT Step-1 instrument (e.g. compare ATM_CE.OI_CHG against ATM_PE.OI_CHG).
Change basisShown for *_CHG metrics. vs prev bar (default) = this bar minus the previous bar — on a 3-min instrument that IS the 3-minute change. vs day open = running change since today's first data point. vs prev day close (OI only) = change from the previous trading day's closing OI.

Operator catalog

OperatorFires when…
greater_than / less_thanPlain numeric comparison.
above / belowLHS above/below a price reference (e.g. above_VWAP).
crossingLHS crosses RHS in either direction this bar.
crossing_up / crossing_downLHS crosses RHS from below / above this bar.
moving_up / moving_downLHS strictly increasing / decreasing N bars in a row.
inside_channel / outside_channelLHS is between (or outside) two RHS values.
entering_channel / exiting_channelEntered / left the channel this bar.
new_day_high / new_day_lowLHS prints a fresh intraday extreme.
range_breakout_up / _down / _eitherLHS breaks above/below/either side of the opening-range high/low. Window is user-editable (Start–End times).

Combine mode

Toggle AND (all rows must fire) or OR (any one). Rows cannot mix AND/OR within one block — for that, save two strategies and cascade them via On-Hit actions.

Check Frequency

How often the expression is evaluated:

Lookahead-bias guard In backtest, an indicator-driven entry signal at bar X always fills at bar X+1's OPEN — never at the same bar's close. This matches QuantMan semantics and what's physically possible in live trading. Pure-TIME strategies (no indicator read) fill same-bar since no bar data was consulted.

Comparing two instruments — CE vs PE OI crossover

Pick RHS mode instrument to compare one instrument's metric against another's. The canonical intraday use: two ATM watches (ATM_CE, ATM_PE, ATM tracking = Auto, Timeframe 3m) and a row ATM_CE · OI Chg · Crossing Up · instrument · ATM_PE · OI Chg. Crossings against a moving right-hand side are TRUE crossings — both sides are read at the previous bar too, so the row is true on exactly the crossing bar, not while one side merely stays ahead. Pairs without a previous-bar form (e.g. IV Chg) compile as a plain level check — the Preview always shows exactly what will run.

Already crossed at the open? Some days the two lines START the session in the crossed state (e.g. CE OI above PE OI from the very first data point) and never cross again — a pure crossing row would sit silent all day. Tick "or fire on day's 1st bar if already crossed" on the crossing row to ALSO enter on the session's first closed bar when the condition already holds there. It evaluates exactly once, on the day's first bar-close check; after that only real crossings fire. Works in live and backtest identically.

On an Auto-tracking ATM watch, a strike change resets OI continuity: the new contract's book has nothing to do with the old one's, so OI-change metrics read 0 until the new strike establishes its own baseline (prices are left untouched).

When conditions evaluate — and when entries fill

With Check Frequency every X-min bar close, the expression is evaluated ONCE per bar, in the first second after the bar closes — never mid-bar, never on an intrabar spike, and never against the half-formed bar the strategy started inside. A condition fires the first time it is true (a crossing is true for exactly one bar; a level like LTP > 100 fires once when first satisfied). The entry then executes immediately — effectively the next bar's open. The backtest enforces the same discipline: signal on bar X's close → fill at bar X+1's open (see no-lookahead-bias). tick mode evaluates in real time, live only at tick granularity (the backtest's floor is 1-minute bars).

Step 3B · Exit conditions

Same builder as 3A but evaluated after entry. If any exit row fires (when combine = OR) or all exit rows fire (combine = AND), the engine flattens every open leg at next bar's open.

Exit conditions compose with the per-leg SL/TG (Step 4) and Combined SL/TG (Step 5). Whichever triggers first wins — they're not mutually exclusive.

Step 3C · BTST / STBT mode

Buy-Today-Sell-Tomorrow / Sell-Today-Buy-Tomorrow. Two time pickers: Start Time (today's entry window) and Exit Time (next trading day's square-off). When both are set, the engine flips overnight_hold = true and the strategy is held across the EOD square-off boundary. Entry/Exit conditions 3A/3B remain available but optional.

Backtest BTST/STBT is fully simulated. The entry day runs to the close with no same-day square-off, the position rides the overnight gap at its pinned strikes, and it exits at your Exit Time the next session (filled at that bar's open) — so the gap risk lands in the P&L exactly like live. A range that ends while still holding books the position at the last marks and says so.

Step 3D · Overnight Protection

Carrying short option legs overnight exposes you to gap risk and higher peak margin. Overnight Protection automatically buys a protective hedge against every open short option leg at a set time (typically just before close) and sells it back at a set time the next trading morning — no manual step, and it survives engine restarts (the hedge is rebuilt from the order ledger).

Controls

FieldWhat it does
EnableTurns it on. Requires product NRML — MIS is squared off intraday, so there is no overnight to protect.📎 A short straddle on NRML gets hedged and carried; the same straddle on MIS is rejected at launch with "needs NRML". Set Product = NRML in Step 6 first.
Strike byHow the hedge strike is picked — always further OTM than the short. Six methods (below).📎 Short 25000 CE, spot 25000. Strike distance = 3 → buys the 25150 CE. Delta ≈ 0.10 → buys whichever strike is ~10-delta today (further out on a low-IV day, nearer on a high-IV day) so the wing cost stays roughly constant.
± strikesExtra ladder steps applied AFTER the method resolves (e.g. Max-OI + 1). Clamped so the hedge always stays beyond the short.
Apply atIST time the hedges are BOUGHT (default 15:20).📎 15:20 — 10 minutes before the 15:30 close, so the wings are on and confirmed before the session ends and margin is measured.
Remove atIST time they are SOLD next session (default 09:20). Weekends / holidays wait for the next trading session automatically.📎 09:20 — 5 minutes after the 09:15 open, once the opening auction settles and the gap (if any) has printed. A Friday-evening hedge simply waits and sells at Monday 09:20.

Strike-selection methods

MethodPicks the OTM strike…
Strike distanceN ladder steps further OTM than the short (classic).
Premium closest to ₹whose premium is nearest your ₹ target — cheap fixed-cost wings.
Delta closest towhose |delta| is nearest a target (e.g. 0.10) — constant risk shape.
Max OI strikecarrying the highest open interest — the market's wall.
Straddle-width ×a multiple of the ATM straddle premium away — the market's own expected-move yardstick.
Underlying % awaynearest spot ± X% of the underlying.
Example You hold a short NIFTY 25000 CE / 25000 PE straddle overnight, method Strike distance = 3, apply 15:20, remove 09:20. At 15:20 the engine buys the 25150 CE and 24850 PE (3 strikes OTM of each short). On a gap-up open, the CE hedge's gain offsets the short CE's loss; at 09:20 both hedges are sold. If a short leg exits on SL overnight, its hedge is sold with it. Hedge P&L is folded into the strategy MTM.
Build a unique strategy Protected BTST theta: combine this with the BTST short straddle (3C) — sell the ATM straddle at 15:15, protect it 3 strikes wide at 15:20, exit both at 09:20. You harvest the overnight theta of an index that historically opens near flat, but a black-swan gap is capped by the wings instead of blowing up the book. Prefer Delta ≈ 0.08 as the method if you want the wing cost to stay constant regardless of where spot sits.
Backtest Overnight Protection is simulated (for BTST/STBT strategies): hedges are bought at the apply bar off the bar ladder using the same six methods (delta via Black-Scholes on the bar IV), carried, and sold at the remove bar — so the report shows exactly what the protection cost or saved on each gap.

Step 4 · Strategy Legs

Table of legs the strategy fires. One row per leg.

Main-row columns

ColWhat it does
IdleLeg is deferred — won't fire at entry. Activated only by another leg's execute_other_leg / enter_leg_id action.📎 Mark a BUY-CE wing Idle so it sits dormant; a short CE's SL then wakes it as an emergency hedge.
HedgeMarks a protective BUY leg. Excluded from Move-SL-to-Cost and exits LAST on flatten.📎 On an iron condor, tick Hedge on both BUY wings — on a square-off the shorts close first and the wings last, so you are never momentarily naked.
SideBUY / SELL
Fut/OptOPT (default) or FUT. FUT hides Type/Strike-Selection cells.
TypeCE or PE
Strike SelectionHow the strike is picked — see below.
Strike ValueAdapts to the selection mode.📎 Distance → "OTM2"; Absolute → "24500"; Premium → "₹120"; Delta → "0.30"; Underlying → "+0.5%". The field label changes with the mode you pick.
ExpiryRelative (Current / Next / Far Weekly and Current / Next / Far Monthly) or Absolute date. Far = the 3rd upcoming series.📎 Current Weekly always tracks the nearest weekly expiry as weeks roll — a saved strategy stays "this week's expiry" forever without editing. Next and Far systematically trade the later series, in live trading and in backtests alike.
Qty (lots)Multiplied by lot_size at order time.📎 Qty 2 on NIFTY (lot 75) → 150 units sent. On MCX the lot is the real contract size (e.g. CRUDEOILM = 10 barrels) and freeze limits auto-split large orders.
⚙ SettingsExpands the advanced 4-tab panel.

Strike Selection modes

ModeBehaviourBacktest support
DistanceATM / OTM1–15 / ITM1–15 strike steps from ATM. Most common.ATM±10 — a leg set deeper is replayed at ATM±10, with a warning on the report. Marked (live only) in the dropdown because the replay is then not like-for-like.
AbsoluteExact strike number (e.g. 24500).ATM±10 — a strike outside the archived range is replayed at the nearest archived one.
PremiumEngine picks the strike whose LTP is closest to a target ₹ value.ATM±10 — the search only sees archived strikes, so a deeper target resolves to the nearest one inside the range.
DeltaTarget |delta| (e.g. 0.30 for ~30-delta).ATM±10 — as Premium: a low-delta target resolves to the nearest archived strike, which live may not match.
Straddle WidthStrike whose premium is N% (or N×) of the ATM straddle premium.LIVE
Rolling ATMATM ± distance, anchored on the strike the Rolling ATM Straddle watch is currently built from — MIN(CE+PE) over ±5 strikes, not round(spot/step). Live: needs that watch on the same underlying, and the engine refuses the order without it rather than falling back to the spot ATM. How to configure →ATM±10 — recomputed per bar in a replay; see the fidelity note under Rolling ATM Straddle.
Underlying PriceSigned % offset from spot — e.g. +0.5% on NIFTY=24000 → strike ≈ 24120.LIVE

Advanced (⚙) — tabbed panel

Tab 1 · Wait & Trade

Delay this leg's entry until its premium crosses a trigger price. Useful for buying weakness or selling strength after the basket has already fired.

Tab 2 · Stoploss (SL1+)

SL TypeMeaning
pct% of entry premium (e.g. 30 = 30%).
pointsFlat ₹ move from entry (e.g. 15 = ₹15 swing).
pnlPer-leg ₹ loss (qty-aware).📎 5000 → exit the leg once it is down ₹5,000 across its full quantity (2 lots of NIFTY = 150 units, so a ₹33/unit adverse move).
underlying_move / _up / _downSL trips when spot moves N points or N% in the chosen direction.📎 underlying_move_up 100 on a short CE → exit when NIFTY rises 100 pts from your entry spot, regardless of the option's own premium (a directional stop, not a premium stop).
deltaSL trips when the leg's |delta| crosses a threshold.📎 0.60 → exit the short CE once it reaches ~0.60 delta (going deep ITM) — a moneyness-based stop that fires the same whether the move was slow or a spike.
atrSL = entry ± N × ATR(period). ATR source is a Step-1 watch instrument.📎 1.5 × ATR(14) → a volatility-scaled stop: it sits wider on choppy high-ATR days and tighter on calm days, instead of a fixed % that's too tight in a storm and too loose in a lull.

SL Wait (sec) — SL breach debounce (next to the tab's Check Frequency): a breached stoploss must STAY breached for this many consecutive seconds before the exit fires; a recovery inside the window resets the timer. Ignores flash-spikes / single-tick wicks. 0 = exit on first breach. The same knob exists at basket level on the Combined Stoploss tab (Step 5).

Per-rung fields: SL Qty (% or lots), On-Hit action, Check Frequency. Add SL2 / SL3 rungs for laddered exits.

On-Hit action catalog

ActionEffect
just exitClose the leg, do nothing else (default).
keep_leg_runningDon't close — mark SL fired but continue holding.📎 SL1 at 30% with keep_leg_running only triggers a partial (SL Qty 50%) and holds the rest; SL2 at 50% then closes what's left — a two-rung scale-out instead of an all-or-nothing exit.
re_execute_N_timesClose, then re-fire the same leg up to N times.📎 Short CE with re_execute 2×: SL closes it, the engine re-sells a fresh ATM CE, and can do so twice more — three total attempts to collect premium on a range day.
close_leg_idAlso close another leg by ID (e.g. spread partner).
enter_leg_idFire a leg marked Idle.📎 Sell a naked CE now; keep a BUY-CE wing marked Idle. If the CE's SL hits, enter_leg_id fires the wing — a protective hedge that only exists once you're in trouble.
move_sl_to_costMove every other leg's SL to its entry price (lock breakeven).📎 On a short strangle, once the CE hits its target the PE's SL jumps to its entry price — the winning side can no longer turn into a loser.
add_qty_pctScale up the leg by N% (martingale-style — use with care).📎 add_qty_pct 100 → when the short PE's SL hits, double its size at the new (higher) premium, betting on mean-reversion. Powerful and dangerous: pair it with a hard combined SL.
execute_other_legTrigger another leg with optional delay (live engine cascade).📎 CE target hit → after a 30s delay, fire a fresh OTM CE sell to keep theta working on the call side while the put runs.
execute_other_strategyLaunch a separate saved strategy.📎 A directional breakout strategy's target hit launches your "trend-continuation" saved strategy — chaining two independent recipes into one workflow.

Tab 3 · Target (TGT1+)

Same structure as SL. Target Types include all SL types plus r_multiple (risk-reward — target distance = N × stop distance).

Tab 4 · Per-leg Trailing

Example Trigger ₹2,000 · Step ₹500 · Lock ₹1,000. The short CE runs to +₹2,000 → the trail arms and locks ₹1,000. It climbs to +₹2,500 (one ₹500 step) → the locked floor ratchets to ₹1,500; +₹3,000 → ₹2,000. If it then falls back to the current floor the leg exits — you keep the ratcheted profit instead of giving it all back.

Profit Lock & Trail (per leg)

₹-P&L guards on ONE leg, independent of the price trail and of its "Trailing enabled" switch. Profit Locking: when this leg's P&L reaches ₹X, a minimum of ₹Y is locked — if P&L falls back to ₹Y, the leg exits in full. Profit Trailing: every further ₹X of PEAK P&L lifts the locked floor by ₹Y. Evaluated on every tick live (a ₹ guard, like Combined SL); at bar closes in backtest.

The per-leg price trail's Trigger / Step / Lock take a unit — % of entry premium (default) or Pts (absolute premium points). The hints and "What this means" readback speak whichever unit you pick.

Step 4B · Strategy Adjustment Conditions

The engine's most powerful section — modify a LIVE position without stopping the run. Where SL/Target close a leg, adjustment rules re-strike it: roll a threatened short leg further OTM, roll a decayed winner back in, re-center a straddle when spot drifts, or delta-hedge the whole book. Each rule is a card — click + Add rule and pick its type (one rule per type; a duplicate type overrides the earlier card).

A roll closes the leg (fill-confirmed) and re-opens at the target strike off the live option chain; the new leg gets a fresh SL/Target from its own entry. Every action is journaled.

Global guards (apply to every rule)

GuardEffect
Min CE−PE strike gapInversion guard — a roll that would leave the lowest CE strike below the highest PE + gap is aborted whole. Default 100.📎 Gap = 100. A delta-hedge roll wants to push your short 25500 CE down to 25300, but the short PE sits at 25400. Post-roll the CE (25300) would be BELOW the PE (25400) — an inverted, un-manageable book. The gap rule sees 25300 < 25400 + 100 and aborts the whole roll, leaving the position untouched.
Auto-action limitMax rolls/day (ALL rules share this budget) + cooldown seconds between actions. Default 3 / 60s — stops a whipsaw from churning the book.📎 3 / 60s. On a fast trend day your CE rolls at 10:05, 10:40 and 11:15 (3 rolls). At 11:20 a 4th trigger fires — it is ignored and journaled ("budget spent"), so the strategy can't roll itself to death chasing the move. Cooldown also blocks two rolls inside 60 seconds. The count resets next trading morning.
Only sold (short) legsLeg-price / delta rules act on SHORT legs only by default. Uncheck to also act on bought legs.📎 ON (default). On a short strangle with protective BUY wings, a leg-price roll rule ignores the wings and only manages the sold CE/PE. Turn OFF for a LONG straddle where you actually want the rule to roll the bought legs as they move.

Rule types

1 · Roll / exit a leg at a price level

Per-side premium trigger off each leg's own entry (% / points / absolute ₹). On breach: roll away N strikes, roll in, or exit.

Example You sold the 25500 CE at ₹100, CE = 50% (of entry) → trigger ₹150. NIFTY rallies and the CE hits ₹150 → with Roll away by 2 the engine buys back the 25500 CE at ₹150 and sells the 25600 CE at its prevailing price. With Exit it just buys the CE back and stops.
2 · Price-diff band around entry (two-sided)

One band, a different action on each side: LTP ≥ entry + band fires the ▲ action; LTP ≤ entry − band fires the ▼ action.

Example Sold the 25500 PE at ₹100, band ₹40. PE rises to ₹140 → ▲ rolls away to the 25450 PE; instead PE decays to ₹60 → ▼ rolls in to the 25550 PE so the leg keeps collecting meaningful premium.
3 · Roll / exit a leg at a delta level

The delta twin of the price rule — fires on the leg's |delta| off the live chain greeks (a short 0.45δ call is a threatened call regardless of premium). Roll by strikes, exit, or roll AWAY to a target |delta|.

Example (short strangle) Sold the 25700 CE (δ 0.30) and 25300 PE (δ −0.30); rule CE |δ| ≥ 0.45 → roll to |δ| ≈ 0.20. NIFTY rallies, the CE's delta hits 0.45 → buy it back and sell the CE whose delta is now ≈ 0.20 (say the 25950 CE). The safe PE side is untouched; a crash would roll the PE instead.
4 · CE/PE divergence — winner & loser actions

Straddle/strangle only. When |CE − PE| crosses a threshold, the winner (decayed, in profit) premium-matches IN and the loser rolls AWAY — in one inversion-guarded action.

Example Short straddle CE ₹95 + PE ₹90 (combined ₹185), threshold 50%. Rally: CE ₹160, PE ₹50 → |160 − 50| = 110 ≥ ₹100 → the winner PE is bought back at ₹50 and re-sold at ≈ ₹128 (80% of the CE) — the 25600 PE; the loser CE rolls away 1 strike to 25550.
5 · Rebalance — roll the cheap side in (premium match)

Straddle/strangle only. When one side's premium reaches N× the other, the CHEAP (decayed) leg rolls IN to the strike worth ≈ the target % of the expensive side — the running side is left alone.

Example Strangle 25700 CE ₹60 / 25300 PE ₹60, ratio 2×. Drift down: CE decays to ₹30, PE runs to ₹95 → 95 ≥ 2×30 → buy back the cheap CE and sell the CE worth ≈ ₹76 (80% of ₹95), say the 25550 CE. Balanced credit restored.
6 · Delta / gamma hedge — re-balance when net delta skews

Watches the whole book's net delta (Σ ±δ·qty / Σqty off the live greeks; SELL negates) — 0 when balanced, drifting toward ±1 as one side runs ITM. Two actions:

An optional net-gamma trigger fires the same fix earlier, before the delta itself looks bad.

Example Short straddle (75/side), max net 0.20. At entry δCE +0.50 / δPE −0.50 → net 0. Rally to ~25700: CE δ 0.74, PE δ 0.27 → net = (−0.74·75 + 0.27·75)/150 = −0.235 → breaches. Roll: buy back the heavy 25500 CE and sell the CE matching |δ| ≈ 0.27 (~25950). Futures: −0.235 × 300 qty = −70 delta units → BUY 1 lot (75) of NIFTY futures; sold back when net Δ recovers.
7 · Spot re-center at ATM ± offset

Straddle/strangle only. When the underlying moves ≥ X% from the armed reference, close both legs and re-open at the new ATM ± offset. The reference re-bases after each fire.

Example Straddle sold at the 25500 ATM, move 0.75% on Spot. NIFTY grinds up to 25691 → both legs close and a fresh straddle opens at the new ATM 25700. The reference re-bases to 25691; the next re-center needs another 0.75%.
Build a unique strategy Self-managing short straddle: stack three rules on one straddle — (a) delta hedge, roll at net 0.25 to keep it directionally neutral through trends, (b) rebalance at 2.5× to re-collect credit when one side decays, and (c) a leg-price roll-away at +60% as the hard backstop on a runaway side. The shared 3-rolls/day budget and inversion guard keep the combination from over-trading. This is a strategy that adapts to trend, range and shock without you touching it — impossible to express with SL/Target alone.
Backtest Adjustment rules are simulated per bar: rolls close at the bar price and re-open at the target strike off the bar ladder (deltas via Black-Scholes on bar IV), with the same edge-latch, daily budget, cooldown and inversion guard as live. Two exceptions are stated on the report: alert-only configs (nothing executes live either) and the delta rule's futures action (no futures bars in the option archive — its roll action does simulate).

Step 5 · Strategy Risk Settings (Combined)

Same shape as the per-leg advanced panel but at the basket level. Four tabs: Wait & Trade, Stoploss, Target, Trailing.

Combined SL/TG fires when the basket-level MTM (sum of all open-leg PnLs) crosses a ₹ or % threshold. On hit, the action choices include:

SL Wait (sec) — the same debounce as the per-leg one, at basket level (next to the group Check Frequency): a breached Combined SL must STAY breached for N consecutive seconds before its action fires; if the basket MTM recovers inside the window the timer resets. Applies to every Combined SL condition (AND groups included). In backtests (1-min bars) waits under 60s are absorbed into the bar; longer waits require the breach to persist across bars.

Profit Lock & Trailing (basket)

Its own tab in Step 5, and a different mechanism from Combined Trailing — the difference is who decides where the floor sits. Combined Trailing gives back from the peak: the floor is always peak − Trail Lock, so you choose how much to hand back, never where the floor lands. Profit Lock & Trailing locks an absolute floor you name: when combined P&L reaches ₹X, a floor of ₹Y is held, lifted by ₹L per further ₹S of peak. Falling back to the floor squares off every leg.

Use Profit Lock when you can state the outcome — "once I'm up ₹20,000 I keep at least ₹18,000". Combined Trailing cannot express that.

Arm one, not both. They are checked on the same tick and the first to fire wins, in the order Combined Trailing → Profit Lock → Combined Target. Arm both and the trail usually closes the position before the lock engages. For the same reason a Combined Target at or below your arm level books the basket before the lock can ever arm — disable the target if you want the lock to run.

Two more things worth knowing. Set lift = step for a constant give-back: with step ₹5,000 and lift ₹2,000 the floor falls further behind as profit grows (₹8,000 behind at a ₹30,000 peak, ₹14,000 behind at ₹40,000). And these are rupee amounts on the whole basket, so scale them with lot count just like the Combined Target — a ₹20,000 lock sized for 10 lots arms far too early on 17.

Both are editable while a strategy is running, from the Forward Test / live position panel. Changing the profit lock can close the position immediately: if P&L has already pulled back below the floor your new numbers imply, you get a warning showing the actual floor, peak and current MTM before it applies.

Step 6 · Execution Settings

FieldWhat it does
Legs Executionparallel (all at once), sequential (fire next after prev fills), buy_first (BUYs in parallel, then SELLs after delay).📎 An iron condor with buy_first buys both protective wings first, waits Hold Sell Sec, then sells the ATM legs — so you are never even briefly naked short (and get the margin benefit immediately).
Hold Sell SecDelay between BUY batch and SELL batch in buy_first mode. Used to lock hedges before opening short exposure.📎 2 → a 2-second gap: long enough for the two wing BUY fills to confirm before the short CE/PE orders go out.
If Leg Failscancel_all / keep_placed / retry_failed (with Max Retries).📎 4-leg condor, cancel_all: if the far CE wing is rejected (illiquid), the other 3 filled legs are pulled too — you never end up holding a lopsided, unhedged book.
Spike Protect %Skip entry if the basket's spread blows out beyond %.📎 5 → on a news-spike or thin open where the combined bid/ask gaps past 5%, the entry is skipped rather than filled at a bad price. It re-checks on the next bar.
Spread Limit %Reject any leg whose bid/ask spread exceeds %.📎 3 → a far-OTM wing quoting 12 / 13 (≈8% spread) is rejected as illiquid; a liquid ATM leg at 100 / 100.5 (0.5%) passes.
Premium Gap %Reject if the leg's LTP gapped more than % from its prior close.📎 20 → on a gap-open day, a CE that closed ₹80 and opens ₹105 (+31%) is skipped — you avoid selling a premium that has already spiked.
Slippage %Cap acceptable slippage at fill.📎 1 → an order expecting ₹100 accepts fills up to ₹101 (BUY) / down to ₹99 (SELL); a worse fill is flagged as slippage-rejected. This same % is applied to entry AND exit fills in backtests.
Run On DaysMon–Sun checkboxes. Strategy is paused on un-checked days.📎 Tick only Tue + Thu for a NIFTY/expiry-focused seller — the strategy sleeps Mon/Wed/Fri and only fires on your chosen days.
DTE FilterOnly enter when days-to-expiry matches the chosen set (discrete: pick 0,1,2…) or range (e.g. 3–7). Basis = weekly or monthly cycle.
Max LotsHard cap on total lot count across all legs.📎 10 → an exposure-sized basket that computes 14 lots is capped down to 10 — a hard ceiling on position size regardless of what the sizing math returns.
Exposure (₹)Auto-size qty from capital — engine divides this by margin/lot to compute lots.📎 ₹3,00,000 on a straddle needing ~₹1.5L margin/lot → auto-sizes to 2 lots. Change your capital and the qty scales with it — no manual re-entry.
Order TypeMKT / LMT / LMT-BUF (limit with N% buffer off LTP).📎 LMT-BUF 0.5% on a BUY at LTP 100 places a limit at 100.5 — fills quickly but caps how far above the touch you pay (protection against a market-order spike fill).
ProductNRML (carry) / MIS (intraday).📎 NRML to carry a BTST straddle overnight (and to use Overnight Protection); MIS for an intraday scalp auto-squared-off at 15:25 (23:25 for MCX).
Send to TelegramMirror lifecycle events to your bot.📎 With it on, entry, each SL/target hit, every 4B roll and the square-off land as messages in your configured Telegram bot — a live audit trail on your phone.

Step 7 · Summary & Save

A single-page English-prose recap of everything you've configured. Refresh it (↻) any time. Then ▶ Start Strategy (live), 💾 Save Strategy (reusable recipe), or Export JSON / Import JSON (share/version).

Expression language

Conditions internally compile to a small expression language. The builder writes it for you, but you can also type it directly into the Preview box (advanced).

Operators & precedence

ClassOperatorsNotes
BooleanAND OR NOTCase-insensitive; standard precedence (NOT > AND > OR).
Comparison> < >= <= == !=Pair LHS metric to RHS value/metric.
Arithmetic+ - * /Standard math precedence. Use parentheses freely.
Grouping( )Override precedence.

Symbol resolution

Three styles, all interchangeable:

Special identifiers

TokenValue
TIMECurrent bar in HHMM (e.g. TIME >= 0930).
PREV_CLOSEYesterday's last bar close — persists across overnight gap.
LAST_TICKTick-level LTP (not candle-level). Useful for sub-second alerts in live.

Multi-instrument (Phase 4.6)

Cross-index gating

You can reference foreign underlyings in the same expression. Common use: trade NIFTY only when the broader market (SENSEX) also agrees.

// NIFTY straddle, only when SENSEX is trending up
TIME >= 0920 AND SENSEX.CLOSE > SENSEX.EMA(10)

Backtest data: only NIFTY and SENSEX have archived spot bars today. BANKNIFTY / FINNIFTY references compile fine but produce a warning + read as 0 (so the gate effectively never fires). Live trading is unaffected — all 6 indices stream.

Arithmetic between metrics

The evaluator supports full arithmetic between metric reads. Strike-wise PCR is the canonical example:

// Strike-wise PCR > 1.5 (puts dominate at ATM = bearish hedging)
ATM_PE.OI / ATM_CE.OI > 1.5

// Straddle premium relative to spot > 1.5%
(ATM_CE.LTP + ATM_PE.LTP) / NIFTY.CLOSE * 100 > 1.5

// Credit-spread net premium > ₹50
LEG1.LTP - LEG2.LTP > 50

Every condition row in Steps 3A/3B has an optional arithmetic combinator between the primary metric and the operator — a small dropdown reading by default. Pick +, , ×, or ÷ and a second [Symbol] + [Metric] + [args] block appears, so you can build composite LHS expressions like ATM_PE.OI ÷ ATM_CE.OI > 1.5 entirely from dropdowns. The Preview textarea is still available for power users who want to type longer compound expressions directly.

Metrics & indicator catalog

Every metric below works on any symbol — spot, option, alias.

Price & structural

MetricReturnsExample
LTPLast traded priceOPT_ATM_CE.LTP > 200
OPEN / HIGH / LOW / CLOSECurrent bar's OHLCNIFTY.CLOSE > NIFTY.OPEN
DAY_HIGH / DAY_LOWIntraday extremeNIFTY.CLOSE >= NIFTY.DAY_HIGH
PREV_CLOSEYesterday's last closeNIFTY.CLOSE > PREV_CLOSE
VWAPVolume-weighted avg price (day-anchored)NIFTY.CLOSE > NIFTY.VWAP
SMA(N)Simple moving avg over N barsNIFTY.CLOSE > NIFTY.SMA(20)
EMA(N)Exponential MANIFTY.CLOSE > NIFTY.EMA(10)
WMA(N)Weighted MANIFTY.WMA(14)
SAR(step, max)Parabolic SAR (defaults 0.02, 0.2)NIFTY.CLOSE > NIFTY.SAR(0.02, 0.2)

Momentum

MetricReturnsExample
RSI(N)Wilder RSI (0–100)NIFTY.RSI(14) < 30
ROC(N)Rate of change (%) over N barsNIFTY.ROC(5) > 0.5
MACD(fast, slow)MACD lineNIFTY.MACD(12, 26) > 0
MACD_SIGNAL(f, s, sig)Signal lineNIFTY.MACD(12,26) > NIFTY.MACD_SIGNAL(12,26,9)
MACD_HIST(...)Histogram (MACD − signal)NIFTY.MACD_HIST(12,26,9) > 0
STOCH_K(N) / STOCH_D(N, d)Stochastic %K / %DNIFTY.STOCH_K(14) > 80
ADX(N)Average Directional IndexNIFTY.ADX(14) > 25
CCI(N)Commodity Channel IndexNIFTY.CCI(20) > 100
WILLR(N)Williams %R (−100..0)NIFTY.WILLR(14) > -20

Volatility & channels

MetricReturnsExample
ATR(N)Avg True RangeNIFTY.ATR(14) > 100
BB_UPPER(N, σ)Bollinger upper bandNIFTY.CLOSE > NIFTY.BB_UPPER(20, 2)
BB_MIDDLE(N)BB middle (SMA(N))NIFTY.BB_MIDDLE(20)
BB_LOWER(N, σ)BB lower bandNIFTY.CLOSE < NIFTY.BB_LOWER(20, 2)
SUPERTREND(N, mult)Supertrend valueNIFTY.CLOSE > NIFTY.SUPERTREND(10, 3)

Volume / OI / CDV

MetricReturnsExample
VOLUMEBar volumeOPT_ATM_CE.VOLUME > 100000
OBVOn-Balance VolumeNIFTY.OBV > 0
OIOpen interest (options only)ATM_PE.OI / ATM_CE.OI > 1.5
CDVCumulative delta volume (signed)NIFTY.CDV > 0
BUILDUPOI buildup tag (long/short addition/unwinding)OPT_ATM_CE.BUILDUP == 1
OI_CHGOI change vs the previous bar close (contracts). Bar-anchored: on a 3-min instrument this is the 3-minute change.ATM_CE.OI_CHG > 8000
OI_CHG_PCTSame, as % of the previous bar's OIATM_CE.OI_CHG_PCT > 2
OI_CHG_FROM_OPENOI change since today's first data point (the day-open basis; every *_CHG metric has a _FROM_OPEN form)ATM_CE.OI_CHG_FROM_OPEN > 50000
OI_CHG_FROM_PREV_CLOSEOI change from the previous trading day's closing OI (OI only)ATM_CE.OI_CHG_FROM_PREV_CLOSE > 0
PREV_OI / PREV_OI_CHG…Previous-bar forms — the anchors crossings compile against, so an OI crossing fires on the crossing bar only(emitted by the builder's Crossing operators)

Spot instruments have no OI — OI metrics on a spot watch read 0. The condition-row basis picker ("vs prev bar / vs day open / vs prev day close") writes these forms for you; you rarely type them by hand.

Option Greeks

Computed via Black-Scholes (Hull 11e) at risk-free rate 6.5%. Returned per option symbol; backtest computes on-the-fly from (spot, strike, IV, DTE).

MetricReturnsExample
IVImplied volatility (%)ATM_CE.IV > 25
DELTAPrice sensitivity to spotOPT_ATM_CE.DELTA > 0.4
GAMMAΔ sensitivity to spotATM_CE.GAMMA > 0.001
THETAPer-day time decay (₹)OPT_ATM_CE.THETA < -50
VEGAPer-1%-IV sensitivity (₹)ATM_CE.VEGA > 20

Pivots, CPR, Camarilla

MetricReturns
PIVOT_P, PIVOT_R1..R3, PIVOT_S1..S3Standard floor pivots
CPR_PIVOT, CPR_TC, CPR_BC, CPR_WIDTHCentral Pivot Range bands
FIB_P, FIB_R1..R3, FIB_S1..S3Fibonacci pivots
CAM_H1..H4, CAM_L1..L4Camarilla bands

TIME & PREV_CLOSE

// Window-only entry
TIME >= 0925 AND TIME < 1100

// Gap-up open
NIFTY.OPEN > PREV_CLOSE * 1.005

Backtest engine

Replays your saved strategy against minute-by-minute history — years of option prices (open/high/low/close), implied volatility and open interest for strikes around the money, plus the index itself. Hit ▶ Run Backtest on any saved strategy; reports are persisted to Backtest History.

What a backtest is — and isn't A backtest is a faithful rehearsal of your strategy's LOGIC on past 1-minute data. It's the right tool to answer "does this idea make money, and how does it behave in trends vs ranges?" — not a promise of live returns. Real fills, real slippage and second-by-second timing only happen when you go live (or paper forward-test). See the honest scorecard below.

External signals — backtest a TradingView strategy (or any signal list)

The Backtest tab has an optional Entry signals row (below the main settings). Upload a CSV of timestamped entry/exit signals and the backtest fires your strategy only when the file says so — your SuperTrend / Pine-script / Python / Excel logic decides when, while everything you built in the Builder decides what: legs, strikes, expiry, SL/Target, trailing, square-off. It works in Single-strategy, Portfolio and Parameter-sweep runs, and costs the same credits as a normal backtest.

Two accepted file formats

Signal types

A signal row is a pure entry or exit event — the engine never reads a direction out of it and never changes your strategy's legs because of it. The long/short tag is only a label you can filter on:

Signal valueCodeMeaning
ENTRY / EXITE / XUntagged entry / exit — counts in every "Use rows" mode.
LONG ENTRY / LONG EXITLE / LXEntry / exit tagged as the long side of your signal system.
SHORT ENTRY / SHORT EXITSE / SXEntry / exit tagged as the short side.

Word order and case don't matter (Entry Long, exit_short, close long all work). Every entry needs an explicit exit row — an opposite-side entry does not imply one. This is the same E/X/LE/LX/SE/SX taxonomy the live Signals page (webhooks) uses, so a system you backtest from a file can go live on a webhook unchanged.

The "Use rows" filter

Untagged ENTRY/EXIT rows pass every filter. Build the strategy for the side you want, then pick the matching rows. Example — a SuperTrend stop-and-reverse export: run a BUY CE strategy with Long only (holds a call through the long stretches) and a BUY PE strategy with Short only (holds a put through the short stretches).

How the gate actually fires

Why option PnL ≠ TradingView PnL TradingView scored your signals on the index itself; here every entry buys/sells a real option with premium, theta and IV. A spot trade that made points overnight can still lose money as a long option — that difference is exactly what this backtest is for. Mind the file's date range too: the From→To of the run is clamped to your plan, and the summary line warns when the file and the backtest range don't overlap.

Backtest vs Live — what matches, what doesn't

Same in both Close, but approximated Live / forward-test only
What you buildBacktestLive / ForwardPlain-English note
Entry & exit conditions (time, price, indicators)Same rules, same trigger logic.
Per-leg SL / Target / Trailing (ladders)Every rung replays; intrabar-SL fills stops off the bar's high/low.
Combined (basket) SL / Target / TrailingSame basket-MTM maths.
Re-entry, spike guard, gap gate, DTE, run-on-daysAll top-of-day gates apply identically.
Strike selection (Distance / Premium / Delta / Straddle / Underlying %)Dynamic strikes resolve off the same greeks. The archive holds ATM±10, so anything deeper — a low-delta target or a Distance leg past OTM10 — is replayed at the nearest archived strike, and the report says which legs were substituted.
External signals (SIGNAL condition)Backtest drives it from an uploaded CSV; live from the Signals page's webhook — same E/X/LE/LX/SE/SX taxonomy.
BTST / STBT overnight holdPosition rides the gap; exits next morning at your time.
Overnight Protection (auto-hedge)All six strike methods — only for overnight (BTST/STBT) strategies.
4B adjustment rules — roll actionsRolls close & re-open at the target strike, per bar.
Delta hedge — FUTURES actionThe archive has no futures bars, so futures hedging can't be replayed (the delta roll action does).
Alert-only rules (auto = off)They don't place orders anywhere — nothing to simulate.
Costs & slippageBacktest uses your flat ₹/leg + slippage%; live is your broker's actual charges.
Order fillsBacktest fills at the bar's open/close; live gets real fills — partial fills, freeze-splits and the odd rejection happen only live.
Timing resolutionBacktest = 1-minute bars; live = ~1-second ticks. Live can act up to a bar sooner, never later.
Instruments with historyNIFTY, SENSEX and BANKNIFTY are backtestable (history from May 2021, May 2023 and Sep 2024 respectively). FINNIFTY, MIDCPNIFTY, stock F&O and MCX have no usable backtest data — use a paper Forward Test.
Marketplace, copy trading, credits/billingLive-only features — not part of a replay.
Why live never matches a backtest exactly Three things a replay can't reproduce: (1) timing — 1-minute bars can't see an intra-minute spike the way live ticks do; (2) fills — your broker's real price, partial fills and rejections aren't in historical data; (3) your own hand — a live pause/stop, a connectivity blip, or a gap open all move the result. Treat a good backtest as strong evidence the LOGIC works, then confirm on a paper Forward Test before real money. Every backtest report also lists, in its Warnings panel, exactly which advanced features were simulated for that run.

What's loaded

On-the-fly Greeks

The archive carries OHLC + IV + OI but not Δ Γ Θ Vega. The engine computes them per-minute from (spot, strike, IV, DTE) via Black-Scholes. Theta ticks down throughout the day as DTE shrinks. Verified by 7 unit tests including ATM sanity, deep ITM/OTM bounds, Γ-peak-at-ATM, vega-peak-at-ATM, garbage-input guards, and put-call parity at 1e-9 precision.

Multi-instrument

Expression tokens like SENSEX.RSI(14) in a NIFTY backtest transparently load SENSEX spot bars in lock-step. Unsupported foreign underlyings (BANKNIFTY, FINNIFTY, MIDCPNIFTY, BANKEX) surface a clear Warnings entry instead of silently zeroing — see multi-instrument.

No-lookahead-bias

Honest backtesting

Common backtester bug: signal fires at bar X's close and "fills" at bar X's open. That's physically impossible — the open already happened 60s before the close existed — and inflates results.

This engine enforces a 1-bar defer: indicator signal at bar X → fill at bar X+1's OPEN. The rule applies to entry, exit_condition, per-leg SL/TG, AND combined SL/TG.

Pure-TIME strategies (no bar data read) still fill same-bar — no lookahead since no bar was consulted to decide.

Friction model

Two knobs in the Run-Backtest dialog:

The report has 3 tabs: Plain, Costs only, +Slippage — so you can see the friction sensitivity instantly.

Check Frequency throttle

Honored independently per surface: entry expression, exit expression, per-leg SL1/SL2/TGT1/TGT2/Trail, and combined SL/TG/Trail. You get three modes:

Use this to model "evaluate SL only on 5-min close" or "Combined SL every minute, per-leg SL every 5 minutes" mixtures.

Strike clamp at ATM±10

The archive only has ATM±10 strike data. Out-of-range legs are clamped to the boundary (with a warning) — never silently skipped. Live trading uses the exact strike you specified.

You'll also see a clamp notification toast in the Builder when:

Report & History

Every backtest produces:

Every run is persisted to Backtest History — a professional table you can filter by strategy/symbol/result, with one-click 🧪 Forward test and 🚀 Deploy live on each row.

How many forward tests do I get? 10 strategies, free. A forward test runs on the same live chain and engine a real deploy does, so the free tier gets enough to prove an edge: 10 different strategies, for as long as you like. Re-running one you've already forward-tested is always free — the limit counts strategies, not runs, and it never resets or expires. Need an 11th? Spend 10 credits for another permanent slot, or move to a paid Algo plan for unlimited forward tests. Your usage is shown on the Forward Test page.
One engine, one honest caveat Backtest, forward test and live run the SAME strategy engine — your logic behaves the same in all three. What a replay can't fully match is timing, fills and instrument coverage. See Backtest vs Live for the plain scorecard of exactly what matches and what doesn't.

Monte Carlo & sequence risk

Your backtest ran your rules over history once. The wins and losses arrived in one particular order — and that order is an accident of the window you picked. Take the identical set of trades, deal them in a different order, and your worst drawdown changes completely even though the total profit doesn't move at all. Live trading will deal you a different order. The Monte Carlo card on every report re-deals your own P&L series thousands of times so you can see the whole range instead of the single hand history gave you.

The coin-toss intuition. 100 tosses, 55 heads. The total is fixed. But whether the 45 tails arrive nicely spread out or as one brutal run of nine decides whether you'd still be trading at the end. Same edge, same final P&L — completely different experience, and a completely different capital requirement. Drawdown is a property of the order, and your backtest only ever showed you one.

First — what "p95" actually means

Every figure in this card is a percentile: rank all the simulated runs from best to worst, then ask where one of them sits. Read them as frequencies and they stop being jargon.

PercentileSay it out loud as…What it is to you
p519 in 20 runs are worseA lucky run. Don't plan around it.
p253 in 4 runs are worseA good run.
Median (p50)half the runs are worse The typical outcome — a coin flip either side.
p75 / p901 in 4 / 1 in 10 runs is worse Bad patches you should fully expect to live through.
p951 in 20 runs is worse The sizing number. Common, not a worst case — if twenty traders ran this strategy, one of them would get it.
p991 in 100 runs is worse The stress case. Survive it; don't budget for comfort.
Worstthe single worst of every simulation Not a limit — just the worst that happened to turn up. Run more simulations and it gets worse.
Mind the direction For drawdown, a higher percentile is a worse outcome (a deeper hole). For Net P&L, a higher percentile is a better one. That's why the report's table pairs the deepest-drawdown row with the worst-finishing P&L — both are the ugly tail, read from opposite ends. And note that sizing for the median means being wrong half the time.

The three methods

MethodWhat it re-dealsNet P&LUse it to
ShuffleThe order only — same trades, new sequence. Never changesIsolate pure sequence luck.
BootstrapWhich trades happen at all (drawn with replacement). VariesSee the outcome range for the same edge.
Block bootstrap
default, blocks of 10
Which trades, keeping streaks glued together. VariesGet the realistic worst case — this is the one to size on.

Why Shuffle can never change your P&L. Adding the same numbers in a different order gives the same total — so at the engine's fixed quantity, reordering trades moves the path and nothing else. That's a feature: it isolates drawdown from every other variable. If you want the P&L itself to vary, you have to change which trades occur, and that's what the two bootstrap methods do.

Why Block is the default. Losing days in option selling are not independent — they cluster, because one trending week punishes every single day of it. Plain shuffling scatters those losses apart and makes the strategy look safer than it really is. Block bootstrap keeps them together in runs, which is why it usually reports the deepest and most honest drawdown.

A free diagnostic Flip between Shuffle and Block bootstrap. If Shuffle says your realized drawdown was freakishly bad but Block says it was ordinary, your losses cluster — and that clustering is a permanent feature of the strategy, not bad luck. Size for the Block number.

Every number, and what to do about it

NumberWhat it actually meansWhat to do about it
Observed max DDThe dip your backtest actually produced. Treat it as one sample, not "the" drawdown.
Its percentile rankWhere that dip sits among all the re-deals. Under the 25th = history was kind to you; expect live to be worse.
Median (p50)The typical dip — half of re-deals are worse. Your normal bad patch. Expect to meet it.
p95 max DDBeaten only 1 time in 20. Size your capital on this. The single most useful number in the card.
p99 / worstThe stress case. Confirm you'd survive it — not that it's comfortable.
p95 DD ÷ marginThat dip as a share of capital actually at risk. Past ~30% it's very hard to sit through. Near 100% the account is gone.
Risk of ruinHow often the drawdown alone exceeds your whole base. Anything above zero means cut the quantity, not "accept the risk".
Max time underwaterLongest stretch below a previous equity high. Depth breaks accounts; length breaks conviction. This is what makes traders switch off a strategy that works.
Longest losing streakConsecutive losing days/trades to expect. Know it before you meet it, so a normal streak doesn't read as a broken strategy.
p5 net P&L1 re-draw in 20 finishes at or below this. If negative, the same edge can plausibly lose money over this span.
Chance of a losing runHow often the same edge ends net negative. Above ~20% the edge is thin — trade smaller or lengthen the horizon.

Reading the two charts

Settings

UnitPer day (default) resamples whole trading days and matches how the Max DD pill is computed. Per trade is finer-grained but treats same-day trades as independent, which they usually aren't.
BlockHow many consecutive periods stay glued together (Block bootstrap only). Larger blocks preserve longer streaks. 10 is a sensible default for daily data; try 20–40 if your strategy's bad patches run for weeks.
Simulations1,000 / 5,000 / 10,000. More sims don't add information — they just measure the same distribution more precisely. 5,000 is plenty.
ResampleResults are seeded, so the same report always shows the same numbers (a risk figure that changes on every page load is not something you can size to). Press Resample for a fresh draw.

Runs entirely in your browser off the report you already have — no re-run, and it costs no backtest credits. It also works on any saved run reopened from Backtest History.

What Monte Carlo cannot tell you
  • It can only re-deal what your backtest already contained. If your window holds no crash, no re-deal will invent one — a quiet period resamples into a reassuring, and wrong, answer. Test across a range that includes ugly markets.
  • It assumes future trades resemble the tested ones. An overfit strategy resamples into confidently precise nonsense. Monte Carlo measures consistency; it does not validate an edge.
  • It does not re-price slippage, liquidity, or a broker margin call landing mid-drawdown. Real ruin arrives earlier than the "risk of ruin" figure suggests.
If you remember one thing Size on the p95, not on what the backtest happened to show. Then ask honestly: could I keep trading through the p99 drawdown, for the full time-underwater figure, without switching this strategy off? If the answer is no, the strategy isn't the problem — the position size is.

Parameter sweep — variants, not clones

On the Backtest page, tick Parameter sweep to compare tweaks of ONE strategy without saving a copy per tweak. The composer mirrors the sections your strategy actually configures — each leg's Stoploss row (type / value / then / then) and the enabled Adjustment rules — using the builder's own controls. Change any combination, name it, + Save as variant. Variants persist on the strategy, so the same comparison re-runs later on any date range.

Live trading · broker adapters

AdapterStatusUse case
stubREADYNo real orders. Lifecycle / smoke tests.
paperREADYFills at current LTP from quote feed. Realistic dry-run with live data.
kiteREADYZerodha — real orders on the assigned broker account.
dhanREADYDhan — real orders on the assigned broker account.

Strategy lifecycle

  1. Start — registry spawns a supervised goroutine for the strategy.
  2. Wait for entry — evaluates entry condition every tick (or per check_freq) until firing.
  3. Resolve strikes — uses the per-leg strike-selection mode (Distance / Premium / Delta / OI-based / etc.).
  4. Fire legs — atomically, per execution-mode (parallel / sequential / buy-first).
  5. Monitor — quote feed per leg → per-leg SL/TG → combined SL/TG → trail SL — all gated by their own check_freq.
  6. Exit — on SL/TG hit, exit-condition fire, sqoff time, or kill-switch.
  7. Settle — records realised P&L, updates daily-loss counters, marks strategy complete.

Forward Test & live runs · editing a running strategy

A Forward Test is simply a strategy deployed to a Demo / paper broker account — simulated fills at live prices, monitoring only. There is no separate "forward test" object: assign a saved strategy to a Demo account from the Strategies page and it appears under Forward Test. The slot is keyed to the saved strategy, so re-running one you have already tested never consumes another.

Expand any row to reach Positions · Orders · Trades · Logs, and the live override panel. Everything there applies to the running strategy immediately — it does not edit the saved recipe, and it survives a restart.

ControlWhat it does
Combined SL / Target ₹ overrideReplace the basket stop or target mid-run. 0 disables that limit.
Combined TrailingThe give-back trail — arm at ₹, then every ₹step raises the floor by ₹lock. Floor always sits below the peak.
Profit Lock & TrailingThe absolute-floor guard — the same four fields as the Builder tab of that name. Editable live since 2026-08-12.
Pause / ResumeStop acting on triggers without closing anything.
Square-offClose every open leg at market now.
External CloseBook a leg at a price you supply without sending a broker order — for positions you exited outside the platform.
Per-leg SL / TGTEdit an individual leg's stop or target from its row in the positions table.

Editing Profit Lock on an open position can close it immediately. The floor is derived from the peak MTM the run has seen, not from where P&L is now. If profit has already pulled back below the floor your new numbers imply, the lock is breached the moment it arms. The platform checks this before applying and shows you the actual floor, peak and current MTM — you can still choose to go ahead, and the position will book on the next tick.

Two sizing reminders that bite here. Every ₹ figure is on the whole basket, so it must scale with lot count — a ₹20,000 target or lock built for 10 lots fires far too early on 17. And the account multiplier on the strategy-to-account link multiplies your lots again: a strategy set to 17 lots linked at ×17 trades 289 lots, which will exceed the exchange freeze limit and fail. Keep the size in one place and the multiplier at 1.

Leg execution modes

Fail policies when any leg fails to fill:

On-Hit actions

Fire on SL or TGT events at the leg level (Step 4 → SL/TGT tabs) or the basket level (Step 5 → Combined SL/TGT). See the Step 4 action catalog for per-leg; basket-level actions are listed in Step 5. All actions can chain and most carry a delay parameter for staged behaviour.

Hedges & Move-SL-to-Cost

Risk gate

SettingEffect
Max Daily LossKill switch — once realised P&L for the day drops below this, no new entries fire (across all strategies). Resets at IST midnight.
Max Daily TradesCap on entry count per day.

Webhook entry & exit (OnSignal)

Create a Signal, wire strategies and broker accounts to it, and it gets its own URL — /api/webhook/sig/{token}, shown behind the 🔗 on the Signals page. POST to it from TradingView, Chartink, Python or any HTTP source. The token is the auth, so treat the URL as a password.

One Signal can enter and exit, fan out to several strategies × broker accounts with a per-route quantity multiplier, take the instrument and size from the alert body, ignore duplicate alerts, check the broker is logged in before ordering, and log every step under Signals → Logs.

One URL, and the alert says what it is. Paste the same webhook URL into every TradingView alert for that strategy; each alert names its type in signal_type. The Signal's strategy rows then decide what that alert is allowed to be — a type you never wired is refused and logged, never quietly turned into something else. Omit signal_type and every wired row fires, which is how older integrations keep working unchanged.

signal_typeRow to wireWhat happens
LONG ENTRYLong Entry (or Entry)Open a long. A repeat while one is open is a pyramid add when the Signal allows it.
SHORT ENTRYShort Entry (or Entry)Open a short.
LONG EXITLong Exit (or Exit)Close the long — fully, or partly if the alert carries qty.
SHORT EXITShort Exit (or Exit)Close the short, same rule.
ENTRY / EXITEntry / ExitMulti-leg strategies, which have no single side.
UPDATEUpdate riskChange the stop, target, trailing or profit lock of a position already open. Can never open or close one.

Short codes (LE, SE, LX, SX, E, X) work too, as do the words a TradingView strategy tends to emit — buy, stoploss, tp, square_off.

Every other field is optional, and anything you leave out keeps the strategy's saved value:

Sent onFields
Entry symbol · fut_opt (FUT/CASH/OPT) · expiry · option_type · strike_offset · side · qty (in lots; qty_units for raw contracts) · sl · tgt · trailing · legs (multi-leg; replaces the saved legs and their risk settings)
Exit qtyomit it to close the position. A quantity in lots releases just that much of every open leg and leaves the rest running, so a straddle stays a straddle; a quantity at or above what is open closes it anyway. qty_pct does the same as a percentage.
Update sl_inr · target_inr (basket ₹; 0 removes the limit, which is how you go to breakeven) · trailing · profit_lock · force · leg with sl_price / target_price / trail

sl and tgt on an entry carry no unit — they are read in whatever unit the strategy already uses, percent of entry premium by default or points if the strategy is set that way. A TradingView alert cannot know which, and making it declare one is how a 30-point stop ends up applied as 30%. Use sl_pct or sl_points when you do want to be explicit.

Two rules that are easy to trip over: omitted is not zero — leaving a field out means "don't touch it", while 0 is a real value that removes a limit — and an empty object ("trailing": {}) reads as omitted, so it cannot wipe a live trail. Numbers may arrive as strings, since TradingView substitutes its {{…}} placeholders as text before sending.

A profit lock sent by webhook can close the position. Its floor comes from the peak MTM the run has seen, not from where P&L is now, so a lock sent after a pullback may already be breached and would book the basket on the next tick. The app asks the operator to confirm; an alert has nobody to ask, so the engine refuses it and logs the floor, peak and current MTM under Signals → Logs. Add "force": true only if immediate booking is genuinely what you want.

Test it from a terminal before pointing TradingView at it:

# entry — the type is the only field that always matters
curl -X POST https://algo.fnotrader.com/api/webhook/sig/<signal-token>   -H 'Content-Type: application/json'   -d '{"signal":{"signal_type":"LONG ENTRY","symbol":"NIFTY","fut_opt":"FUT","qty":2}}'

# book half, leaving the rest running
curl -X POST https://algo.fnotrader.com/api/webhook/sig/<signal-token>   -H 'Content-Type: application/json'   -d '{"signal":{"signal_type":"LONG EXIT","qty":1}}'

# → {"signal":"NIFTY breakout","started":1,"squared_off":0,"updated":0}
#   the counts tell you what the alert actually did

Worked examples — every one of these goes to the same URL:

ScenarioRow to wireAlert body
Go long, exactly as savedLong Entry{"signal":{"signal_type":"LONG ENTRY"}}
Go long, alert picks instrument, size and riskLong Entry{"signal":{"signal_type":"LONG ENTRY","symbol":"NIFTY","fut_opt":"FUT","qty":2,"sl":30,"tgt":50}}
Go shortShort Entry{"signal":{"signal_type":"SHORT ENTRY","qty":2}}
Close the positionLong Exit / Short Exit{"signal":{"signal_type":"LONG EXIT"}}
Book part of it (TP1 / TP2 / TP3)Long Exit{"signal":{"signal_type":"LONG EXIT","qty":1}} — send again at each level
Add to a winner (pyramid)Long Entry, with Pyramid ticked and Max positions setthe entry body again; the count is how many adds are accepted
Reverseone row typed LX, SE{"signal":{"signal_type":"SHORT ENTRY","qty":2}}
Multi-leg entryEntry{"signal":{"signal_type":"ENTRY"}}, or add "legs":[…] to compose the basket
Multi-leg exit, whole or partExit{"signal":{"signal_type":"EXIT"}} · {"signal":{"signal_type":"EXIT","qty":1}}
Same alert, several brokersone row per broker, each with a multiplierunchanged — the multiplier scales the size per account
Move to breakevenUpdate risk{"signal":{"signal_type":"UPDATE","sl_inr":0}}
Change stop / target / trailing mid-tradeUpdate risk{"signal":{"signal_type":"UPDATE","sl_inr":8000}}

In TradingView the Signal's URL goes in the Webhook URL field and the body in the Message box — the same URL in every alert for that strategy. TradingView substitutes its own {{…}} placeholders before sending, so "qty":"{{strategy.order.contracts}}" works. Don't pipe {{ticker}} into symbol for derivatives: a charting ticker like NIFTY1! is not the tradable root.

Staged booking works either way: send an exit alert carrying a qty at each of your levels, or set SL/TGT ladders on the legs and let the engine take the position off in stages on its own triggers, with no alert at all.

Telegram notifications

Tick Send to Telegram in Step 6 to mirror every lifecycle event to your bot — entry fills, SL/TG hits, leg closes, re-entries, auto-hedge applied. Configure bot_token + chat_id in config.yml. Buffered, non-blocking, Markdown-formatted.

Signals · repeat policy (ignore vs pyramid)

A webhook sender can retry or double-fire. Each Signal chooses what a REPEAT same-side entry does while that strategy is already live on that broker: with Pyramid on repeat signals unticked (the default), the repeat is ignored and logged in the signal log — your position cannot be multiplied by a duplicated alert. Ticked, each repeat ADDS another position up to Max positions (a ceiling always applies). A same-side check is side-aware: a Short Entry while a long is open is a reversal, not a repeat, and still fires. Exit signals always close every matching run.

Deployments & mornings

Strategy recipes

Fifteen worked examples covering the breadth of features. Each is a complete spec you can paste into the builder.

These are examples, not recommendations. The recipes below show what can be configured — starting points to learn the builder's vocabulary, not strategies to trade as-is. Every watch instrument, metric, timeframe, condition, leg and risk control combines freely, so imagination is the limit when creating your own. Backtest anything before deploying it live.

R1 · Short Straddle Beginner

UnderlyingNIFTY · Current Weekly
EntryTIME >= 0920
Legs SELL PE · ATM · 1 lot · SL 30% · TG 50%
SELL CE · ATM · 1 lot · SL 30% · TG 50%
Sqoff15:25
WhyThe Hello-World of premium selling. Sell both ATM legs at the bell, exit on either side hitting SL or by EOD.

R · Protected BTST straddle Intermediate

UnderlyingNIFTY · Current Weekly · Product NRML
Entry (3C)Start 15:15 · Exit 09:20 next day (overnight hold)
Legs SELL PE ATM · 1 lot
SELL CE ATM · 1 lot
Overnight Protect (3D)Strike by Delta ≈ 0.08 · apply 15:20 · remove 09:20
WhyHarvest overnight theta on an index that usually opens flat, with constant-cost delta-0.08 wings capping any gap. Fully backtestable — the report shows the hedge's cost/benefit on every gap.

R · Self-managing short straddle Advanced

EntryTIME >= 0920 · SELL ATM CE + PE
Adjust (4B) Delta hedge roll at net 0.25
Rebalance at 2.5× → cheap side to 80%
Leg-price roll-away at +60% (backstop)
GuardsMax 3 rolls/day · 60s cooldown · min CE−PE gap 100
Sqoff15:20
WhyOne straddle that adapts to trend (delta hedge), range decay (rebalance) and shock (leg-price backstop) without intervention — impossible with SL/Target alone. Backtests replay every roll so you can tune the thresholds against history.

R2 · Iron Condor with hedges Beginner

EntryTIME >= 0920
Legs SELL PE ATM · SL 30% · TG 50%
SELL CE ATM · SL 30% · TG 50%
BUY PE OTM3 · Hedge ✓
BUY CE OTM3 · Hedge ✓
CombinedMove SL to Cost when basket MTM > +₹1500
WhyDefined-risk short strangle. Hedges cap max loss and qualify for margin benefit. Move-SL-to-Cost locks breakeven once the trade pays you something.

R3 · EMA-crossover long CE Beginner

WatchOPT_ATM_CE · 5m TF
EntryTIME >= 0925 AND OPT_ATM_CE.CLOSE > OPT_ATM_CE.EMA(10)
LegsBUY CE · ATM · SL 25% · TG 50%
WhyPure directional. Enter long CE only after the option price closes above its own 10-period EMA on 5m — confirms intra-bar momentum before paying premium.

R4 · Range Breakout strangle Intermediate

EntryNIFTY.CLOSE range_breakout_either (window 09:15–10:00)
LegsSELL OTM2 CE + SELL OTM2 PE
SL30% per leg · Combined TG ₹2000
WhyFade the post-breakout drift. Wait for the 09:15–10:00 range to be defined, then sell wings once direction reveals itself.

R5 · PCR-gated straddle Intermediate

WatchATM_CE · ATM_PE
Entry Row 1: TIME ≥ 0930
Row 2: ATM_PE · OI · ÷ · ATM_CE · OI · > · 1.5 (use the arithmetic ÷ between the two metrics)
Compiled: TIME >= 0930 AND (ATM_PE.OI / ATM_CE.OI) > 1.5
LegsStandard short straddle
WhyOnly sell premium when there's evidence puts are being aggressively positioned (PCR > 1.5 at ATM) — i.e. crowd is hedging hard, vol-of-vol likely topped.

R6 · IV-filtered iron fly Intermediate

EntryTIME >= 0920 AND ATM_CE.IV > 18
LegsIron Condor (R2 setup) — only fires on elevated-IV days.
WhyPremium selling pays only when IV is rich. Add a single IV gate to skip low-vol "death by theta" days.

R7 · BTST overnight strangle Intermediate

ModeStep 3C · BTST · Start 15:15 · Exit 09:30
LegsSell OTM2 CE + OTM2 PE
Combined SL₹1500
WhyCapture overnight theta on a defined window. Position late, square next morning before any post-open drift bites.

R8 · Cross-index gate Advanced

UnderlyingNIFTY
EntryTIME >= 0920 AND SENSEX.CLOSE > SENSEX.EMA(10)
WhyTrade NIFTY only when the broader market (SENSEX) agrees. Diversification of signal source — reduces false starts on NIFTY-internal noise.

R9 · Delta-gated CE seller Advanced

WatchATM_CE
EntryTIME >= 0920 AND ATM_CE.DELTA > 0.4 AND ATM_CE.DELTA < 0.6
LegsSELL CE · ATM · Combined TG ₹2000
WhySell only at-the-money calls. Filter for "true ATM" via Δ in (0.4, 0.6) — protects against early-DTE drift where the nominal ATM strike has already moved deep ITM/OTM.

R10 · Multi-level SL ladder Advanced

LegSELL CE ATM · 1 lot
SL115% · Qty 50% · action just exit · check freq tick
SL230% · Qty 100% · action move_sl_to_cost on remaining · check freq 5m close
WhyScale-out on first stop, kill on second. Different check frequencies let SL1 trigger on a wick while SL2 only fires on a 5m close — fewer false flushes.

R11 · Combined SL kill-switch + re-enter Advanced

Combined SL₹2000 · action close_and_re_enter_strategy · delay 300s · NTimes 2
WhyIf the basket goes ₹2000 against you, flatten and re-enter at fresh levels after 5 minutes. Cap at 2 re-entries per day so you don't martingale forever.

R12 · 5m TF indicator + 1m execution Advanced

WatchOPT_ATM_CE · TF = 5m
EntryOPT_ATM_CE.CLOSE > OPT_ATM_CE.EMA(10)
Check freqtick (= 1m)
WhyEMA(10) computes on 5-min candles. The condition is re-checked every minute but only flips state on the 5-min close. Lets you react quickly (1m) while still using a noise-resistant trend filter (5m).

R13 · ATM CE/PE OI crossover → buy PE Intermediate

WatchTwo instruments: ATM_CE and ATM_PE — Option (single strike) · Relative → ATM · ATM tracking Auto · Timeframe 3m
EntryATM_CE · OI · Crossing Up · instrument · ATM_PE · OI — true on exactly the bar where CE open interest crosses above PE open interest
LegBUY PE ATM · 1 lot · SL 30% · target 60%
Check freqevery 3-min bar close — evaluated once per bar, entry fills at the next bar's open
WhyRising CE OI overtaking PE OI = fresh call writing dominating — sellers positioning against upside. The classic read is bearish, so the recipe buys the PE. The crossover form fires once at the flip, not on every bar CE stays ahead; ATM tracking keeps both books on the CURRENT strike (OI continuity resets on a re-strike, so the switch itself can never fake a cross).

R14 · OI-Chg crossover — 3-minute flow flip Advanced

WatchSame two ATM watches as R13 (Auto tracking · 3m)
EntryATM_CE · OI Chg · (vs day open) · Crossing Up · instrument · ATM_PE · OI Chg
LegBUY PE ATM · 1 lot · SL 30% · Profit Lock reaches ₹1500 → lock ₹700
Check freqevery 3-min bar close
WhyInstead of the absolute OI books (which carry days of history), this compares the day's FLOW: whose open interest is being built faster since today's open. The change basis matters — vs day open reads the running build since 09:15; vs prev bar would read only the last 3 minutes; vs prev day close includes the overnight adjustment. Both sides share the basis, so the comparison is like-for-like.

R15 · Multi-timeframe Supertrend BUY / SELL Intermediate

WatchThe SAME underlying twice with the SAME alias: SPOT (NIFTY) at Timeframe 5m and SPOT at 15m — the builder auto-suffixes them to SPOT_5M and SPOT_15M so each is addressable separately
Entry (BUY)Two rows combined with AND (all):
SPOT_5M.CLOSE > SPOT_5M.SUPERTREND(10,3)
SPOT_15M.CLOSE > SPOT_15M.SUPERTREND(10,3)
LegBUY CE ATM · 1 lot · SL 30% · trail 20/10/5%
Check freqevery 5-min bar close — the 15m Supertrend only flips on its own bar closes, so the AND naturally waits for both timeframes to agree
WhyPrice above Supertrend = uptrend on that timeframe. Requiring BOTH the fast (5m) and slow (15m) trends to agree filters the fast frame's whipsaws: the 5m gets you in early, the 15m keeps you out of counter-trend noise. For the SELL mirror, flip both comparisons to < and BUY the PE (or SELL the CE) — same structure, opposite side.

R16 · Rolling ATM straddle breaks its VWAP → short straddle Intermediate

WatchOne instrument: Scope Rolling ATM Straddle · NIFTY · Expiry current weekly · Alias ROLL_STRDL
EntryTwo rows, AND (all):
ROLL_STRDL.LTP < ROLL_STRDL.VWAP
a time condition after 09:30 — see Why
LegsSELL CE + SELL PE · Strike Mode Rolling ATM · Distance ATM · 1 lot each · per-leg SL 30%
ExitPer-leg SL/target and a square-off time — deliberately NOT a condition on ROLL_STRDL; see Why
Check freqevery 1-min bar close
WhyThe straddle premium falling below its own session VWAP says the day is decaying rather than trending — the condition premium sellers actually want. Two settings carry most of the risk here. The time gate: a session VWAP is only as old as the session, so the first cross often lands ~09:16 on two bars of data, which is close to a coin flip; 09:30 gives it something to mean. Strike Mode = Rolling ATM: the legs then sell the strike the SIGNAL was computed on. The published series picks MIN(CE+PE) over ±5 strikes, which sat one strike away from round(spot/step) on 52% of minutes on 10 Aug — with plain Distance you would routinely sell a different contract than the one that triggered, and nothing in the order book would look wrong. And the exit: ROLL_STRDL keeps rolling after you are filled while your sold straddle stays pinned, so an exit written against the alias slowly stops describing the position it is meant to protect.

Known limits

Glossary

TermMeaning
ATMAt-the-money. Strike closest to current spot.
ATM±NN strike steps away from ATM (typically 50pt for NIFTY, 100pt for BANKNIFTY).
OTMOut-of-the-money. CE strike > spot, or PE strike < spot.
ITMIn-the-money. Opposite of OTM.
DTEDays to expiry.
MTMMark-to-market — current unrealised P&L.
NRMLCarry-forward (overnight) product.
MISIntraday product — must square off by 15:25 IST.
PCRPut-Call Ratio. OI(PE) / OI(CE) — at a strike or aggregated.
IVImplied Volatility (%).
VWAPVolume-Weighted Average Price (day-anchored).
Lookahead biasBacktester bug where a signal fills at a price that didn't yet exist when the signal computed.
Combined SL/TGBasket-level stop/target on the sum of all open-leg PnLs.
Move-SL-to-CostAction that moves every other leg's stop to its entry price (lock breakeven).
BTST / STBTBuy-Today-Sell-Tomorrow / Sell-Today-Buy-Tomorrow — overnight hold.
Hedge legA BUY leg flagged to cap basket loss; excluded from Move-SL-to-Cost; exits last.
Idle legLeg that doesn't fire at entry — activated only by another leg's execute_other_leg action.

FAQ

Why are my backtest trades different from yesterday's run?

Most likely you tweaked something in the Builder, or the engine received a lookahead-bias fix / Greeks fix / TF-fix in a recent release. If the recipe is unchanged and pre-dates a fix, results should diverge — the older results were quietly wrong.

My strategy never enters in backtest. Why?

Check the Warnings panel of the report. Common reasons:

Why is my entry timing one bar later than my signal?

That's the lookahead-bias guard working as intended — see No-lookahead-bias. Pure-TIME entries don't defer; only indicator-driven entries do.

How do I compute strike-wise PCR?

Pick the primary metric (e.g. ATM_PE · OI), then choose ÷ from the arithmetic-combinator dropdown in the same row, then pick the second metric (ATM_CE · OI). Set the operator to greater than and the RHS value to 1.5. The Preview compiles to (ATM_PE.OI / ATM_CE.OI) > 1.5 and the backtest/live engine evaluates it natively — no special PCR metric needed because the same UI supports any ratio / sum / difference / product of two metrics.

What's the difference between "tick" and "xm_close" check freq?

tick evaluates every minute bar. xm_close only evaluates on bars whose minute-of-day mod X is zero — so 5m_close fires at 09:20, 09:25, 09:30, … and ignores the bars between. Use xm_close to model "candle-close confirmation" entry/exit logic.