Appearance
Personalize your experience
Mode
Accent Color
Layout
Direction
Opening Range Breakout
FreeClassic ORB strategy for NSE equities and index futures
4.5(112)
2.8k installs 530 2 commentsA
orbbreakoutintradaynsefutures
Preview
1 / 2
Chart preview
About
Waits for the first 15-minute candle to establish a range, then enters breakouts with ATR-based stop-loss.
Rules
1. **Range**: First 15 min high/low
2. **Entry**: Breakout above range high (long) or below range low (short)
3. **Stop**: 1.5× ATR below entry
4. **Exit**: Daily close or stop hit
Strategy Rules
Entry Conditions
- ▸ Price breaks first 15-min candle high/low
- ▸ Time < 12:00 PM IST
Exit Conditions
- ▸ Daily close
- ▸ ATR-based stop hit
Backtest Results
29.7%
Return
1.45
Sharpe
-9.8%
Max DD
52.6%
Win Rate
410
Trades
Source Code
Edit in IDEtypescript
| 1 | // Opening Range Breakout (ORB) Strategy — Quatick IDE |
| 2 | // SDK math globals available: sma, ema, atr, rsi, macd, bollingerBands, vwap, etc. |
| 3 | |
| 4 | const metadata = { id: 'orb-strategy', name: 'Opening Range Breakout', version: '1.0.0', category: 'strategy' }; |
| 5 | |
| 6 | interface BarData { |
| 7 | time: number; |
| 8 | open: number; |
| 9 | high: number; |
| 10 | low: number; |
| 11 | close: number; |
| 12 | volume?: number; |
| 13 | } |
| 14 | |
| 15 | const defaultParams = { |
| 16 | orbBars: 15, |
| 17 | atrPeriod: 14, |
| 18 | atrMultiplier: 1.5, |
| 19 | }; |
| 20 | |
| 21 | function run(data: BarData[], config = defaultParams) { |
| 22 | const highs = data.map(d => d.high); |
| 23 | const lows = data.map(d => d.low); |
| 24 | const closes = data.map(d => d.close); |
| 25 | |
| 26 | // atr() is an SDK global: atr(high[], low[], close[], period) -> number[] |
| 27 | const atrValues = atr(highs, lows, closes, config.atrPeriod); |
| 28 | |
| 29 | const trades: { entry: number; exit: number; direction: string; pnl: number }[] = []; |
| 30 | let position: string | null = null; |
| 31 | let entryIdx = 0; |
| 32 | let stopLoss = 0; |
| 33 | |
| 34 | let rangeHigh = -Infinity; |
| 35 | let rangeLow = Infinity; |
| 36 | |
| 37 | for (let i = config.orbBars; i < data.length; i++) { |
| 38 | if (i === config.orbBars) { |
| 39 | for (let j = 0; j < config.orbBars; j++) { |
| 40 | if (data[j].high > rangeHigh) rangeHigh = data[j].high; |
| 41 | if (data[j].low < rangeLow) rangeLow = data[j].low; |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | if (!position && data[i].close > rangeHigh && !isNaN(atrValues[i])) { |
| 46 | position = 'long'; |
| 47 | entryIdx = i; |
| 48 | stopLoss = data[i].close - config.atrMultiplier * atrValues[i]; |
| 49 | } |
| 50 | |
| 51 | if (position === 'long') { |
| 52 | if (data[i].low <= stopLoss) { |
| 53 | trades.push({ entry: entryIdx, exit: i, direction: 'long', pnl: stopLoss - data[entryIdx].close }); |
| 54 | position = null; |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | return { |
| 60 | trades, |
| 61 | totalTrades: trades.length, |
| 62 | winRate: trades.length > 0 ? (trades.filter(t => t.pnl > 0).length / trades.length) * 100 : 0, |
| 63 | totalPnl: trades.reduce((sum, t) => sum + t.pnl, 0), |
| 64 | }; |
| 65 | } |
Read-only preview. Open in the QuaTick IDE to edit and deploy.
Reviews
No reviews yet. Be the first to review this listing.
Discussion
Sign in to join the discussion. Your posts and replies show up on your profile.