Detailed reference for strategy scoring, risk management, firefighting, and position lifecycle.
File: core/strategy_scorer.py
FMS (Final Market Sentiment) is a single number from -10 to +10. Purely directional — no VIX influence.
FMS = weighted_sum( trend × 0.35, # EMA/SuperTrend/ADX direction macd × 0.15, # MACD histogram direction + crossover rsi × 0.15, # RSI zone with momentum macro × 0.20, # Global macro score from 31 instruments intraday_bias × 0.15 # VWAP position + candle structure ) Range: -10.0 to +10.0 Sign: positive = bullish, negative = bearish Magnitude: |FMS| > 6 = strong trend, |FMS| < 2 = neutral
Each strategy has a piecewise-linear mapping from FMS to base score (0-100):
Short Straddle: Peak at FMS=0 (neutral). Score=85 at center. Drops to 0 at |FMS|≥5. The default seller — maximum theta in range markets.
Short Strangle: Broader peak. Score=80 at FMS=0, stays above 60 through |FMS|≤2. Handles mild directional lean with wider breakevens.
Iron Condor: Peaks at |FMS|=3-4 (mild trend). The overlap zone where straddle/strangle are fading but BCS/BPS haven't fully activated. Last seller standing.
BCS: Activates at FMS ≥ +3. Peaks at FMS = +7. Zero below +2. Needs confirmed bullish momentum.
BPS: Mirror of BCS. Activates at FMS ≤ -3. Peaks at FMS = -7.
VIX Level score: VIX < 11: very_low → sellers: 1.1x, buyers: 0.8x VIX 11-14: low → sellers: 1.05x, buyers: 0.9x VIX 14-18: normal → 1.0x for all VIX 18-24: elevated → sellers: 0.9x, buyers: 1.1x VIX 24-30: high → sellers: 0.7x, buyers: 1.2x VIX > 30: extreme → sellers: 0.5x, buyers: 1.3x VIX Direction modifier: Falling → sellers +0.1x, buyers -0.05x (theta-friendly) Rising → sellers -0.1x, buyers +0.1x (movement helps buyers) Stable → no change Final: VIX_mult = level_mult × direction_mod
Composite of VIX level + trend strength + regime volatility. Range: 0.5 to 1.2.
High hostility penalizes unlimited-risk sellers (straddle, strangle) more than defined-risk strategies (IC, BCS, BPS).
IV Rank >60: premiums are rich → sellers get +5-10% boost. IV Rank <30: premiums are cheap → buyers get boost.
final_score = base_score × VIX_mult × hostility_mult × IV_rank_mod Threshold: 55% — below this, strategy not recommended Selection: highest scoring strategy above threshold
File: core/risk_engine.py
Starting from base (30% sellers, 20% buyers), SL tightens based on:
| Factor | Sellers | Buyers |
|---|---|---|
| VIX rising | -3% (tighter) | No change (momentum helps) |
| VIX falling | Trail earlier | -3% (IV crush hurts) |
| VIX elevated/high | -2% to -5% | No change |
| DTE = 0 (expiry) | -5% | -5% |
| DTE ≤ 2 | -3% | -3% |
| Trend strength >70% | -3% | No change |
| Low confidence (<40%) | -5% | -5% |
| After 2:15 PM | Trail earlier | -3% |
Final SL clamped to: sellers [20%, 30%], buyers [15%, 20%].
Activation: profit reaches 25-30% of premium/debit Mechanism: floor ratchets UP only Sellers: floor = 70% of peak profit (keep 70%, give back max 30%) Buyers: floor = 80% of peak profit (tighter — time works against) Example (seller, peak ₹15,000): Floor = ₹10,500. If P&L drops below ₹10,500 → exit. Peak rises to ₹20,000 → floor rises to ₹14,000. Never goes back. Score decay tightening: if strategy score drops 20% from entry, floor tightens to 80% (sellers) or 85% (buyers) of peak.
Backup hard cap in absolute rupees. Prevents percentage SL from being too loose on large positions.
Sellers: 30% of premium collected in ₹ Buyers: 20% of debit paid in ₹ Minimum: max(₹500, 5% of position value) Tightens with DTE and conditions (same factors as % SL)
File: core/firefighter.py (1350 lines)
Position Manager monitors every tick:
loss_severity = current_loss / SL_threshold (0.0 → 1.0+)
if severity >= 1.0 → HARD SL EXIT (safety net, non-negotiable)
if severity >= 0.30 → ADJUSTMENT ZONE:
Build FirefighterContext (bias, OI, macro, delta, surge, tier)
→ Firefighter.analyze(context)
→ Returns: action + reason + urgency + confidence
→ Trading engine executes the recommendation
| Tier | Severity Range | Philosophy |
|---|---|---|
| TIER 1 | 30% of SL | Advisory. Mild trouble. Conservative action — roll if clear signal. |
| TIER 2 | 50% of SL | Active. Must act. Lower thresholds — roll even without strong signal. |
| TIER 3 | 70% of SL | Emergency. Last chance before SL. Aggressive — do whatever it takes. |
Priority order (checked in sequence):
0. DELTA TIER (independent, unlimited rolls)
Trigger: position delta drifts ≥0.25 from entry base
Action: roll profitable (untested) side closer
Purpose: restore delta neutrality
Note: fires even at NORMAL severity, no roll limit
1. VIX SPIKE OVERRIDE (any tier)
Trigger: VIX change ≥1.5% from entry AND no wings
Action: buy both CE+PE wings immediately
Purpose: convert unlimited risk → defined risk (Iron Butterfly)
Note: highest priority, 95% confidence
2. ROLL PROFITABLE SIDE (all tiers, max 3 total)
Triggers:
- Tested side surge ≥ threshold (T1: 25-30%, T2: 20-25%, T3: 15-20%)
- Spot moved ≥0.35% + trend strength ≥30%
- At T2/T3: even without surge
Action: roll untested side closer to collect credit
Thresholds: lowered by urgency modifier (bias, OI, macro confirming)
ITM allowed: yes — delta management over moneyness rules
3. MAX ROLLS → TIGHTEN SL (T3 only)
Trigger: 3 SL-tier rolls exhausted
Action: tighten SL for controlled exit
Simpler than strangle — wings already exist, no wing-buying needed. 0. DELTA TIER: same as strangle (unlimited rolls) 1. T1/T2/T3: roll untested spread closer (max 3 rolls) 2. Max rolls: no further action (defined risk via wings)
Different philosophy — these are BUYING strategies with defined max loss.
Goal: salvage value before SL hits.
TIER 1: NARROW THE SPREAD
Action: roll short leg 1 strike closer (e.g. 25750→25650 for BCS)
Purpose: collect credit, reduce net debit
Max: 1 narrow per position
TIER 2: ADD SHORT LOTS
Action: add ~25% extra short lots at narrowed strike
Purpose: premium cushion before SL
Example: 14L/14S → 14L/18S (+4 naked shorts)
TIER 3: SCENARIO ANALYSIS
Classifies WHY the loss is deepening:
Scenario A — TREND REVERSAL:
Intraday bias has flipped back to entry direction
Action: add ~25% long lots (average into recovery)
Example: 14L/18S → 18L/18S
Scenario B — CONTINUATION DRIFT:
Spot drifting steadily against entry, slow bleed
Action: add ~25% more short lots (premium cushion)
Example: 14L/18S → 14L/22S
Scenario C — SHORT LEG SURGING:
Short leg losing disproportionately (gamma/IV pressure)
Action: add ~25% long lots (restore delta balance)
MAX ADJUSTMENTS: 3 total (1 narrow + 1 add + 1 T3)
Exceeded → tighten SL
SAFETY: Extra naked shorts are closed when spread recovers to breakeven.
Each firefighter recommendation's threshold is shifted by a modifier ([-5, +5]) computed from market context:
| Signal | Confirms tested side | Contradicts tested side |
|---|---|---|
| Intraday bias | +3 (more urgent) | -2 (less urgent) |
| OI sentiment | +2 | -1 |
| OI momentum | +1 to +2 | -1 to -2 |
| Macro direction | +2 | -1 |
| Regime trending | +2 (moves follow through) | |
| Regime rangebound | -2 (mean reversion likely) | |
| VIX spike ≥2% | +2 (vol event, act fast) | |
| Delta drift ≥0.15 | +1 | |
| Trend duration >90min | +1 (sustained, not spike) | |
File: core/position_manager.py
Every tick, checked in this order: 1. TIME EXIT (3:00 PM) → close all legs, non-negotiable 2. RANGE BREACH (post-wings, spot past wing strike) → close all 3. HARD SL (rupee floor OR % SL hit) → close all 4. TRAILING STOP (below floor of peak) → close all 5. ADJUSTMENT ZONE → firefighter decides 6. NORMAL → continue monitoring
total_pnl = unrealized_pnl + realized_pnl unrealized_pnl: sum of (current_value - entry_value) for all open legs realized_pnl: booked P&L from closed/rolled legs net_premium: frozen at entry, never recalculated after rolls → Ensures SL % is based on original risk, not adjusted position Loss severity = |total_pnl| / (net_premium × SL_pct/100) → 0.0 = no loss, 1.0 = SL hit, 0.5 = halfway to SL
File: core/greeks.py
Black-Scholes model with: Risk-free rate: 7% (India 10Y) Dividend yield: 1.2% (Nifty) IV: back-solved from LTP via Newton-Raphson (20 iterations) Primary use: Delta computation for: - Entry delta recording (base delta for firefighter) - Position-level net delta monitoring - Delta drift threshold (≥0.25 triggers delta-tier roll) Delta drift = |current_net_delta - entry_base_delta|
File: agents/global_macro.py (1300 lines)
| Category | Instruments |
|---|---|
| Global Indices | S&P 500, Nasdaq, Nikkei 225, Hang Seng, Shanghai, DAX, FTSE, Stoxx 600, Kospi, Taiwan Weighted, ASX 200, Straits Times |
| US Futures | ES (S&P), NQ (Nasdaq), YM (Dow) |
| GIFT Nifty | SGX Nifty futures (via Kite, fallback Yahoo) |
| Commodities | Gold, Silver, Crude Oil (WTI + Brent), Copper, Natural Gas |
| Forex | DXY, USD/INR, EUR/USD, USD/JPY |
| Bonds/VIX | US 10Y, India 10Y, CBOE VIX |
| Participants | FII/DII net OI positioning + daily change |
Each instrument's change% is scored against per-instrument thresholds. Scores are weighted by category importance. Final macro score feeds into FMS computation at 20% weight.
Only instruments that traded today are scored (stale holiday data skipped). US futures always count (trade on holidays).
File: dashboard/api_server.py (~4800 lines). FastAPI backend.
| Endpoint | Purpose | Refresh |
|---|---|---|
GET /api/strategies/scores | All strategy scores, strikes, payoff, adjustments | 30s |
GET /api/market/overview | Spot, VIX, technicals, global macro grid | 30s |
GET /api/market/oi | OI analysis: PCR, max pain, strike-level buildup | 30s |
GET /api/positions | Active positions with P&L, firefighter status | 5s |
GET /api/market/technicals | RSI, MACD, BB, VWAP, SuperTrend, S/R | 30s |
GET /api/market/scoring-inputs | Raw scoring inputs for display | 30s |
GET /api/news | RSS feed with sentiment scores | 5min |
POST /api/engine/start | Start trading engine (paper/live) | - |
POST /api/trade/manual | Manual trade entry | - |
GET /api/trade/history | Historical trades from SQLite | - |
The /api/strategies/scores endpoint generates real strike proposals whenever the engine is warmed up and Kite is connected — not just during market hours. This allows viewing proposed strikes after market close.
If WebSocket data is stale, the API fetches fresh quotes via kite.quote() HTTP fallback. If contracts are missing for a strategy (e.g., deep OTM IC wings with no LTP), that strategy shows empty strikes rather than hardcoded fallbacks.
Client-side Black-Scholes computation in the dashboard.
Blue (Current): Theoretical P&L right now using Black-Scholes with calibrated per-strike IV. IV is back-solved from each leg's premium at current spot using Newton-Raphson. This ensures P&L ≈ ₹0 at current spot.
Teal dashed (At Expiry): Intrinsic-only payoff at expiration. The classic hockey-stick chart.
Outside market hours, premiums are stale (from last trading session). To prevent misleading P&L, DTE is adjusted to match when premiums were captured:
If market is closed: Find last trading day (walks back skipping weekends + NSE holidays) DTE += calendar_days_since_last_trading_day Example: Sunday viewing Monday expiry API DTE = 2 (calendar Sun→Tue) Last trading day = Friday → gap = 2 days Adjusted DTE = 4 (matches Friday close state) NSE 2026 holiday calendar is embedded for accurate gap calculation.
File: core/learning_engine.py
After each trade closes, the learning engine:
1. Stores full market snapshot at entry and exit 2. Records all adjustments made (what, when, why, result) 3. AI generates post-trade analysis (what went right/wrong) 4. Identifies patterns: - Strategy × VIX regime × time-of-day → win rate - Adjustment effectiveness by type and market context - Score threshold optimization 5. Parameter tuner suggests adjustments: - SL percentages, trail activation, roll thresholds - Based on accumulated trade data and outcomes
File: config/settings.py
| Parameter | Default | Description |
|---|---|---|
| SCORE_THRESHOLD | 55% | Minimum score for strategy recommendation |
| MAX_POSITIONS | 1 | Max concurrent positions |
| LOT_SIZE | 75 | Nifty lot size |
| MAX_LOTS_PER_LEG | 28 | Lot limit per leg (margin-based) |
| TIME_EXIT | 15:00 | Mandatory squareoff time |
| DELTA_DRIFT_THRESHOLD | 0.25 | Delta-tier roll trigger |
| VIX_SPIKE_THRESHOLD | 1.5% | Wing-buying VIX trigger |
| MAX_FIREFIGHTER_ROLLS | 3 | Max SL-tier adjustments |