Options Income Strategies System

 

Executive Summary & Implementation Roadmap


Executive Overview

This comprehensive guide delivers a complete options income generation system for Indian markets, designed for ₹5-10 lakh capital. The framework prioritizes regime-adaptive strategy selectionrisk-first execution, and scalable implementation from manual trading to full automation.

Top 3 Recommended Starting Strategies:

  1. Short Iron Condor (Sideways/Low Vol) — High win-rate, defined risk, capital-efficient
  2. Credit Put Spreads (Neutral-Bullish) — Directional bias with controlled risk
  3. Short Strangles with Protective Wings (Sideways/Medium Vol) — Higher premium, managed tail risk

Capital Deployment Philosophy:

  • Start with 10-15% of capital per strategy (₹50k-₹1.5L per position)
  • Maximum 3 concurrent strategies initially
  • Reserve 40% capital for margin buffer and opportunity reserve
  • Per-trade risk cap: 1.5-2% of total capital (₹7.5k-₹20k max loss per trade)

Expected Timeline to Proficiency:

  • Weeks 1-2: Setup, backtesting infrastructure, paper trading
  • Months 2-3: Live pilot with micro-positions (₹25-50k notional)
  • Months 4-6: Scale to full position sizing with 3-4 active strategies
  • Month 6+: Portfolio diversification and automation layers

Strategy Universe: 12 Options Income Strategies

Regime Classification Matrix

StrategyBullBearSidewaysHigh VolLow VolCapital EfficiencyComplexity
1. Short Iron CondorHighMedium
2. Credit Put SpreadHighLow
3. Credit Call SpreadHighLow
4. Short Strangle + WingsMediumMedium
5. Ratio Put SpreadHighHigh
6. Calendar Spread (Put/Call)MediumHigh
7. Jade LizardHighMedium
8. Big LizardHighMedium
9. Diagonal SpreadMediumHigh
10. Iron ButterflyHighMedium
11. Covered Strangle (Cash-secured)LowLow
12. Butterfly Spread (Debit)Very HighMedium

Legend: ● Primary fit | ○ Secondary fit


STRATEGY CARD 1: Short Iron Condor

Overview

  • Name: Short Iron Condor (4-leg neutral strategy)
  • Regime Fit: Sideways/Rangebound markets, Low-to-Medium Volatility
  • Goal: Collect premium from time decay while price remains within defined range
  • Win Rate (Typical): 65-75% (hypothetical, structure-dependent)

Intuition

Sell OTM call spread + OTM put spread simultaneously. Profit from theta decay when underlying stays between short strikes. Defined max risk through long wings.

Instruments

  • Primary: NIFTY Index options (weekly expiry preferred for faster theta)
  • Alternative: BANKNIFTY (higher premiums, more volatile), Liquid stocks (RELIANCE, INFY, TCS)
  • Expiry: 7-14 DTE (Days To Expiry) for optimal theta/gamma balance
  • Lot Size Reference: NIFTY = 25 units/lot (verify current), BANKNIFTY = 15 units/lot (verify current)

Exact Setup

Strike Selection Rules:

Underlying = Spot price at entry
Short Put Strike = Spot - (1.5-2 × ATR_14) ≈ 16-20 delta
Long Put Strike = Short Put - ₹100-200 (NIFTY) [wing width]
Short Call Strike = Spot + (1.5-2 × ATR_14) ≈ 16-20 delta
Long Call Strike = Short Call + ₹100-200 (NIFTY)

Example (NIFTY @ 22,000):
- Sell 21,700 Put (0.18 delta)
- Buy 21,600 Put (0.12 delta)
- Sell 22,300 Call (0.18 delta)
- Buy 22,400 Call (0.12 delta)

Net Credit = ₹60/unit × 25 units = ₹1,500 per lot
Max Risk = (₹100 wing width - ₹60 credit) × 25 = ₹1,000 per lot

Position Sizing (for ₹5L capital):

  • Conservative: 1 lot (₹1,000 risk = 0.2% capital)
  • Moderate: 3-5 lots (₹3-5k risk = 0.6-1% capital)
  • Aggressive: 8-10 lots (₹8-10k risk = 1.6-2% capital)
  • Margin Requirement: ≈₹25-35k per lot (verify with broker SPAN+Exposure)

Entry Rules (Precise Triggers)

Primary Filter:

  1. IV Percentile Check: Enter when NIFTY VIX is in 20th-60th percentile of 90-day range (neither extreme high nor extreme low)
  2. Trend Filter: ADX < 25 (weak trend = good for range-bound strategy)
  3. Momentum Filter: Close price within ±0.75% of 20-day SMA
  4. Time Filter: Enter Monday-Wednesday (avoid Thursday/Friday for weekly expiries)

Technical Confirmation:

  • Bollinger Bands: Price in middle 40-60% of band width
  • RSI between 40-60 (no strong directional momentum)
  • No major earnings/events within expiry window

Execution Timing:

  • First 30 min after open: Avoid (high volatility)
  • 10:00-11:30 AM or 2:00-3:00 PM: Preferred (better pricing)

Exit Rules

Profit Targets:

  1. Primary: Close at 50-60% of max credit (₹30-36 per unit in example)
  2. Theta Decay Target: If 70% of time expired with profit >40% of max, close
  3. Early Exit: Volatility crush (VIX drops 15%+) → take 40% profit

Stop Losses:

  1. Hard Stop: Position reaches 200% of credit received (₹120 loss per unit = ₹3,000 per lot)
  2. Dynamic Stop: If underlying breaches short strike → close immediately
  3. Gamma Threshold: If delta magnitude exceeds 0.30 on either side → reduce/exit

Time-Based Rules:

  • Exit at 2 DTE regardless of P&L (avoid assignment/gamma risk)
  • If position profitable and <5 DTE, consider rolling to next week

Adjustment Rules:

  1. Threatened Side: If underlying approaches short strike (within 50% of width):
    • Roll threatened spread out and up/down (collect more credit)
    • Add protective long option on threatened side
  2. Inverted Position: If position shows loss >100% credit, close entire structure

Greeks Profile

At Entry (Target Values):

Delta: ±0.05 to 0.10 (near delta-neutral)
Gamma: -0.08 to -0.15 (negative, increases near short strikes)
Theta: +25 to +45 per day per lot (our profit engine)
Vega: -8 to -15 (profit from vol decrease, risk from vol spike)

Greeks Evolution:

  • Days 7-10: Theta acceleration (sweet spot)
  • Days 3-5: Gamma explosion (danger zone if ATM)
  • Days 0-2: Assignment risk, exit recommended

Portfolio Greeks Limits:

  • Net Portfolio Delta: ±0.15 per ₹1L capital
  • Net Portfolio Vega: <₹5,000 exposure per VIX point

Transaction Cost Model (India)

Per-Leg Costs (per lot):

Brokerage: ₹20-40 per executed order (flat fee model, verify with broker)
STT (Securities Transaction Tax): 0.0625% on sell side premium (options)
Exchange Charges: ≈0.05% of premium
GST: 18% on brokerage
SEBI Turnover Fee: ₹10 per ₹1 crore turnover
Stamp Duty: 0.003% on buy side (State-dependent)

Example Iron Condor (4 legs, entry + exit = 8 orders):
- Brokerage: 8 × ₹30 = ₹240
- STT (on 2 short legs, ₹1,500 credit): 0.0625% × ₹1,500 = ₹0.94 (minimal)
- Exchange + GST + Misc: ≈₹100
Total Round-Trip Cost: ≈₹350-400 per lot

Breakeven Impact: ₹400/25 units = ₹16 per unit (reduce net credit by ₹16)

Cost Optimization:

  • Use limit orders (avoid market impact)
  • Batch orders at favorable spreads
  • Consider zero-brokerage plans for high-frequency

Position Sizing Formula

# Conservative sizing
max_risk_per_trade = 0.015  # 1.5% of capital
capital = 500000  # ₹5L

max_loss_per_lot = (wing_width - net_credit) * lot_size
# Example: (100 - 60) × 25 = ₹1,000

lots = floor(capital × max_risk_per_trade / max_loss_per_lot)
# = floor(500000 × 0.015 / 1000) = 7 lots

# But check margin:
margin_per_lot = 30000  # Approx, verify
total_margin_needed = lots × margin_per_lot = 7 × 30000 = ₹210,000

# Ensure margin < 50% of capital:
if total_margin_needed > 0.5 × capital:
    lots = floor(0.5 × capital / margin_per_lot)  # = 8 lots max

Final Position Size: 5-7 lots for ₹5L capital (moderate risk)

Hedging & Safety Rules

Delta Hedge Trigger:

  • If net position delta exceeds ±0.15: Buy/sell underlying futures in 0.5 lot increments
  • Hedge cost: Factor in ₹100-200 slippage per adjustment

Vega Protection:

  • If VIX spikes >25% in single day → add long ATM straddle (10-15% of iron condor premium) as insurance
  • Alternatively: Close position and re-enter after vol stabilizes

Protective Long Options:

  • If one side threatened, add extra long wing:
    • Already short 22,300 Call, buy additional 22,500 Call for protection

Margin Spike Protection:

  • Maintain 40-50% capital as cash buffer
  • Set broker margin alerts at 70% usage
  • Pre-authorize intraday square-off if margin breached

Known Failure Modes

  1. Gap Risk (Overnight/Weekend):

    • Problem: Underlying gaps through short strike, immediate max loss
    • Mitigation: Reduce position size before event risk, avoid holding over long weekends, use tighter wings
  2. Volatility Explosion:

    • Problem: VIX spikes 40%+ (e.g., geo-political event), vega losses overwhelm theta gains
    • Mitigation: IV percentile filter, protective long options, exit early if VIX >75th percentile
  3. Whipsaw (Trend Reversal):

    • Problem: Price breaks out of range, hits one side, then reverses to other side
    • Mitigation: Widen initial range, use ADX filter, roll aggressively on first breach
  4. Assignment Risk (ITM Expiry):

    • Problem: Short options expire ITM → futures assignment, margin explosion
    • Mitigation: Exit by 2 DTE, never hold ITM options into expiry
  5. Liquidity Crunch:

    • Problem: Wide bid-ask on illiquid strikes → slippage exceeds profit
    • Mitigation: Trade only NIFTY/BANKNIFTY, avoid far OTM wings (>4 standard deviations)
  6. Serial Correlation (Bad Month):

    • Problem: 4-5 losing trades in row due to sustained trend/volatility
    • Mitigation: Max 3 active positions, pause after 2 consecutive losses >100% credit

Parameter Presets

Conservative (Recommended for First 3 Months):

Wing Width: ₹150-200 (NIFTY)
Delta Target: 0.12-0.15 per side
DTE Entry: 10-14 days
Profit Target: 60% max credit
Stop Loss: 150% of credit
Max Position Size: 3 lots for ₹5L capital
Entry IV Percentile: 25th-50th

Moderate (After 3 Months Profitability):

Wing Width: ₹100-150
Delta Target: 0.16-0.20 per side
DTE Entry: 7-10 days
Profit Target: 50% max credit
Stop Loss: 200% of credit
Max Position Size: 5-7 lots for ₹5L capital
Entry IV Percentile: 20th-60th

Aggressive (Experienced Traders Only):

Wing Width: ₹50-100
Delta Target: 0.20-0.25 per side
DTE Entry: 5-7 days
Profit Target: 40% max credit
Stop Loss: 250% of credit
Max Position Size: 8-10 lots for ₹5L capital
Entry IV Percentile: 15th-70th
Note: Requires active intraday monitoring

Backtest Recipe

Data Requirements:

  1. NIFTY Spot minute data (1-min or 5-min bars) — last 2-3 years
  2. NIFTY Options chain: strikes, bid/ask/last, IV, OI, volume — daily snapshots
  3. VIX daily close
  4. Interest rates (NSE published, typically 6-7% for India)
  5. Dividend schedule (minimal impact for index options)

Modeling Considerations:

# Pseudocode structure
def backtest_iron_condor(data, params):
    capital = 500000
    positions = []
    
    for date in trading_days:
        # Entry logic
        if should_enter(date, data, params):
            spot = data.loc[date, 'NIFTY_close']
            atr = calculate_atr(data, date, period=14)
            
            # Strike selection
            short_put = round_to_strike(spot - 1.8 * atr)
            long_put = short_put - params['wing_width']
            short_call = round_to_strike(spot + 1.8 * atr)
            long_call = short_call + params['wing_width']
            
            # Get premiums (use mid of bid-ask or last)
            credit = get_credit(date, short_put, long_put, short_call, long_call)
            
            # Position sizing
            max_loss = (params['wing_width'] - credit) * 25
            lots = min(
                floor(capital * params['max_risk_pct'] / max_loss),
                floor(capital * 0.5 / get_margin(date))
            )
            
            position = {
                'entry_date': date,
                'expiry': get_next_expiry(date, params['dte']),
                'strikes': [long_put, short_put, short_call, long_call],
                'credit': credit,
                'lots': lots,
                'max_loss': max_loss * lots
            }
            positions.append(position)
        
        # Exit logic (check all open positions)
        for pos in open_positions:
            pnl = calculate_pnl(pos, data.loc[date])
            dte = (pos['expiry'] - date).days
            
            # Exit rules
            if pnl > 0.5 * pos['credit'] * pos['lots']:  # Profit target
                close_position(pos, date, 'profit_target')
            elif pnl < -2.0 * pos['credit'] * pos['lots']:  # Stop loss
                close_position(pos, date, 'stop_loss')
            elif dte <= 2:  # Time exit
                close_position(pos, date, 'time_exit')
            elif breached_short_strike(pos, data.loc[date]):  # Dynamic stop
                close_position(pos, date, 'strike_breach')
    
    return calculate_metrics(positions)

def calculate_pnl(position, current_data):
    # MTM using Black-Scholes or mid-market prices
    current_values = []
    for strike, option_type in position['strikes']:
        current_val = get_option_price(current_data, strike, option_type)
        current_values.append(current_val)
    
    # P&L = initial credit - current debit
    current_debit = (current_values[1] - current_values[0] + 
                     current_values[2] - current_values[3])
    pnl = (position['credit'] - current_debit) * 25 * position['lots']
    return pnl

Slippage & Fill Model:

  • Use mid-price for entry/exit or assume 1-2 ticks slippage per leg
  • For bid-ask spread: Assume 0.5-1.0% of premium for liquid strikes
  • Reject fills if spread > 5% of mid price (illiquidity filter)

Synthetic P&L Calculation:

  • Use Black-Scholes for Greeks and mark-to-market
  • Implied volatility surface: Interpolate from available strikes
  • Handle early assignment: Check if ITM amount > remaining time value

Performance Metrics (Hypothetical Thresholds):

Target Metrics (Conservative Preset):
- Win Rate: >60%
- Avg Win / Avg Loss: >0.8
- Max Drawdown: <15% of capital
- Profit Factor: >1.5
- Expectancy: >0.5% per trade
- Sharpe Ratio: >1.0 (annualized)

If backtest shows metrics below these, adjust:
- Widen wings (reduce risk)
- Tighten entry filters (ADX, IV percentile)
- Increase profit target percentage

STRATEGY CARD 2: Credit Put Spread (Bull Put Spread)

Overview

  • Name: Credit Put Spread / Bull Put Spread
  • Regime Fit: Neutral-to-Bullish, Low-to-Medium Volatility
  • Goal: Collect premium betting price stays above short strike
  • Win Rate (Typical): 70-80% (hypothetical, structure-dependent)

Intuition

Sell OTM put, buy further OTM put for protection. Profit if underlying stays above short put strike. Simpler than iron condor, capital-efficient, directional bias.

Instruments

  • Primary: NIFTY/BANKNIFTY weekly options (7-14 DTE)
  • Alternative: Liquid large-caps (RELIANCE, HDFCBANK, TCS) for monthly expiry
  • Lot Size: NIFTY = 25, BANKNIFTY = 15

Exact Setup

Strike Selection:

Current Spot = S
Short Put Strike = S - (1.0-1.5 × ATR_14) ≈ 20-30 delta
Long Put Strike = Short Put - ₹100-150 (NIFTY)

Example (NIFTY @ 22,000):
- Sell 21,800 Put (0.25 delta)
- Buy 21,650 Put (0.15 delta)

Net Credit = ₹45/unit × 25 = ₹1,125 per lot
Max Risk = (₹150 width - ₹45 credit) × 25 = ₹2,625 per lot
Risk/Reward = 2.33:1

Position Sizing (₹5L capital):

  • Conservative: 2 lots (₹5,250 risk = 1.05%)
  • Moderate: 3-4 lots (₹7,875-10,500 risk = 1.6-2.1%)
  • Margin: ≈₹18-25k per lot

Entry Rules

Primary Filters:

  1. Bullish Bias: NIFTY above 20-SMA AND RSI > 50
  2. Vol Environment: VIX < 60th percentile (not too high)
  3. Support Level: Short put strike near recent support or psychological level
  4. Momentum: 5-day return > 0 (recent uptrend)

Timing:

  • Enter Monday-Wednesday for weekly expiry
  • Avoid day-before or day-of major events (Fed, RBI, election results)

Exit Rules

Profit Target: 50-70% of max credit (₹22-32 per unit) Stop Loss: 200-250% of credit (₹90-112 per unit loss) Time Exit: Close at 2 DTE Dynamic: If short put breached → exit immediately

Greeks Profile

Delta: +0.15 to +0.25 (bullish exposure)
Gamma: -0.05 to -0.10 (short gamma)
Theta: +15 to +30 per day (time decay profit)
Vega: -5 to -10 (short volatility)

Hedging: If NIFTY falls 2%+ in session, consider buying ATM put as protection (costs ₹800-1,200, limits downside)

Failure Modes

  1. Sharp Selloff: Gap down through support → max loss
    • Mitigation: Wider spreads, reduce size before events
  2. Volatility Spike: VIX jumps 30%+ → mark-to-market loss
    • Mitigation: Exit if VIX enters 90th percentile

Parameter Presets

Conservative:

  • Width: ₹150-200, Delta: 0.20-0.25, DTE: 10-14, Size: 2 lots per ₹5L

Moderate:

  • Width: ₹100-150, Delta: 0.25-0.30, DTE: 7-10, Size: 3-4 lots per ₹5L

Aggressive:

  • Width: ₹50-100, Delta: 0.30-0.35, DTE: 5-7, Size: 5-6 lots per ₹5L

Backtest Recipe

Similar to Iron Condor but:

  • Only model put spread (2 legs)
  • Check for bullish filter in entry (price > SMA, RSI > 50)
  • Assignment simulation: If short put ITM at expiry, assume futures assignment at strike price

STRATEGY CARD 3: Short Strangle with Protective Wings

Overview

  • Name: Short Strangle with Protective Wings (Modified Iron Fly variant)
  • Regime Fit: Sideways, Medium-to-High Volatility (collect large premium)
  • Goal: Higher credit than iron condor, tail-risk protected
  • Win Rate (Typical): 60-70%

Intuition

Sell OTM put and OTM call (strangle) to collect high premium in volatile markets. Add far OTM wings (long put/call) to cap black-swan risk. Wider breakevens than iron condor.

Instruments

  • Primary: NIFTY/BANKNIFTY weekly (7-14 DTE)
  • High Vol Events: Earnings weeks, event-driven volatility

Exact Setup

Spot = 22,000
Short Put = 21,600 (0.25 delta)
Short Call = 22,400 (0.25 delta)
Long Put = 21,200 (0.08 delta) — 400 points away
Long Call = 22,800 (0.08 delta)

Credit (Short Strangle): ₹80/unit × 25 = ₹2,000
Cost (Long Wings): ₹15/unit × 25 = ₹375
Net Credit: ₹1,625 per lot

Max Risk (if wings hit): (400 - 65) × 25 = ₹8,375 per lot

Position Sizing (₹5L):

  • Conservative: 1 lot (₹8,375 = 1.7% risk)
  • Moderate: 2 lots (3.4% risk — at upper limit)

Entry Rules

  1. IV Rank: 40th-80th percentile (elevated vol, fat premiums)
  2. Range Expectation: Expect consolidation after volatility spike
  3. Technical: Price near middle of recent 30-day range
  4. Event Avoidance: No major announcements within 7 days

Exit Rules

Profit: 40-50% of net credit Stop Loss: If underlying reaches either short strike OR loss exceeds 2× credit Time: Exit by 3 DTE (gamma/assignment risk) Volatility: If VIX crashes below 25th percentile, take profits early (vol premium gone)

Greeks Profile

Delta: -0.05 to +0.05 (near neutral)
Gamma: -0.20 to -0.35 (high negative gamma, dangerous near expiry)
Theta: +50 to +80 per day (very high time decay)
Vega: -20 to -35 (high short vega, vulnerable to vol spikes)

Hedging:

  • If one side threatened, close that spread or roll to next expiry
  • Can dynamically add more long wings if vol explodes further

Failure Modes

  1. Sustained Breakout: Trend emerges, price breaches range → hit long wing
  2. Gamma Risk: If held to <3 DTE while ATM → uncontrollable delta swings
  3. Whipsaw: Breach one side, adjust, then breach other side

Mitigation: Use wider wings, never hold into last 2 days, aggressive rolling

Backtest Notes

  • Model both strangle + wing costs
  • Simulate wing payout if price exceeds short strike + wing distance
  • Use implied volatility surface for realistic pricing (vol skew)

Manual Implementation Guide (Consolidated for All Strategies)

Pre-Trade Checklist

  1. Market Context Check:

    •  Check NIFTY trend (above/below 20-SMA, 50-SMA)
    •  Check VIX level and percentile (use 90-day rolling window)
    •  Note ADX reading (trend strength)
    •  Review upcoming events calendar (expiry, F&O rollover, policy meetings, earnings)
  2. Strategy Selection:

    •  Match current regime to strategy (use Regime Matrix)
    •  Confirm IV environment suitable for chosen strategy
    •  Verify sufficient liquidity in target strikes (OI > 1000 lots, volume > 500 lots)
  3. Position Sizing Calculation:

    Step 1: Calculate max loss per lot for chosen strategy
    Step 2: Risk per trade = Capital × 0.015 (1.5%)
    Step 3: Initial lots = floor(Risk per trade / Max loss per lot)
    Step 4: Margin check = Lots × Margin per lot < 50% of capital
    Step 5: Final lots = min(Step 3, Step 4)
    
  4. Strike Selection:

    •  Calculate ATR(14) from daily data
    •  Identify target delta strikes using option chain
    •  Verify bid-ask spread < 5% of mid-price
    •  Note breakeven points and probability of profit (from option chain)

Execution Checklist (Brokerage Platform)

Using Zerodha Kite / Upstox / Other Platforms:

  1. Order Entry (Example: Iron Condor on NIFTY):

    Step 1: Open Options Chain for NIFTY current week expiry
    Step 2: Identify 4 strikes per Strategy Card
    
    Leg 1: SELL 21,700 PE (Put) — Limit Order
          - Qty: 25 (1 lot)
          - Price: ₹32 (or better)
    
    Leg 2: BUY 21,600 PE — Limit Order
          - Qty: 25
          - Price: ₹20 (or better)
    
    Leg 3: SELL 22,300 CE (Call) — Limit Order
          - Qty: 25
          - Price: ₹30 (or better)
    
    Leg 4: BUY 22,400 CE — Limit Order
          - Qty: 25
          - Price: ₹18 (or better)
    
    Target Net Credit: ₹24 per unit (₹600 total)
    
  2. Order Type Strategy:

    • Use Limit Orders: Avoid market orders (protect against wide spreads)
    • Leg Sequencing:
      • Enter short legs first (collect credit)
      • Then immediately enter long legs (protection)
      • Or use "Basket Order" / "Strategy Builder" feature if available
    • Price Adjustment: If no fill in 2 minutes, adjust limit by ₹1-2
  3. Confirmation:

    •  All 4 legs filled
    •  Net credit received ≥ target credit (after slippage)
    •  Position shows correctly in "Positions" tab
    •  Margin blocked = expected amount

Monitoring & Management (Intraday)

Dashboard Metrics (Track in Spreadsheet or App):

TimeNIFTY SpotP&L (₹)DeltaDTEAction
10:00 AM22,050+150+0.029Hold
12:00 PM22,120+200+0.059Hold
2:30 PM22,280-50+0.129Monitor (approaching call)
3:15 PM22,310-180+0.189Consider adjustment

Greeks Monitoring (Manual Calculation or Broker Dashboard):

  • Check Delta: Should remain < 0.15 for neutral strategies
    • If > 0.20: Consider delta hedge or close position
  • Check Theta Decay: Expect ₹25-45 daily decay per lot (for iron condor)
  • Check Vega Exposure: If VIX spikes >20%, recalculate position value

Adjustment Triggers (Intraday Alerts): (continued)

  1. Price Alert: Set alerts at short strike ±25%

    • Example: Short call at 22,300 → Alert at 22,225
    • Short put at 21,700 → Alert at 21,775
  2. P&L Alert: Set alerts at:

    • +50% of max profit → Consider closing
    • -150% of credit received → Prepare to exit
  3. VIX Alert: If VIX jumps >15% in single session → review all positions

Manual Adjustment Procedures:

Scenario A: Price Threatens Call Side (Moving Up)

Current: NIFTY @ 22,250 (approaching 22,300 short call)
Action Options:
1. Roll Call Spread Up:
   - Close 22,300/22,400 call spread
   - Open 22,400/22,500 call spread
   - Collect additional credit or pay small debit
   
2. Add Protective Long:
   - Buy 22,350 CE (between current price and short strike)
   - Cost: ₹400-600 per lot
   
3. Close Entire Position:
   - If profit target not met but risk escalating
   - Accept small loss to preserve capital

Execution: Place all closing orders as Limit orders first, then opening orders

Scenario B: Volatility Spike (VIX +25%)

Action:
1. Check mark-to-market P&L (will show paper loss)
2. If position still within range, consider holding (vol will revert)
3. If loss exceeds 200% credit, close position
4. Alternative: Close short strikes, keep long wings (convert to long strangle)

End-of-Day Operational Checklist

Daily Close Routine (3:20-3:30 PM):

  1. Record Keeping:

    Date: [DD-MM-YYYY]
    Strategy: [Iron Condor / Put Spread / etc.]
    Entry Date: [DD-MM-YYYY]
    DTE Remaining: [X days]
    
    Strikes: [21,600/21,700/22,300/22,400]
    Entry Credit: ₹60/unit
    Current MTM: ₹45/unit (₹375 profit per lot)
    
    Greeks:
    - Delta: +0.03
    - Theta: +28/day
    - Vega: -12
    
    NIFTY Close: 22,080
    VIX Close: 14.2
    
    Decision: Hold (profit = 25% of target, 9 DTE remaining)
    
  2. Risk Assessment:

    •  Calculate overnight exposure: Total position value × sensitivity to 2% gap
    •  Check margin utilization: Should be < 60% of available
    •  Review next day's calendar: Any major events?
    •  Set alerts for next day (price, P&L thresholds)
  3. Position Health Check:

    •  All positions within acceptable delta range?
    •  Any position showing loss > 100% credit?
    •  DTE < 3 for any position? (Flag for exit)
    •  Aggregate portfolio delta within ±0.15 per ₹1L capital?
  4. Transaction Log Update:

    Trade_ID, Date, Strategy, Action, Strikes, Lots, Credit_Debit, Fees, Net_PnL, Notes
    IC_001, 01-11-2024, Iron Condor, Entry, 21600/21700/22300/22400, 3, 1800, -400, 0, "Entry clean"
    IC_001, 05-11-2024, Iron Condor, Hold, -, -, -, -, +900, "Day 4, profit 50%"
    
  5. Weekly Review (Every Friday):

    •  Calculate weekly P&L across all strategies
    •  Review win rate: # wins / # closed trades
    •  Compare actual vs expected theta decay
    •  Adjust position sizing if consecutive losses (pause or reduce)
    •  Update strategy performance dashboard

Position Sizing Examples with Real Numbers

Example 1: Conservative Trader with ₹5L Capital

Capital: ₹500,000
Risk per trade: 1.5%
Max risk per trade: ₹7,500

Strategy: Iron Condor (NIFTY)
Max loss per lot: ₹1,000
Max lots by risk: 7,500 / 1,000 = 7 lots

Margin per lot: ₹30,000
Max lots by margin (50% rule): 250,000 / 30,000 = 8 lots

Final position size: 7 lots (risk-constrained)
Total margin: ₹210,000 (42% utilization — safe)

Credit received: 7 × ₹1,500 = ₹10,500
Max potential loss: 7 × ₹1,000 = ₹7,000
R:R = 1.5:1

Example 2: Moderate Trader with ₹10L Capital

Capital: ₹1,000,000
Risk per trade: 2%
Max risk per trade: ₹20,000

Strategy 1: Iron Condor (NIFTY) — 15 lots
- Risk: 15 × ₹1,000 = ₹15,000
- Margin: 15 × ₹30,000 = ₹450,000

Strategy 2: Credit Put Spread (BANKNIFTY) — 4 lots
- Risk: 4 × ₹2,600 = ₹10,400
- Margin: 4 × ₹40,000 = ₹160,000

Total margin: ₹610,000 (61% utilization)
Total risk: ₹25,400 (2.54% — slightly over but diversified)

Reserve: ₹390,000 for adjustments/opportunities

Example 3: Risk Budget Allocation Across Multiple Strategies

Capital: ₹500,000
Total risk budget: 5% = ₹25,000 (across all positions)

Allocation:
- Strategy 1 (Iron Condor): 2% risk = ₹10,000 → 10 lots
- Strategy 2 (Put Spread): 1.5% risk = ₹7,500 → 3 lots  
- Strategy 3 (Strangle + Wings): 1.5% risk = ₹7,500 → 1 lot

Total deployed: ₹25,000 risk
Margin used: ≈₹350,000 (70% — acceptable for diversified portfolio)

Quant / Algo Implementation Blueprint

System Architecture Overview

┌─────────────────────────────────────────────────────────┐
│                   Data Layer                             │
│  - Historical OHLCV (underlying)                        │
│  - Options chain snapshots (daily/intraday)             │
│  - Greeks & IV surface                                   │
│  - VIX, interest rates, dividends                       │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│              Signal Generation Engine                     │
│  - Regime detection (trend/vol classification)          │
│  - Entry filters (IV percentile, ADX, RSI)             │
│  - Strike selection algorithm                            │
│  - Position sizing calculator                            │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│              Backtest Engine                             │
│  - Vectorized or event-driven simulation                │
│  - Greeks calculation (Black-Scholes)                   │
│  - Transaction cost model                                │
│  - Walk-forward validation                               │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│            Live Execution Layer                          │
│  - Order management system (OMS)                        │
│  - Broker API integration (Kite/Upstox)                │
│  - Position tracking & Greeks monitor                   │
│  - Risk kill-switch logic                               │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│          Monitoring & Alerting                           │
│  - Real-time P&L dashboard                              │
│  - Greeks aggregation                                    │
│  - Margin utilization tracker                            │
│  - Email/SMS alerts                                      │
└─────────────────────────────────────────────────────────┘

Data Requirements & Schema

1. Underlying Data (NIFTY/BANKNIFTY)

# Daily OHLCV
columns = ['date', 'open', 'high', 'low', 'close', 'volume']
# Source: NSE historical data API, vendor (e.g., TrueData, Upstox)

# Intraday (for live trading)
columns = ['timestamp', 'open', 'high', 'low', 'close', 'volume']
# Frequency: 1-min or 5-min bars

2. Options Chain Data

# Daily snapshot (EOD) for backtesting
columns = [
    'date', 'underlying', 'expiry_date', 
    'strike', 'option_type',  # 'CE' or 'PE'
    'ltp', 'bid', 'ask', 'volume', 'oi',
    'iv',  # Implied volatility
    'delta', 'gamma', 'theta', 'vega'  # Greeks (if available, else calculate)
]

# Live option chain (for trading)
# Fetch via broker API: kite.quote() or similar
# Frequency: Real-time or every 30-60 seconds

3. VIX Data

# India VIX (volatility index)
columns = ['date', 'vix_close']
# Source: NSE website, vendor APIs

4. Risk-Free Rate & Dividends

# India: Use NSE T-Bill rates or RBI repo rate
# Typical: 6-7% annually
# Dividends: Minimal impact for index options, fetch for stock options

Signal Generation Logic (Pseudocode)

Module 1: Regime Detection

import pandas as pd
import numpy as np
from ta.trend import ADXIndicator, SMAIndicator
from ta.momentum import RSIIndicator

def detect_regime(df, vix_df):
    """
    Classify market regime for strategy selection
    
    Returns: {'regime': 'sideways'|'bull'|'bear', 
              'volatility': 'low'|'medium'|'high'}
    """
    # Trend detection
    df['sma_20'] = SMAIndicator(df['close'], window=20).sma_indicator()
    df['sma_50'] = SMAIndicator(df['close'], window=50).sma_indicator()
    adx = ADXIndicator(df['high'], df['low'], df['close'], window=14)
    df['adx'] = adx.adx()
    
    current_price = df['close'].iloc[-1]
    sma_20 = df['sma_20'].iloc[-1]
    sma_50 = df['sma_50'].iloc[-1]
    adx_val = df['adx'].iloc[-1]
    
    # Trend classification
    if adx_val < 25:  # Weak trend
        regime = 'sideways'
    elif current_price > sma_20 > sma_50:
        regime = 'bull'
    elif current_price < sma_20 < sma_50:
        regime = 'bear'
    else:
        regime = 'sideways'
    
    # Volatility classification
    vix_percentile = calculate_percentile(vix_df['vix_close'], window=90)
    if vix_percentile < 33:
        volatility = 'low'
    elif vix_percentile < 66:
        volatility = 'medium'
    else:
        volatility = 'high'
    
    return {'regime': regime, 'volatility': volatility, 'vix_percentile': vix_percentile}

def calculate_percentile(series, window=90):
    """Calculate current value percentile vs rolling window"""
    recent = series.tail(window)
    current = series.iloc[-1]
    percentile = (recent < current).sum() / len(recent) * 100
    return percentile

Module 2: Entry Signal Generator (Iron Condor Example)

def generate_iron_condor_signal(df, vix_df, option_chain, params):
    """
    Determine if conditions met for iron condor entry
    
    params: {
        'dte_target': 10,
        'vix_percentile_min': 20,
        'vix_percentile_max': 60,
        'adx_max': 25,
        'rsi_min': 40,
        'rsi_max': 60,
        'wing_width': 100,
        'delta_target': 0.18
    }
    """
    regime = detect_regime(df, vix_df)
    
    # Filter 1: Regime check
    if regime['regime'] != 'sideways':
        return None
    
    # Filter 2: Volatility check
    if not (params['vix_percentile_min'] <= regime['vix_percentile'] <= params['vix_percentile_max']):
        return None
    
    # Filter 3: ADX check
    adx_val = ADXIndicator(df['high'], df['low'], df['close'], window=14).adx().iloc[-1]
    if adx_val > params['adx_max']:
        return None
    
    # Filter 4: RSI check
    rsi_val = RSIIndicator(df['close'], window=14).rsi().iloc[-1]
    if not (params['rsi_min'] <= rsi_val <= params['rsi_max']):
        return None
    
    # Filter 5: Day of week (avoid Thursday/Friday for weekly)
    current_day = df.index[-1].dayofweek  # 0=Monday, 4=Friday
    if current_day >= 3:  # Thursday or Friday
        return None
    
    # Passed all filters - generate strike selection
    spot_price = df['close'].iloc[-1]
    atr_14 = calculate_atr(df, period=14)
    
    # Find strikes in option chain with target delta
    expiry = get_next_expiry(df.index[-1], params['dte_target'])
    strikes = select_iron_condor_strikes(
        option_chain, spot_price, atr_14, expiry, 
        params['delta_target'], params['wing_width']
    )
    
    if strikes is None:
        return None
    
    return {
        'strategy': 'iron_condor',
        'entry_date': df.index[-1],
        'expiry': expiry,
        'spot_price': spot_price,
        'strikes': strikes,  # {'short_put': 21700, 'long_put': 21600, ...}
        'regime': regime
    }

def calculate_atr(df, period=14):
    """Calculate Average True Range"""
    high_low = df['high'] - df['low']
    high_close = np.abs(df['high'] - df['close'].shift())
    low_close = np.abs(df['low'] - df['close'].shift())
    
    ranges = pd.concat([high_low, high_close, low_close], axis=1)
    true_range = ranges.max(axis=1)
    atr = true_range.rolling(window=period).mean().iloc[-1]
    
    return atr

def select_iron_condor_strikes(option_chain, spot, atr, expiry, delta_target, wing_width):
    """
    Select strikes for iron condor based on delta and wing width
    """
    # Filter to target expiry
    chain = option_chain[option_chain['expiry_date'] == expiry]
    
    if chain.empty:
        return None
    
    # Short put: spot - 1.8*ATR, target delta ≈ delta_target
    target_put_strike = round_to_strike(spot - 1.8 * atr)
    puts = chain[chain['option_type'] == 'PE']
    short_put_row = puts.iloc[(puts['strike'] - target_put_strike).abs().argsort()[:1]]
    
    if short_put_row.empty or abs(short_put_row['delta'].values[0]) < delta_target * 0.8:
        return None
    
    short_put_strike = short_put_row['strike'].values[0]
    long_put_strike = short_put_strike - wing_width
    
    # Short call: spot + 1.8*ATR
    target_call_strike = round_to_strike(spot + 1.8 * atr)
    calls = chain[chain['option_type'] == 'CE']
    short_call_row = calls.iloc[(calls['strike'] - target_call_strike).abs().argsort()[:1]]
    
    if short_call_row.empty or abs(short_call_row['delta'].values[0]) < delta_target * 0.8:
        return None
    
    short_call_strike = short_call_row['strike'].values[0]
    long_call_strike = short_call_strike + wing_width
    
    # Get premiums
    strikes_dict = {
        'short_put': short_put_strike,
        'long_put': long_put_strike,
        'short_call': short_call_strike,
        'long_call': long_call_strike
    }
    
    # Add premium values
    for key, strike in strikes_dict.items():
        opt_type = 'PE' if 'put' in key else 'CE'
        row = chain[(chain['strike'] == strike) & (chain['option_type'] == opt_type)]
        if not row.empty:
            strikes_dict[f'{key}_premium'] = row['ltp'].values[0]
    
    # Calculate credit
    net_credit = (strikes_dict.get('short_put_premium', 0) - 
                  strikes_dict.get('long_put_premium', 0) +
                  strikes_dict.get('short_call_premium', 0) - 
                  strikes_dict.get('long_call_premium', 0))
    
    strikes_dict['net_credit'] = net_credit
    strikes_dict['max_loss'] = wing_width - net_credit
    
    return strikes_dict

def round_to_strike(price, strike_interval=50):
    """Round price to nearest valid strike"""
    return round(price / strike_interval) * strike_interval

def get_next_expiry(current_date, dte_target):
    """
    Get next expiry date matching DTE target
    For weekly: Thursdays
    """
    # Simplified: assuming weekly Thursday expiries
    days_until_thursday = (3 - current_date.dayofweek) % 7
    next_expiry = current_date + pd.Timedelta(days=days_until_thursday)
    
    # Adjust to match dte_target
    while (next_expiry - current_date).days < dte_target - 3:
        next_expiry += pd.Timedelta(days=7)
    
    return next_expiry

Backtest Engine (Event-Driven)

class OptionsBacktester:
    def __init__(self, underlying_data, option_chain, vix_data, params):
        self.underlying = underlying_data
        self.option_chain = option_chain
        self.vix = vix_data
        self.params = params
        
        self.capital = params['initial_capital']
        self.positions = []
        self.closed_positions = []
        self.equity_curve = []
        
    def run(self):
        """Main backtest loop"""
        for date in self.underlying.index:
            # Check for new entry signals
            if self.should_check_entry(date):
                signal = generate_iron_condor_signal(
                    self.underlying.loc[:date],
                    self.vix.loc[:date],
                    self.option_chain[self.option_chain['date'] == date],
                    self.params
                )
                
                if signal:
                    position = self.enter_position(signal, date)
                    if position:
                        self.positions.append(position)
            
            # Manage existing positions
            self.manage_positions(date)
            
            # Record equity
            self.record_equity(date)
        
        return self.generate_results()
    
    def enter_position(self, signal, date):
        """Execute entry with position sizing"""
        # Calculate position size
        max_loss_per_lot = signal['strikes']['max_loss'] * 25  # NIFTY lot size
        risk_per_trade = self.capital * self.params['risk_per_trade']
        lots = int(risk_per_trade / max_loss_per_lot)
        
        # Margin check
        margin_per_lot = self.estimate_margin(signal)
        total_margin = lots * margin_per_lot
        if total_margin > self.capital * 0.5:
            lots = int(self.capital * 0.5 / margin_per_lot)
        
        if lots < 1:
            return None
        
        # Apply transaction costs
        entry_cost = self.calculate_transaction_cost(signal, lots, 'entry')
        
        position = {
            'id': len(self.positions) + 1,
            'entry_date': date,
            'expiry': signal['expiry'],
            'strikes': signal['strikes'],
            'lots': lots,
            'entry_credit': signal['strikes']['net_credit'] * lots * 25,
            'max_loss': max_loss_per_lot * lots,
            'entry_cost': entry_cost,
            'status': 'open'
        }
        
        return position
    
    def manage_positions(self, date):
        """Check exit rules for all open positions"""
        for position in self.positions:
            if position['status'] != 'open':
                continue
            
            # Calculate current P&L
            current_pnl = self.calculate_position_pnl(position, date)
            dte = (position['expiry'] - date).days
            
            # Exit rules
            exit_reason = None
            
            # Rule 1: Profit target
            if current_pnl >= position['entry_credit'] * self.params['profit_target_pct']:
                exit_reason = 'profit_target'
            
            # Rule 2: Stop loss
            elif current_pnl <= -position['entry_credit'] * self.params['stop_loss_pct']:
                exit_reason = 'stop_loss'
            
            # Rule 3: Time exit
            elif dte <= 2:
                exit_reason = 'time_exit'
            
            # Rule 4: Strike breach
            elif self.check_strike_breach(position, date):
                exit_reason = 'strike_breach'
            
            if exit_reason:
                self.exit_position(position, date, exit_reason, current_pnl)
    
    def calculate_position_pnl(self, position, date):
        """Calculate MTM P&L using option prices"""
        # Get current option prices
        chain = self.option_chain[
            (self.option_chain['date'] == date) &
            (self.option_chain['expiry_date'] == position['expiry'])
        ]
        
        if chain.empty:
            # Use Black-Scholes if no market data
            return self.calculate_bs_pnl(position, date)
        
        strikes = position['strikes']
        current_value = 0
        
        # Short put value (we owe)
        sp = chain[(chain['strike'] == strikes['short_put']) & (chain['option_type'] == 'PE')]
        if not sp.empty:
            current_value -= sp['ltp'].values[0]
        
        # Long put value (we own)
        lp = chain[(chain['strike'] == strikes['long_put']) & (chain['option_type'] == 'PE')]
        if not lp.empty:
            current_value += lp['ltp'].values[0]
        
        # Short call value (we owe)
        sc = chain[(chain['strike'] == strikes['short_call']) & (chain['option_type'] == 'CE')]
        if not sc.empty:
            current_value -= sc['ltp'].values[0]
        
        # Long call value (we own)
        lc = chain[(chain['strike'] == strikes['long_call']) & (chain['option_type'] == 'CE')]
        if not lc.empty:
            current_value += lc['ltp'].values[0]
        
        # P&L = entry credit - current debit
        pnl = (strikes['net_credit'] - current_value) * position['lots'] * 25
        
        return pnl
    
    def calculate_bs_pnl(self, position, date):
        """Fallback: Calculate P&L using Black-Scholes"""
        # Implement Black-Scholes pricing
        # This requires: spot, strike, time to expiry, IV, risk-free rate
        # ... (implementation details)
        pass
    
    def check_strike_breach(self, position, date):
        """Check if underlying breached short strikes"""
        spot = self.underlying.loc[date, 'close']
        strikes = position['strikes']
        
        if spot <= strikes['short_put'] or spot >= strikes['short_call']:
            return True
        return False
    
    def exit_position(self, position, date, reason, pnl):
        """Close position and record"""
        exit_cost = self.calculate_transaction_cost(position, position['lots'], 'exit')
        net_pnl = pnl - position['entry_cost'] - exit_cost
        
        position['status'] = 'closed'
        position['exit_date'] = date
        position['exit_reason'] = reason
        position['gross_pnl'] = pnl
        position['net_pnl'] = net_pnl
        position['exit_cost'] = exit_cost
        
        self.closed_positions.append(position)
        self.capital += net_pnl
    
    def calculate_transaction_cost(self, position, lots, action):
        """Calculate brokerage, STT, exchange fees, GST"""
        # 4 legs for iron condor
        num_orders = 4
        brokerage = num_orders * self.params['brokerage_per_order']
        
        # STT on sell side (short put + short call)
        premium_sell = (position['strikes'].get('short_put_premium', 30) + 
                       position['strikes'].get('short_call_premium', 30))
        stt = premium_sell * lots * 25 * 0.0625 / 100
        
        # Exchange + GST
        misc = 100  # Simplified
        
        total_cost = brokerage + stt + misc
        return total_cost
    
    def estimate_margin(self, signal):
        """Estimate SPAN + Exposure margin"""
        # Simplified: Typically 30-40% of wing width
        wing_width = signal['strikes']['short_put'] - signal['strikes']['long_put']
        margin_per_lot = wing_width * 25 * 0.35
        return margin_per_lot
    
    def record_equity(self, date):
        """Record daily equity curve"""
        mtm_pnl = sum([self.calculate_position_pnl(p, date) for p in self.positions if p['status'] == 'open'])
        total_equity = self.capital + mtm_pnl
        
        self.equity_curve.append({
            'date': date,
            'equity': total_equity,
            'cash': self.capital,
            'open_positions': len([p for p in self.positions if p['status'] == 'open'])
        })
    
    def generate_results(self):
        """Calculate performance metrics"""
        results = pd.DataFrame(self.closed_positions)
        equity = pd.DataFrame(self.equity_curve)
        
        if results.empty:
            return None
        
        total_trades = len(results)
        winning_trades = len(results[results['net_pnl'] > 0])
        win_rate = winning_trades / total_trades * 100
        
        avg_win = results[results['net_pnl'] > 0]['net_pnl'].mean()
        avg_loss = results[results['net_pnl'] < 0]['net_pnl'].mean()
        
        total_pnl = results['net_pnl'].sum()
        max_drawdown = (equity['equity'].cummax() - equity['equity']).max()
        
        # Sharpe ratio (annualized)
        equity['returns'] = equity['equity'].pct_change()
        sharpe = equity['returns'].mean() / equity['returns'].std() * np.sqrt(252)
        
        metrics = {
            'total_trades': total_trades,
            'win_rate': win_rate,
            'avg_win': avg_win,
            'avg_loss': avg_loss,
            'profit_factor': abs(avg_win / avg_loss) if avg_loss != 0 else np.inf,
            'total_pnl': total_pnl,
            'max_drawdown': max_drawdown,
            'sharpe_ratio': sharpe,
            'final_capital': self.capital
        }
        
        return {'metrics': metrics, 'trades': results, 'equity': equity}

Execution Layer (Broker API Integration)

Zerodha Kite Connect Example:

from kiteconnect import KiteConnect
import time

class LiveExecutor:
    def __init__(self, api_key, access_token, capital):
        self.kite = KiteConnect(api_key=api_key)
        self.kite.set_access_token(access_token)
        self.capital = capital
        self.positions = []
        
    def execute_iron_condor(self, signal, lots):
        """
        Execute 4-leg iron condor using basket orders
        """
        strikes = signal['strikes']
        symbol = signal['underlying']  # 'NIFTY' or 'BANKNIFTY'
        expiry = signal['expiry'].strftime('%y%b%d').upper()  # 24DEC28
        
        # Build trading symbols
        short_put_symbol = f"{symbol}{expiry}{strikes['short_put']}PE"
        long_put_symbol = f"{symbol}{expiry}{strikes['long_put']}PE"
        short_call_symbol = f"{symbol}{expiry}{strikes['short_call']}CE"
        long_call_symbol = f"{symbol}{expiry}{strikes['long_call']}CE"
        
        # Get instrument tokens (required by Kite)
        instruments = self.kite.instruments("NFO")
        token_map = {inst['tradingsymbol']: inst['instrument_token'] for inst in instruments}
        
        # Place orders
        orders = []
        
        try:
            # Leg 1: Sell Put
            order_id_1 = self.place_limit_order(
                symbol=short_put_symbol,
                transaction_type='SELL',
                quantity=lots * 25,
                price=strikes['short_put_premium']
            )
```python
            orders.append(('short_put', order_id_1))
            
            # Leg 2: Buy Put
            order_id_2 = self.place_limit_order(
                symbol=long_put_symbol,
                transaction_type='BUY',
                quantity=lots * 25,
                price=strikes['long_put_premium']
            )
            orders.append(('long_put', order_id_2))
            
            # Leg 3: Sell Call
            order_id_3 = self.place_limit_order(
                symbol=short_call_symbol,
                transaction_type='SELL',
                quantity=lots * 25,
                price=strikes['short_call_premium']
            )
            orders.append(('short_call', order_id_3))
            
            # Leg 4: Buy Call
            order_id_4 = self.place_limit_order(
                symbol=long_call_symbol,
                transaction_type='BUY',
                quantity=lots * 25,
                price=strikes['long_call_premium']
            )
            orders.append(('long_call', order_id_4))
            
            # Wait and verify fills
            time.sleep(5)
            fill_status = self.verify_fills(orders)
            
            if fill_status['all_filled']:
                position = {
                    'id': len(self.positions) + 1,
                    'entry_time': pd.Timestamp.now(),
                    'signal': signal,
                    'lots': lots,
                    'orders': orders,
                    'status': 'open'
                }
                self.positions.append(position)
                return position
            else:
                # Partial fill - cancel and retry or close
                self.handle_partial_fill(orders, fill_status)
                return None
                
        except Exception as e:
            print(f"Execution error: {e}")
            # Emergency: try to close any filled legs
            self.emergency_close(orders)
            return None
    
    def place_limit_order(self, symbol, transaction_type, quantity, price):
        """Place limit order with retry logic"""
        max_retries = 3
        
        for attempt in range(max_retries):
            try:
                order_id = self.kite.place_order(
                    variety=self.kite.VARIETY_REGULAR,
                    exchange=self.kite.EXCHANGE_NFO,
                    tradingsymbol=symbol,
                    transaction_type=transaction_type,
                    quantity=quantity,
                    product=self.kite.PRODUCT_NRML,  # or PRODUCT_MIS for intraday
                    order_type=self.kite.ORDER_TYPE_LIMIT,
                    price=price,
                    validity=self.kite.VALIDITY_DAY
                )
                return order_id
                
            except Exception as e:
                print(f"Order placement failed (attempt {attempt+1}): {e}")
                if attempt < max_retries - 1:
                    time.sleep(2)
                    # Adjust price by 1 tick if timeout
                    if transaction_type == 'BUY':
                        price += 0.05
                    else:
                        price -= 0.05
                else:
                    raise
    
    def verify_fills(self, orders):
        """Check if all orders filled"""
        fill_status = {'all_filled': True, 'details': {}}
        
        for leg_name, order_id in orders:
            order_history = self.kite.order_history(order_id)
            last_status = order_history[-1]['status']
            
            fill_status['details'][leg_name] = {
                'order_id': order_id,
                'status': last_status,
                'filled_qty': order_history[-1].get('filled_quantity', 0)
            }
            
            if last_status not in ['COMPLETE']:
                fill_status['all_filled'] = False
        
        return fill_status
    
    def handle_partial_fill(self, orders, fill_status):
        """Handle partial fills - cancel unfilled, close filled"""
        for leg_name, order_id in orders:
            status = fill_status['details'][leg_name]['status']
            
            if status == 'OPEN' or status == 'TRIGGER PENDING':
                # Cancel unfilled orders
                try:
                    self.kite.cancel_order(
                        variety=self.kite.VARIETY_REGULAR,
                        order_id=order_id
                    )
                except:
                    pass
            
            elif status == 'COMPLETE':
                # Close filled legs at market
                # Get leg details and reverse
                # ... (implementation)
                pass
    
    def monitor_positions(self):
        """Real-time position monitoring with Greeks"""
        while True:
            for position in self.positions:
                if position['status'] != 'open':
                    continue
                
                # Get current quotes
                symbols = self.get_position_symbols(position)
                quotes = self.kite.quote(symbols)
                
                # Calculate current P&L and Greeks
                current_pnl = self.calculate_live_pnl(position, quotes)
                current_greeks = self.calculate_live_greeks(position, quotes)
                
                # Check exit conditions
                exit_signal = self.check_exit_conditions(
                    position, current_pnl, current_greeks
                )
                
                if exit_signal:
                    self.close_position(position, exit_signal['reason'])
                
                # Check risk thresholds
                self.check_risk_limits(position, current_pnl, current_greeks)
            
            time.sleep(30)  # Check every 30 seconds
    
    def check_exit_conditions(self, position, pnl, greeks):
        """Apply exit rules from strategy"""
        signal = position['signal']
        entry_credit = signal['strikes']['net_credit'] * position['lots'] * 25
        
        # Profit target
        if pnl >= entry_credit * 0.5:
            return {'exit': True, 'reason': 'profit_target'}
        
        # Stop loss
        if pnl <= -entry_credit * 2.0:
            return {'exit': True, 'reason': 'stop_loss'}
        
        # Time exit
        dte = (position['signal']['expiry'] - pd.Timestamp.now()).days
        if dte <= 2:
            return {'exit': True, 'reason': 'time_exit'}
        
        # Delta threshold
        if abs(greeks['delta']) > 0.30:
            return {'exit': True, 'reason': 'delta_breach'}
        
        return {'exit': False}
    
    def check_risk_limits(self, position, pnl, greeks):
        """Kill-switch logic for extreme scenarios"""
        # Daily loss limit
        total_daily_loss = self.calculate_total_daily_pnl()
        if total_daily_loss < -self.capital * 0.03:  # -3% daily loss
            self.emergency_close_all("DAILY_LOSS_LIMIT")
        
        # Margin breach
        margin_used = self.get_margin_used()
        if margin_used > self.capital * 0.75:  # 75% margin usage
            print("WARNING: Margin usage high")
            # Send alert
        
        # VIX spike
        vix = self.get_current_vix()
        if vix > 30:  # Threshold
            print("WARNING: High volatility")
            # Consider closing positions
    
    def close_position(self, position, reason):
        """Close all legs of a position"""
        symbols = self.get_position_symbols(position)
        
        for symbol in symbols:
            # Get current position from broker
            positions_data = self.kite.positions()['net']
            pos = next((p for p in positions_data if p['tradingsymbol'] == symbol), None)
            
            if pos and pos['quantity'] != 0:
                # Close with market order for speed
                self.kite.place_order(
                    variety=self.kite.VARIETY_REGULAR,
                    exchange=self.kite.EXCHANGE_NFO,
                    tradingsymbol=symbol,
                    transaction_type='SELL' if pos['quantity'] > 0 else 'BUY',
                    quantity=abs(pos['quantity']),
                    product=self.kite.PRODUCT_NRML,
                    order_type=self.kite.ORDER_TYPE_MARKET
                )
        
        position['status'] = 'closed'
        position['exit_time'] = pd.Timestamp.now()
        position['exit_reason'] = reason
        
        print(f"Position {position['id']} closed: {reason}")
    
    def emergency_close_all(self, reason):
        """Emergency close all positions"""
        print(f"EMERGENCY CLOSE: {reason}")
        
        for position in self.positions:
            if position['status'] == 'open':
                self.close_position(position, f"EMERGENCY_{reason}")
        
        # Send alert
        self.send_alert(f"All positions closed: {reason}")
    
    def calculate_live_greeks(self, position, quotes):
        """Calculate aggregate Greeks from live quotes"""
        # Use quotes and Black-Scholes for Greeks
        # ... (implementation using py_vollib or manual calculation)
        pass
    
    def get_current_vix(self):
        """Fetch current VIX value"""
        try:
            vix_quote = self.kite.quote("NSE:INDIA VIX")
            return vix_quote['NSE:INDIA VIX']['last_price']
        except:
            return None
    
    def send_alert(self, message):
        """Send SMS/Email/Telegram alert"""
        # Integration with notification service
        print(f"ALERT: {message}")
        # ... (implement SMS/email via twilio/sendgrid/telegram bot)

Risk Management & Monitoring Dashboard

import streamlit as st
import plotly.graph_objects as go

class RiskDashboard:
    def __init__(self, executor):
        self.executor = executor
    
    def render(self):
        st.title("QuantForge Options Trading Dashboard")
        
        # Portfolio Summary
        col1, col2, col3, col4 = st.columns(4)
        
        with col1:
            st.metric("Capital", f"₹{self.executor.capital:,.0f}")
        
        with col2:
            total_pnl = self.calculate_total_pnl()
            st.metric("Today's P&L", f"₹{total_pnl:,.0f}", 
                     delta=f"{total_pnl/self.executor.capital*100:.2f}%")
        
        with col3:
            open_positions = len([p for p in self.executor.positions if p['status'] == 'open'])
            st.metric("Open Positions", open_positions)
        
        with col4:
            margin_used = self.executor.get_margin_used()
            margin_pct = margin_used / self.executor.capital * 100
            st.metric("Margin Used", f"{margin_pct:.1f}%",
                     delta="⚠️" if margin_pct > 60 else "✅")
        
        # Portfolio Greeks
        st.subheader("Portfolio Greeks")
        greeks = self.calculate_portfolio_greeks()
        
        col1, col2, col3, col4 = st.columns(4)
        col1.metric("Delta", f"{greeks['delta']:.2f}")
        col2.metric("Gamma", f"{greeks['gamma']:.2f}")
        col3.metric("Theta", f"₹{greeks['theta']:.0f}/day")
        col4.metric("Vega", f"{greeks['vega']:.2f}")
        
        # Position Details
        st.subheader("Active Positions")
        positions_df = self.build_positions_table()
        st.dataframe(positions_df)
        
        # Risk Gauges
        st.subheader("Risk Indicators")
        col1, col2 = st.columns(2)
        
        with col1:
            # Daily loss gauge
            daily_loss_limit = -self.executor.capital * 0.03
            fig = go.Figure(go.Indicator(
                mode="gauge+number+delta",
                value=total_pnl,
                domain={'x': [0, 1], 'y': [0, 1]},
                title={'text': "Daily P&L"},
                delta={'reference': 0},
                gauge={
                    'axis': {'range': [daily_loss_limit, -daily_loss_limit]},
                    'bar': {'color': "darkblue"},
                    'steps': [
                        {'range': [daily_loss_limit, 0], 'color': "lightcoral"},
                        {'range': [0, -daily_loss_limit], 'color': "lightgreen"}
                    ],
                    'threshold': {
                        'line': {'color': "red", 'width': 4},
                        'thickness': 0.75,
                        'value': daily_loss_limit
                    }
                }
            ))
            st.plotly_chart(fig)
        
        with col2:
            # Margin gauge
            fig = go.Figure(go.Indicator(
                mode="gauge+number",
                value=margin_pct,
                domain={'x': [0, 1], 'y': [0, 1]},
                title={'text': "Margin Usage (%)"},
                gauge={
                    'axis': {'range': [0, 100]},
                    'bar': {'color': "darkblue"},
                    'steps': [
                        {'range': [0, 50], 'color': "lightgreen"},
                        {'range': [50, 70], 'color': "lightyellow"},
                        {'range': [70, 100], 'color': "lightcoral"}
                    ],
                    'threshold': {
                        'line': {'color': "red", 'width': 4},
                        'thickness': 0.75,
                        'value': 75
                    }
                }
            ))
            st.plotly_chart(fig)
        
        # Equity Curve
        st.subheader("Equity Curve")
        equity_data = self.get_equity_history()
        fig = go.Figure()
        fig.add_trace(go.Scatter(x=equity_data['date'], y=equity_data['equity'],
                                mode='lines', name='Equity'))
        fig.update_layout(xaxis_title="Date", yaxis_title="Equity (₹)")
        st.plotly_chart(fig)
    
    def calculate_portfolio_greeks(self):
        """Aggregate Greeks across all positions"""
        total_delta = 0
        total_gamma = 0
        total_theta = 0
        total_vega = 0
        
        for position in self.executor.positions:
            if position['status'] == 'open':
                greeks = self.executor.calculate_live_greeks(position, None)
                total_delta += greeks['delta']
                total_gamma += greeks['gamma']
                total_theta += greeks['theta']
                total_vega += greeks['vega']
        
        return {
            'delta': total_delta,
            'gamma': total_gamma,
            'theta': total_theta,
            'vega': total_vega
        }

Phased Rollout Plan (Practical Implementation)

Phase 0: Setup & Infrastructure (Days 0-14)

Objectives:

  • Build data pipeline
  • Implement backtest engine
  • Set up paper trading environment

Deliverables Checklist:

Week 1: Data & Environment

  •  Open trading account (Zerodha/Upstox) — verify KYC, fund ₹5-10L
  •  Subscribe to data vendor (optional: TrueData, Upstox Historical) or use free NSE data
  •  Download 2-3 years NIFTY/BANKNIFTY daily OHLCV
  •  Set up Python environment (pandas, numpy, ta-lib, backtrader/vectorbt)
  •  Create data storage structure (CSV/SQLite/PostgreSQL)
  •  Build option chain scraper (daily EOD snapshots)

Week 2: Backtest Foundation

  •  Implement OptionsBacktester class from blueprint above
  •  Code Iron Condor signal generator
  •  Code 2-3 additional strategies (Put Spread, Strangle)
  •  Build Black-Scholes pricer for Greeks calculation
  •  Implement transaction cost model
  •  Run first backtest on 1-year data
  •  Document results in backtest log template (see Appendix)

Validation Criteria:

  • Backtest runs without errors on 1+ year data
  • Generated at least 20+ trades in backtest
  • Performance metrics calculated correctly
  • Can reproduce results consistently

Phase 1: Paper Trading & Validation (Days 15-60)

Objectives:

  • Validate strategies in real-time without capital risk
  • Refine entry/exit timing
  • Test execution infrastructure

Week 3-4: Paper Trading Setup

  •  Set up paper trading account (most brokers offer virtual trading)
  •  Implement live data feed integration (WebSocket/REST API)
  •  Build position tracking system
  •  Create manual paper trading log (see template below)
  •  Paper trade 1-2 strategies (start with Iron Condor)

Paper Trading Log Template (CSV):

Date,Time,Strategy,Action,Symbol,Strikes,Lots,Credit_Debit,Spot,VIX,Notes
01-11-2024,10:15,Iron Condor,ENTRY,NIFTY,"21600/21700/22300/22400",3,1800,22050,14.5,"Clean fill"
02-11-2024,14:30,Iron Condor,HOLD,NIFTY,"21600/21700/22300/22400",3,900,22080,14.2,"MTM profit ₹900"
05-11-2024,15:00,Iron Condor,EXIT,NIFTY,"21600/21700/22300/22400",3,-900,22100,13.8,"Profit target hit"

Week 5-6: Iteration & Refinement

  •  Execute 15-20 paper trades across 2-3 strategies
  •  Track actual vs expected slippage
  •  Compare paper P&L vs backtest expectations
  •  Identify execution gaps (timing, fill rates, bid-ask impact)
  •  Refine entry filters based on false signals

Week 7-8: OOS Testing & Walk-Forward

  •  Run walk-forward analysis on backtest
    • Train period: Jan 2023 - Jun 2024
    • Test period: Jul 2024 - Oct 2024
  •  Compare in-sample vs out-of-sample metrics
  •  Stress test with 2024 data (includes high-vol periods)
  •  Document parameter stability

Validation Criteria (Phase 1 Gate):

  •  Minimum 15 completed paper trades
  •  Win rate ≥ 55% (or meets strategy expectations)
  •  Max drawdown in paper trading < 10%
  •  Actual slippage < 10% of backtest assumptions
  •  No major execution failures or missed exits
  •  Profit factor ≥ 1.3 (hypothetical threshold)

Go / No-Go Decision:

  • GO to Phase 2 if: 4+ of 6 criteria met
  • NO-GO if: Win rate < 50% or max drawdown > 15% → Return to backtest, adjust parameters

Phase 2: Small Live Pilot (Days 61-150)

Objectives:

  • Deploy capital with strict risk controls
  • Validate real money execution
  • Build operational discipline

Week 9-10: Pre-Launch Preparation

  •  Transfer ₹50k-₹1.5L to trading account (10-15% of total capital)
  •  Set up broker API credentials (API key, access token)
  •  Implement live executor class with kill-switches
  •  Configure real-time alerts (SMS/email/Telegram)
  •  Test live order placement with 1 lot (micro-test)
  •  Document pre-trade checklist

Week 11-20: Live Trading (Months 3-5)

Position Sizing (Conservative Start):

  • Capital Deployed: ₹1.5L (30% of ₹5L total)
  • Max Per-Trade Risk: 1% of total capital = ₹5,000
  • Strategies:
    • Iron Condor: 2-3 lots max (₹2-3k risk per position)
    • Put Spread: 1-2 lots (₹2-3k risk)
  • Max Concurrent Positions: 2-3 (total risk ₹10-15k = 2-3% capital)

Daily Operating Rhythm:

Morning (9:00-9:30 AM):
- Review overnight news/events
- Check VIX, NIFTY gap-up/down
- Review open positions P&L
- Check margin availability

Mid-Morning (10:00-11:00 AM):
- Scan for entry signals (if < 3 positions open)
- Execute new entries if conditions met
- Adjust threatened positions

Afternoon (2:00-3:00 PM):
- Monitor P&L vs targets
- Prepare adjustment orders if needed
- Check Greeks

End of Day (3:15-3:30 PM):
- Record all positions in log
- Calculate daily P&L
- Update equity curve
- Check exit triggers for next day

Evening (6:00-7:00 PM):
- Review day's performance
- Plan next day's actions
- Weekly review (on Fridays)

Weekly Review (Every Friday):

Metrics to Track:
- Number of trades entered: [X]
- Number of trades closed: [X]
- Win rate: [X]%
- Gross P&L: ₹[X]
- Net P&L (after costs): ₹[X]
- Max position drawdown: ₹[X]
- Largest winner: ₹[X]
- Largest loser: ₹[X]
- Average hold time: [X] days
- Rules followed: [X]/[Y] checklist items

Action Items:
- Any rule violations? Document and correct
- Emotional discipline issues? Note patterns
- Execution problems? Adjust process

Risk Controls (Strictly Enforced):

  1. Daily Loss Limit: Stop trading if loss reaches ₹7,500 (1.5% of total capital)
  2. Weekly Loss Limit: Stop for 1 week if weekly loss > ₹15,000 (3% capital)
  3. Consecutive Losses: After 3 losing trades, reduce position size by 50% for next 3 trades
  4. Margin Discipline: Never exceed 60% margin utilization
  5. Overnight Exposure: No positions held into major events (Budget, Fed meetings, elections)

Validation Criteria (Phase 2 Gate — After 3 Months Live):

  •  Minimum 30 live trades completed
  •  Win rate ≥ 55%
  •  Max drawdown < 10% of deployed capital
  •  No daily loss limit breaches
  •  Positive net P&L (even ₹1 counts — prove viability)
  •  Operational checklist compliance ≥ 90%

Go / No-Go Decision:

  • GO to Phase 3 if: 5+ of 6 criteria met, especially positive P&L
  • NO-GO if: Negative P&L after 3 months OR max drawdown > 12% → Pause, analyze, potentially return to paper trading

Phase 3: Scale & Diversification (Days 151+)

Objectives:

  • Increase position sizes methodically
  • Add more strategies to portfolio
  • Move toward semi-automation

Month 6-7: Gradual Scaling

Scaling Rules (Strict Gating):

Rule 1: Scale only after 4 consecutive profitable weeks
Rule 2: Increase position size by 25% increments (not 2x jumps)
Rule 3: Each scale-up requires 2-week observation period

Example Scaling Path:
- Months 3-5: 2-3 lots per position (base size)
- Month 6: After meeting criteria → 3-4 lots
- Month 7: After 2 weeks stable → 4-5 lots
- Month 8: After 2 weeks stable → 5-7 lots (target size for ₹5L capital)

Stop Scaling If:
- Any weekly loss > 2% of capital
- Drawdown exceeds 8% from peak
- Win rate drops below 50% for 2 consecutive weeks

Month 7-9: Strategy Diversification

Add New Strategies Sequentially:

  1. Month 7: Add Credit Call Spread (if bearish signals available)

    • Start with 1-2 lots, paper trade for 2 weeks first
  2. Month 8: Add Short Strangle + Wings (for high-vol environments)

    • Only deploy when VIX > 50th percentile
  3. Month 9: Add Ratio Spread or Calendar Spread

    • More complex, requires higher monitoring

Portfolio Target (Month 9):

  • 3-4 active strategies
  • 5-8 concurrent positions
  • Max portfolio risk: 5% of capital = ₹25k-50k
  • Margin utilization: 60-70%

Month 10+: Automation Layer

Semi-Automation Priorities:

Phase 3A: Monitoring Automation
- Real-time Greeks tracking dashboard
- Auto-alerts for exit triggers (Telegram bot)
- Automated position journaling

Phase 3B: Execution Assistance
- Pre-validated order batching (human approves, system executes)
- Automatic adjustment order generation (human approves)

Phase 3C: Full Automation (Optional, Month 12+)
- Auto-entry on confirmed signals (with daily limits)
- Auto-exit on profit targets / stop losses
- Human oversight: daily review + kill-switch access

Performance Targets (Hypothetical, Illustrative Only):

Conservative Expectations (₹5L capital, after 6 months scaling):
- Monthly return target: 2-4% (₹10k-₹20k)
- Max monthly drawdown tolerance: 8%
- Sharpe ratio target: >1.0
- Win rate target: 60-65%

Note: These are illustrative targets, not guarantees. Actual results will vary
based on market conditions, execution quality, and strategy selection.

Appendix: Templates & Code Snippets

A. Backtest Results Template (JSON)

{
  "backtest_id": "IC_NIFTY_Conservative_20240101_20241015",
  "strategy": "Iron Condor",
  "underlying": "NIFTY",
  "period": {
    "start": "2024-01-01",
    "end": "2024-10-15"
  },
  "parameters": {
    "dte_target": 10,
    "wing_width": 150,
    "delta_target": 0.18,
    "profit_target_pct": 0.5,
    "stop_loss_pct": 2.0,
    "risk_per_trade": 0.015,
    "vix_percentile_range": [20, 60]
  },
  "results": {
    "total_trades": 45,
    "winning_trades": 29,
    "losing_trades": 16,
    "win_rate": 64.4,
    "gross_pnl": 28500,
    "transaction_costs": 6750,
    "net_pnl": 21750,
    "max_drawdown": 8250,
    "sharpe_ratio": 1.42,
    "profit_factor": 1.68,
    "avg_win": 1450,
    "avg_loss": -1120,
    "max_win": 3200,
    "max_loss": -2800,
    "avg_hold_time_days": 7.2
  },
  "notes": "Backtest assumptions: mid-price fills, 1 tick slippage per leg, ₹350 transaction cost per round-trip"
}

B. Pre-Trade Checklist (Print & Use)

═══════════════════════════════════════════════════════════
QUANTFORGE PRE-TRADE CHECKLIST
═══════════════════════════════════════════════════════════

Trade Date: _______________  Time: _______________

MARKET CONTEXT
□ NIFTY Trend: ☐ Bull  ☐ Bear  ☐ Sideways
□ VIX Level: ______ (Percentile: ____%)
□ ADX Reading: ______ (< 25 for neutral strategies?)
□ Upcoming Events (next 7 days): _______________________

STRATEGY SELECTION
□ Selected Strategy: _____________________
□ Regime Match: ☐ Yes  ☐ Questionable
□ IV Environment Suitable: ☐ Yes  ☐ No

POSITION SIZING
□ Max Loss Per Lot: ₹__________
□ Risk Per Trade (1.5% capital): ₹__________
□ Calculated Lot Size: __________
□ Margin Required: ₹__________ (< 50% capital?)
□ Final Lot Size: __________

STRIKE SELECTION
□ Current Spot: __________
□ ATR(14): __________
□ Short Put Strike: __________ (Delta: ______)
□ Long Put Strike: __________
□ Short Call Strike: __________ (Delta: ______)
□ Long Call Strike: __________
□ Bid-Ask Spread Check: ☐ < 5% ☐ > 5% (reject)

TARGET CREDIT/DEBIT
□ Expected Credit: ₹__________ per unit
□ Min Acceptable Credit: ₹__________ (after slippage)
□ Max Risk Per Lot: ₹__________
□ Risk:Reward Ratio: __________

GREEKS EXPECTATIONS
□ Target Delta: ±__________ (near neutral?)
□ Expected Theta: +₹__________ per day
□ Vega Exposure: __________

EXIT PLAN
□ Profit Target: ₹__________ (50-60% of credit)
□ Stop Loss: ₹__________ (200% of credit)
□ Time Exit: ______ DTE
□ Alerts Set: ☐ Yes  ☐ No

RISK CHECKS
□ Current Open Positions: __________
□ Total Portfolio Risk: ₹__________ (< 5% capital?)
□ Margin Utilization: ______% (< 60%?)
□ Daily Loss Limit Remaining: ₹__________

FINAL APPROVAL
□ All checklist items reviewed
□ Strategy matches regime
□ Position size appropriate
□ Risk acceptable

Trader Signature: ________________  ☐ PROCEED  ☐ ABORT

═══════════════════════════════════════════════════════════

C. Black-Scholes Greeks Calculator (Python)

import numpy as np
from scipy.stats import norm

class BSMGreeks:
    def __init__(self, S, K, T, r, sigma, option_type='call'):
        """
        Black-Scholes-Merton Option Pricing and Greeks
        
        S: Spot price
        K: Strike price
        T: Time to expiry (years)
        r: Risk-free rate (annual)
        sigma: Implied volatility (annual)
        option_type: 'call' or 'put'
        """
        self.S = S
        self.K = K
        self.T = T
        self.r = r
        self.sigma = sigma
        self.option_type = option_type
        
        self.d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
        self.d2 = self.d1 - sigma*np.sqrt(T)
    
    def price(self):
        """Calculate option price"""
        if self.option_type == 'call':
            price = (self.S * norm.cdf(self.d1) - 
                    self.K * np.exp(-self.r*self.T) * norm.cdf(self.d2))
        else:  # put
            price = (self.K * np.exp(-self.r*self.T) * norm.cdf(-self.d2) - 
                    self.S * norm.cdf(-self.d1))
        return price
    
    def delta(self):
        """Calculate delta"""
        if self.option_type == 'call':
            return norm.cdf(self.d1)
        else:  # put
            return norm.cdf(self.d1) - 1
    
    def gamma(self):
        """Calculate gamma (same for call and put)"""
        return norm.pdf(self.d1) / (self.S * self.sigma * np.sqrt(self.T))
    
    def theta(self):
        """Calculate theta (per day)"""
        term1 = -(self.S * norm.pdf(self.d1) * self.sigma) / (2 * np.sqrt(self.T))
        
        if self.option_type == 'call':
            term2 = -self.r * self.K * np.exp(-self.r*self.T) * norm.cdf(self.d2)
        else:  # put
            term2 = self.r * self.K * np.exp(-self.r*self.T) * norm.cdf(-self.d2)
        
        # Convert from per year to per day
        theta_annual = term1 + term2
        return theta_annual / 365
    
    def vega(self):
        """Calculate vega (per 1% change in IV)"""
        vega_decimal = self.S * norm.pdf(self.d1) * np.sqrt(self.T)
        # Convert to per 1% IV change
        return vega_decimal / 100
    
    def rho(self):
        """Calculate rho (per 1% change in interest rate)"""
        if self.option_type == 'call':
            return self.K * self.T * np.exp(-self.r*self.T) * norm.cdf(self.d2) / 100
        else:  # put
            return -self.K * self.T * np.exp(-self.r*self.T) * norm.cdf(-self.d2) / 100
    
    def all_greeks(self):
        """Return all Greeks as dictionary"""
        return {
            'price': self.price(),
            'delta': self.delta(),
            'gamma': self.gamma(),
            'theta': self.theta(),
            'vega': self.vega(),
            'rho': self.rho()
        }

# Example usage:
def calculate_iron_condor_greeks(spot, strikes, dte, iv, r=0.07):
    """
    Calculate aggregate Greeks for iron condor
    
    strikes: dict with 'short_put', 'long_put', 'short_call', 'long_call'
    dte: days to expiry
    iv: implied volatility (e.g., 0.15 for 15%)
    """
    T = dte / 365
    
    # Short put (we sold it, so negative Greeks)
    short_put = BSMGreeks(spot, strikes['short_put'], T, r, iv, 'put')
    sp_greeks = short_put.all_greeks()
    
    # Long put (we bought it)
    long_put = BSMGreeks(spot, strikes['long_put'], T, r, iv, 'put')
    lp_greeks = long_put.all_greeks()
    
    # Short call (we sold it)
    short_call = BSMGreeks(spot, strikes['short_call'], T, r, iv, 'call')
    sc_greeks = short_call.all_greeks()
    
    # Long call (we bought it)
    long_call = BSMGreeks(spot, strikes['long_call'], T, r, iv, 'call')
    lc_greeks = long_call.all_greeks()
    
    # Aggregate (negative for short positions)
    position_greeks = {
        'delta': -sp_greeks['delta'] + lp_greeks['delta'] - sc_greeks['delta'] + lc_greeks['delta'],
        'gamma': -sp_greeks['gamma'] + lp_greeks['gamma'] - sc_greeks['gamma'] + lc_greeks['gamma'],
        'theta': -sp_greeks['theta'] + lp_greeks['theta'] - sc_greeks['theta'] + lc_greeks['theta'],
        'vega': -sp_greeks['vega'] + lp_greeks['vega'] - sc_greeks['vega'] + lc_greeks['vega'],
        'position_value': -sp_greeks['price'] + lp_greeks['price'] - sc_greeks['price'] + lc_greeks['price']
    }
    
    return position_greeks

# Test example
if __name__ == "__main__":
    spot = 22000
    strikes = {
        'short_put': 21700,
        'long_put': 21600,
        'short_call': 22300,
        'long_call': 22400
    }
    
    greeks = calculate_iron_condor_greeks(spot, strikes, dte=10, iv=0.15)
    print("Iron Condor Greeks:")
    for key, value in greeks.items():
        print(f"{key}: {value:.4f}")

D. 30/60/90-Day Rollout Tracking Template (CSV)

Phase,Milestone,Target_Date,Status,Actual_Date,KPI,Target,Actual,Notes
0,Setup,2024-11-15,Pending,,"Data Pipeline",Ready,,"NSE historical + options chain"
0,Setup,2024-11-15,Pending,,"Backtest Engine",Functional,,"Test on 2-year data"
0,Setup,2024-11-20,Pending,,"Paper Trade Env",Ready,,"Virtual account setup"
1,Paper_Trading,2024-12-01,Pending,,"First Paper Trade",1,,"Iron Condor"
1,Paper_Trading,2024-12-15,Pending,,"Paper Trades Count",10,,"Across 2 strategies"
1,Paper_Trading,2024-12-31,Pending,,"Win Rate",">55%",,"Phase 1 gate"
1,Paper_Trading,2024-12-31,Pending,,"Max Drawdown","<10%",,"Phase 1 gate"
2,Live_Pilot,2025-01-05,Pending,,"First Live Trade",1,,"₹50k capital deployed"
2,Live_Pilot,2025-01-31,Pending,,"Live Trades Count",10,,"Month 1"
2,Live_Pilot,2025-02-28,Pending,,"Cumulative Trades",20,,"Month 2"
2,Live_Pilot,2025-03-31,Pending,,"Phase 2 Win Rate","≥55%",,"Phase 2 gate"
2,Live_Pilot,2025-03-31,Pending,,"Net P&L",">₹0",,"Positive after 3 months"
3,Scaling,2025-04-30,Pending,,"Position Size Increase","25%",,"After 4 profitable weeks"
3,Scaling,2025-05-31,Pending,,"Strategy Count",3,,"Add 2nd strategy"
3,Scaling,2025-06-30,Pending,,"Target Position Size","5-7 lots",,"Full scale for ₹5L"
3,Diversification,2025-07-31,Pending,,"Active Strategies",4,,"Portfolio diversified"
3,Automation,2025-09-30,Pending,,"Monitoring Dashboard",Live,,"Real-time Greeks tracking"
3,Automation,2025-12-31,Pending,,"Semi-Automation","Phase 3B",,"Execution assistance"

E. Daily Trading Journal Template

═════════════════════════════════════════════════════════════
QUANTFORGE DAILY TRADING JOURNAL
═════════════════════════════════════════════════════════════

Date: _______________  Day of Week: _______________

MARKET OVERVIEW
─────────────────────────────────────────────────────────────
NIFTY Open: ________  High: ________  Low: ________  Close: ________
NIFTY Change: _______%
VIX: ________  (Change: ______%)
Major News/Events: _________________________________________

PORTFOLIO STATUS (START OF DAY)
─────────────────────────────────────────────────────────────
Starting Equity: ₹__________
Open Positions: __________
Margin Used: ₹__________ (______%)
Available Cash: ₹__________

POSITIONS OPENED TODAY
─────────────────────────────────────────────────────────────
Position #: _____
Strategy: _____________________
Strikes: _____________________
Lots: _____  Credit/Debit: ₹_____  Max Risk: ₹_____
Entry Time: _____  Spot at Entry: _____
Entry Reasoning: ____________________________________________
Checklist Followed: ☐ Yes  ☐ No (If no, explain: __________)

POSITIONS CLOSED TODAY
─────────────────────────────────────────────────────────────
Position #: _____
Strategy: _____________________
Entry Date: _________  Exit Date: _________  Hold Time: _____ days
Exit Reason: ☐ Profit Target  ☐ Stop Loss  ☐ Time  ☐ Adjustment
Entry Credit: ₹_____  Exit Debit: ₹_____
Gross P&L: ₹_____  Costs: ₹_____  Net P&L: ₹_____
Exit Reasoning: _____________________________________________

POSITIONS HELD (End of Day Status)
─────────────────────────────────────────────────────────────
Position #1: ____________  DTE: ____  MTM P&L: ₹____  Delta: ____
Position #2: ____________  DTE: ____  MTM P&L: ₹____  Delta: ____
Position #3: ____________  DTE: ____  MTM P&L: ₹____  Delta: ____

PORTFOLIO STATUS (END OF DAY)
─────────────────────────────────────────────────────────────
Ending Equity: ₹__________
Daily P&L: ₹__________ (______%)
Closed Trades Today: _____  (Wins: _____ / Losses: _____)
Aggregate Greeks: Delta: ____  Gamma: ____  Theta: ____  Vega: ____

RISK ASSESSMENT
─────────────────────────────────────────────────────────────
Daily Loss Limit Status: ₹________ remaining (of ₹7,500)
Position Risk: ₹________ (______% of capital)
Margin Usage: ______% (Target: < 60%)
Max Portfolio Delta: ________ (Target: < 0.15 per ₹1L)

EXECUTION QUALITY
─────────────────────────────────────────────────────────────
Orders Placed: _____  Orders Filled: _____  Fill Rate: ______%
Average Slippage: ₹_____ per leg
Limit Orders Used: ☐ Yes  ☐ No (Market orders)
Execution Issues: ___________________________________________

RULE ADHERENCE
─────────────────────────────────────────────────────────────
Pre-Trade Checklist: ☐ Followed  ☐ Partially  ☐ Skipped
Position Sizing Rules: ☐ Followed  ☐ Violated
Exit Rules: ☐ Followed  ☐ Emotional override
Risk Limits: ☐ Within  ☐ Breached (Explain: ______________)

EMOTIONAL STATE & DISCIPLINE
─────────────────────────────────────────────────────────────
Emotional State: ☐ Calm  ☐ Anxious  ☐ Frustrated  ☐ Euphoric
Discipline Score (1-10): _____
Mistakes Made: ______________________________________________
Lessons Learned: ____________________________________________

TOMORROW'S PLAN
─────────────────────────────────────────────────────────────
Positions to Monitor: _______________________________________
Potential Exits: ____________________________________________
Potential Entries: __________________________________________
Events to Watch: ____________________________________________

NOTES & OBSERVATIONS
─────────────────────────────────────────────────────────────
_________________________________________________________________
_________________________________________________________________
_________________________________________________________________

═════════════════════════════════════════════════════════════

F. Weekly Performance Review Template

═══════════════════════════════════════════════════════════
QUANTFORGE WEEKLY PERFORMANCE REVIEW
═══════════════════════════════════════════════════════════

Week Ending: _______________

TRADING METRICS
───────────────────────────────────────────────────────────
Total Trades: _____
  - Opened: _____
  - Closed: _____
  - Win: _____
  - Loss: _____
  - Scratch: _____

Win Rate: ______%
Profit Factor: ______

FINANCIAL PERFORMANCE
───────────────────────────────────────────────────────────
Starting Capital: ₹__________
Ending Capital: ₹__________
Weekly P&L: ₹__________ (______%)

Largest Win: ₹__________
Largest Loss: ₹__________
Average Win: ₹__________
Average Loss: ₹__________

Total Transaction Costs: ₹__________
Net Profit After Costs: ₹__________

STRATEGY BREAKDOWN
───────────────────────────────────────────────────────────
Strategy 1 (Iron Condor):
  Trades: _____  Win Rate: ______%  P&L: ₹__________

Strategy 2 (Put Spread):
  Trades: _____  Win Rate: ______%  P&L: ₹__________

Strategy 3 (___________):
  Trades: _____  Win Rate: ______%  P&L: ₹__________

Best Performing Strategy: _______________________________
Worst Performing Strategy: _______________________________

RISK METRICS
───────────────────────────────────────────────────────────
Max Intraweek Drawdown: ₹__________ (______%)
Avg Daily Position Risk: ₹__________ (______% capital)
Avg Margin Utilization: ______%
Daily Loss Limit Breaches: _____
Weekly Loss Limit Breached: ☐ Yes  ☐ No

EXECUTION QUALITY
───────────────────────────────────────────────────────────
Total Orders: _____
Fill Rate: ______%
Average Slippage: ₹_____ per leg
Execution Errors: _____

RULE ADHERENCE
───────────────────────────────────────────────────────────
Pre-Trade Checklist Compliance: ______% (_____ / _____)
Position Sizing Violations: _____
Emotional Override Exits: _____
Risk Limit Breaches: _____

Overall Discipline Score (1-10): _____

WHAT WORKED THIS WEEK
───────────────────────────────────────────────────────────
1. ________________________________________________________
2. ________________________________________________________
3. ________________________________________________________

WHAT DIDN'T WORK
───────────────────────────────────────────────────────────
1. ________________________________________________________
2. ________________________________________________________
3. ________________________________________________________

MISTAKES & LESSONS
───────────────────────────────────────────────────────────
Mistake: ___________________________________________________
Lesson: ____________________________________________________

Mistake: ___________________________________________________
Lesson: ____________________________________________________

ACTION ITEMS FOR NEXT WEEK
───────────────────────────────────────────────────────────
☐ _________________________________________________________
☐ _________________________________________________________
☐ _________________________________________________________

SCALING DECISION (If in Phase 2/3)
───────────────────────────────────────────────────────────
Consecutive Profitable Weeks: _____
Ready to Scale Position Size: ☐ Yes  ☐ No
Rationale: _________________________________________________

NOTES
───────────────────────────────────────────────────────────
_____________________________________________________________
_____________________________________________________________
_____________________________________________________________

═══════════════════════════════════════════════════════════

STRATEGY CARDS 4-12 (Condensed)

STRATEGY CARD 4: Credit Call Spread

Overview: Bearish/neutral bet, sell OTM call + buy further OTM call Regime: Bear/Sideways, Low-Med Vol Setup: Sell 0.25 delta call, buy call ₹100-150 above Entry: RSI < 50, price below 20-SMA, VIX 20-60th percentile Exit: 50% profit, 200% loss, 2 DTE, breach short strike Greeks: Delta -0.20, Theta +20, Vega -8 Sizing: 3-4 lots for ₹5L (conservative)


STRATEGY CARD 5: Ratio Put Spread

Overview: Bullish, sell 2x OTM puts, buy 1x further OTM put Regime: Bull, Medium Vol (collect extra premium) Setup: Buy 1 put at 0.10 delta, sell 2 puts at 0.25 delta Entry: Strong bullish momentum, support zone, VIX 40-70th percentile Exit: 40% credit profit, loss if spot drops below lower short put Greeks: Delta +0.30, Gamma negative (risk below lower strike) Sizing: 1-2 lots max (undefined risk below breakeven) Warning: Requires close monitoring, can have large losses in crash


STRATEGY CARD 6: Calendar Spread (Time Spread)

Overview: Neutral, profit from front-month theta decay Regime: Sideways, Medium-High Vol Setup: Sell front-week ATM put/call, buy next-week same strike Entry: Spot stable, VIX elevated (front-month IV > back-month) Exit: Close before front-month expiry, profit from theta Greeks: Theta positive, Vega positive (long back-month) Sizing: 2-3 lots for ₹5L Complex: Requires IV surface understanding, inter-expiry dynamics


STRATEGY CARD 7: Jade Lizard

Overview: Bullish, no upside risk: short strangle + extra OTM call sold Regime: Neutral-Bull, Low-Med Vol Setup: Sell OTM put, sell OTM call spread (put premium ≥ call spread width) Entry: Bullish bias, high IV rank Exit: 50% profit, manage downside (put side risk) Greeks: Delta +0.10-0.20, Theta high Sizing: 2-3 lots Advantage: Undefined upside, defined downside via put


STRATEGY CARD 8: Big Lizard

Overview: Bearish version of Jade Lizard Regime: Neutral-Bear, Low-Med Vol Setup: Sell OTM call, sell OTM put spread (call premium ≥ put spread width) Entry: Bearish bias, high IV rank Exit: 50% profit, manage upside (call side risk) Greeks: Delta -0.10 to -0.20, Theta high


STRATEGY CARD 9: Diagonal Spread

Overview: Directional with time advantage Regime: Trending markets, Med Vol Setup: Sell front-month OTM option, buy back-month further OTM Entry: Expected slow move in direction Exit: Roll front-month each week, close back-month when profitable Complex: Multi-expiry management, requires experience


STRATEGY CARD 10: Iron Butterfly

Overview: Tight range bet, ATM short straddle + OTM wings Regime: Very low vol, tight range expected Setup: Sell ATM put + ATM call, buy OTM wings ₹200-300 away Entry: Bollinger Bands squeezed, low VIX Exit: 40-50% profit, tight stop loss Greeks: Gamma very high (risky near expiry), Theta very high Sizing: 1-2 lots (high risk/reward)


STRATEGY CARD 11: Covered Strangle (Cash-Secured)

Overview: Own underlying, sell OTM put + OTM call Regime: Sideways, income on holdings Setup: Hold 500 NIFTY futures/ETF, sell 0.20 delta put + call Entry: Long-term bullish on underlying, want income Exit: Roll monthly, manage assignment Capital Intensive: Requires holding underlying (₹5-10L+)


STRATEGY CARD 12: Long Butterfly (Debit)

Overview: Profit from no movement, defined risk Regime: Extremely low vol expected Setup: Buy 1 ITM, sell 2 ATM, buy 1 OTM (puts or calls) Entry: VIX < 20th percentile, expected consolidation Exit: Close when 50% of max profit reached Greeks: Theta slightly positive, Gamma high near ATM Sizing: 3-5 lots (low risk per lot)


Risk & Compliance Checklist

  •  SEBI Compliance: Confirm latest F&O margin rules (SPAN+Exposure)
  •  Tax Obligations:
    •  STT on sell side understood
    •  F&O gains taxed as business income (consult CA)
    •  Maintain detailed trade log for tax filing
  •  Broker Agreement: Terms of service reviewed
  •  Pattern Day Trading: Not applicable in India (no PDT rule like US)
  •  Leverage Limits: Understand broker's intraday vs overnight margin
  •  Early Assignment: Know broker's policy on ITM options near expiry
  •  Exchange Penalties: Understand penalties for position limit breaches (if trading large size)

Operational Risk Controls

  •  API Security: API keys stored securely, never in code repos
  •  Kill-Switch Tested: Emergency close-all function works
  •  Backup Internet: Have mobile hotspot for trading continuity
  •  Broker Redundancy: Consider second broker account for backup
  •  Capital Segregation: Trading capital separate from emergency funds
  •  Insurance: Health/life insurance in place (trading stress management)

Final Summary & Next Steps

Immediate Actions (Week 1)

  1. Download historical data for NIFTY (2-3 years)
  2. Set up Python environment with required libraries
  3. Implement Iron Condor backtest using provided code
  4. Review Strategy Cards and select 2-3 to start
  5. Open paper trading account if not already done

Success Principles

  1. Start Small, Scale Slowly: Never risk more than 2% per trade initially
  2. Follow the Process: Checklists exist for a reason—use them
  3. Track Everything: Data drives improvement
  4. Be Patient: Proficiency takes 6-12 months, not weeks
  5. Preserve Capital: Your first job is to not lose money, second job is to make money
  6. Adapt: Markets change, strategies must adapt

Common Pitfalls to Avoid

  • ❌ Skipping paper trading phase
  • ❌ Over-leveraging (using >60% margin)
  • ❌ Holding positions into expiry (gamma risk)
  • ❌ Ignoring stop losses (hope is not a strategy)
  • ❌ Revenge trading after losses
  • ❌ Adding to losing positions without plan
  • ❌ Trading during high-impact events without hedge

Resources for Continuous Learning


DISCLAIMER

Information provided is for educational purposes only. Past performance does not guarantee future returns. Backtest and paper-trade before live deployment. Verify current regulatory, tax, and brokerage rules. Consult licensed financial and legal advisors as necessary.

Options trading involves substantial risk of loss and is not suitable for all investors. The strategies outlined here are hypothetical and based on theoretical models. Actual results may vary significantly due to market conditions, execution quality, slippage, transaction costs, and other factors. No representation is being made that any account will or is likely to achieve profits or losses similar to those discussed. The user assumes full responsibility for their trading decisions.

Comments

Popular posts from this blog

Fyers Automate

Complete Roadmap to Become a Successful Profit-Making Full-Time Quant Trader in India