📖 Nifty Trader — Engine Documentation

Detailed reference for strategy scoring, risk management, firefighting, and position lifecycle.

1. Strategy Scoring v7

File: core/strategy_scorer.py

1.1 FMS Computation

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

1.2 FMS → Base Score Curves

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.

1.3 VIX Multiplier

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

1.4 Hostility Multiplier

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).

1.5 IV Rank Modifier

IV Rank >60: premiums are rich → sellers get +5-10% boost. IV Rank <30: premiums are cheap → buyers get boost.

1.6 Final Score & Selection

final_score = base_score × VIX_mult × hostility_mult × IV_rank_mod
Threshold: 55% — below this, strategy not recommended
Selection: highest scoring strategy above threshold

2. Risk Engine

File: core/risk_engine.py

2.1 Stop Loss Philosophy

Core rule: We're renting premium for hours, not days. 30% max SL for sellers, 20% for buyers. SL only tightens — never widens beyond base.

2.2 Dynamic SL Adjustments

Starting from base (30% sellers, 20% buyers), SL tightens based on:

FactorSellersBuyers
VIX rising-3% (tighter)No change (momentum helps)
VIX fallingTrail 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 PMTrail earlier-3%

Final SL clamped to: sellers [20%, 30%], buyers [15%, 20%].

2.3 Trailing Stop

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.

2.4 Rupee Floor SL

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)

3. Firefighter — Adjustment Engine

File: core/firefighter.py (1350 lines)

Philosophy: NEVER let SL hit if an adjustment can save the position. Be proactive, not reactive. The firefighter acts BEFORE SL — in the adjustment zone (30%-100% of SL severity).

3.1 Trigger Flow

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

3.2 Severity Tiers

TierSeverity RangePhilosophy
TIER 130% of SLAdvisory. Mild trouble. Conservative action — roll if clear signal.
TIER 250% of SLActive. Must act. Lower thresholds — roll even without strong signal.
TIER 370% of SLEmergency. Last chance before SL. Aggressive — do whatever it takes.

3.3 Straddle / Strangle Adjustments

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

3.4 Iron Condor Adjustments

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)

3.5 Debit Spread (BCS/BPS) Adjustments

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.

3.6 Urgency Modifier

Each firefighter recommendation's threshold is shifted by a modifier ([-5, +5]) computed from market context:

SignalConfirms tested sideContradicts 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)

4. Position Manager

File: core/position_manager.py

4.1 Exit Priority Order

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

4.2 P&L Tracking

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

5. Greeks Calculator

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|

6. Global Macro Agent

File: agents/global_macro.py (1300 lines)

6.1 Data Sources (31 instruments)

CategoryInstruments
Global IndicesS&P 500, Nasdaq, Nikkei 225, Hang Seng, Shanghai, DAX, FTSE, Stoxx 600, Kospi, Taiwan Weighted, ASX 200, Straits Times
US FuturesES (S&P), NQ (Nasdaq), YM (Dow)
GIFT NiftySGX Nifty futures (via Kite, fallback Yahoo)
CommoditiesGold, Silver, Crude Oil (WTI + Brent), Copper, Natural Gas
ForexDXY, USD/INR, EUR/USD, USD/JPY
Bonds/VIXUS 10Y, India 10Y, CBOE VIX
ParticipantsFII/DII net OI positioning + daily change

6.2 Scoring

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).

7. Dashboard API

File: dashboard/api_server.py (~4800 lines). FastAPI backend.

7.1 Key Endpoints

EndpointPurposeRefresh
GET /api/strategies/scoresAll strategy scores, strikes, payoff, adjustments30s
GET /api/market/overviewSpot, VIX, technicals, global macro grid30s
GET /api/market/oiOI analysis: PCR, max pain, strike-level buildup30s
GET /api/positionsActive positions with P&L, firefighter status5s
GET /api/market/technicalsRSI, MACD, BB, VWAP, SuperTrend, S/R30s
GET /api/market/scoring-inputsRaw scoring inputs for display30s
GET /api/newsRSS feed with sentiment scores5min
POST /api/engine/startStart trading engine (paper/live)-
POST /api/trade/manualManual trade entry-
GET /api/trade/historyHistorical trades from SQLite-

7.2 Proposal Generation

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.

8. Payoff Diagram

Client-side Black-Scholes computation in the dashboard.

8.1 Two Lines

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.

8.2 Weekend/Holiday DTE

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.

9. Learning Engine

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

10. Configuration

File: config/settings.py

Key Parameters

ParameterDefaultDescription
SCORE_THRESHOLD55%Minimum score for strategy recommendation
MAX_POSITIONS1Max concurrent positions
LOT_SIZE75Nifty lot size
MAX_LOTS_PER_LEG28Lot limit per leg (margin-based)
TIME_EXIT15:00Mandatory squareoff time
DELTA_DRIFT_THRESHOLD0.25Delta-tier roll trigger
VIX_SPIKE_THRESHOLD1.5%Wing-buying VIX trigger
MAX_FIREFIGHTER_ROLLS3Max SL-tier adjustments