QuadraTrades Architecture Reference

Adaptive Regime-Aware Scaling Engine

Complete technical blueprint, mathematical foundation, and implementation rationale for dynamic multi-stage partial profit booking and runner allocation across live market regimes.

System: QuadraTrades (EC2 Verified) Module: trade_management
Test Suite: 473 Passing
Revision: 2026.10.12-v2
1. Core Philosophy 2. Four Market Profiles 3. Regime Detection Ladder 4. NSE Lot Quantization 5. Trailing & Ratchet Engine 6. Interactive Simulator 7. Code Architecture
01

The Problem Statement & System Philosophy

In Indian derivative option buying on the NIFTY 50 index, static profit-taking is inherently flawed. A static model that books fixed percentages (e.g., 40% @ 1.5R, 30% @ 3.0R, 15% @ 5.0R) inevitably suffers from two structural failure modes:

The Trend Day Dilemma

On persistent expansion days (ADX ≥ 28, directional institutional day), banking 40% at +1.5R prematurely strips position weight from the trade. By the time NIFTY surges 150–250 points, the account is left with only 15% runner capacity, leaving vast chunks of expectancy unharvested.

The Mean-Reversion Trap

In range-bound markets or liquidity sweeps, waiting for +3.0R or +5.0R leads to sudden, aggressive price rejections at opposing structural extremes. Open profits evaporate into stop-outs before later milestones are ever touched.

0DTE Expiry Theta Bleed

On Tuesday afternoons post-13:00 IST, non-linear theta decay accelerates dramatically. A runner position idling for 20 minutes without new highs will suffer crushing premium erosion even if the underlying index merely consolidates.

The Solution: The Adaptive Regime-Aware Scaling Engine conditions the milestone allocations, R-multiples, and stop loss ratchet speeds on live market telemetry (ADX, Market Regime, Strategy Classification, and Time-to-Expiry).

02

The Four Market-Aware Scaling Profiles

QuadraTrades dynamically classifies every trade into one of four distinct scaling profiles at order origination:

TREND_RUNNER Expansion Days

Selected for TrendDayRunner, FirstPullback, or any directional signal with ADX ≥ 28.

  • Milestone 1 (+1.5R): 25% Booked
  • Milestone 2 (+3.0R): 25% Booked
  • Milestone 3 (+5.0R): 20% Booked
  • Runner Allocation: 30% Retained
  • Stop Progression: Initial → BE → +2.0R → +3.0R
  • Runner Trailing: 5m Swing Lows / Highs

STANDARD_BALANCED Default Regime

Standard expansion setups, moderate volatility, or general breakout continuations.

  • Milestone 1 (+1.5R): 40% Booked
  • Milestone 2 (+3.0R): 30% Booked
  • Milestone 3 (+5.0R): 15% Booked
  • Runner Allocation: 15% Retained
  • Stop Progression: Initial → BE → +2.0R → +3.0R
  • Runner Trailing: 5m Swing Lows / Highs

QUICK_HARVEST Mean Reversion

Triggered for FailedBreakout, LiquiditySweepReversal, SniperLiquidityReversal, or ADX < 22.

  • Milestone 1 (+1.5R): 50% Booked
  • Milestone 2 (+2.5R): 35% Booked
  • Milestone 3: None (Direct to Runner)
  • Runner Allocation: 15% Retained
  • Stop Progression: Initial → BE → +1.8R Lock
  • State Shift: Enters RUNNER at M2

EXPIRY_GAMMA 0DTE Tuesdays

Triggered for ExpiryGammaBlast, explicit expiry flags, or Tuesday trading post-13:00 IST.

  • Milestone 1 (+1.5R): 50% Booked
  • Milestone 2 (+2.5R): 40% Booked
  • Milestone 3: None (Direct to Runner)
  • Runner Allocation: 10% Retained
  • Theta Stagnation: 15-min timeout (Lock 85%)
  • Round Numbers: Trails 50-pt strikes
03

Dynamic Resolution Ladder Flowchart

When an entry signal arrives, resolve_scaling_profile() executes a deterministic resolution hierarchy to guarantee the correct allocation without ambiguity:

1

Step 1: Check Explicit Metadata Override

If the strategy or manual operator specified metadata["scaling_profile"], respect that directly.

2

Step 2: Check 0DTE Expiry Conditions

If strategy_name == "ExpiryGammaBlast", or is_expiry == True, or current day is Tuesday (weekday 1) and timestamp ≥ 13:00 IST → Select EXPIRY_GAMMA.

3

Step 3: Check Mean-Reversion / Chop / Reversal Regimes

If strategy is FailedBreakout, LiquiditySweepReversal, SniperLiquidityReversal, OR market regime is RANGE, CHOPPY, REVERSAL, OR ADX < 22.0 → Select QUICK_HARVEST.

4

Step 4: Check Directional Trend Continuation

If strategy is TrendDayRunner, FirstPullback with ADX ≥ 25, or regime is TREND_UP/DOWN with ADX ≥ 28.0 → Select TREND_RUNNER.

5

Step 5: Default Fallback

For standard breakout continuations or unclassified expansion regimes → Select STANDARD_BALANCED.

04

NSE Whole-Lot Quantization & Integer Math

In live Indian exchange trading (NSE F&O), contracts can only be traded in exact integer multiples of the lot size (e.g., 25 or 65 shares). Fractional lots are strictly rejected by broker APIs. QuadraTrades enforces robust integer discretization:

# Mathematical Discretization Formula in TradeManager def _calculate_partial_qty(self, trade: Trade, booking_pct: float) -> int: if not self.enforce_exchange_lots: return int(trade.initial_quantity * booking_pct) # Exchange lot mode: 1-lot positions cannot be split if trade.lots <= 1 or trade.current_quantity <= self.lot_size: return 0 # Entire single lot kept for runner expansion # Discretize to floor lot size exit_lots = max(1, math.floor(trade.lots * booking_pct)) exit_qty = exit_lots * self.lot_size # Hard Guard: Guarantee at least 1 lot is preserved for Runner Mode if trade.current_quantity - exit_qty < self.lot_size: exit_lots = max(0, (trade.current_quantity // self.lot_size) - 1) exit_qty = exit_lots * self.lot_size return exit_qty
Initial Position Profile Milestone 1 Milestone 2 Milestone 3 Final Runner
1 Lot (65 shares) Any Profile 0 shares (Stop → BE) 0 shares (Stop → Lock) 0 shares 1 Lot (100% Runner)
4 Lots (260 shares) TREND_RUNNER 1 Lot (65 shares) @ +1.5R 1 Lot (65 shares) @ +3.0R 1 Lot (65 shares) @ +5.0R 1 Lot (25% Runner)
4 Lots (260 shares) QUICK_HARVEST 2 Lots (130 shares) @ +1.5R 1 Lot (65 shares) @ +2.5R — 1 Lot (25% Runner)
5 Lots (325 shares) EXPIRY_GAMMA 2 Lots (130 shares) @ +1.5R 2 Lots (130 shares) @ +2.5R — 1 Lot (20% Runner)
10 Lots (650 shares) TREND_RUNNER 2 Lots (130 shares) @ +1.5R 2 Lots (130 shares) @ +3.0R 2 Lots (130 shares) @ +5.0R 4 Lots (40% Runner)
05

Stop Loss Progression & Gain Retention Mechanics

A successful runner engine must systematically lock in gains without choking normal market pullbacks. QuadraTrades utilizes a 5-tier stop ratchet architecture:

1. Breakeven Lock (+1.5R)

When Milestone 1 triggers, stop loss automatically advances to entry_price + breakeven_buffer (default +1.0 pt), completely eliminating financial risk on the trade.

2. Milestone 2 Lock (+2.0R / +1.8R)

When Milestone 2 triggers, stop loss ratchets to guarantee at least +2.0R (or +1.8R in Quick Harvest), preventing open profits from collapsing back to breakeven.

3. Milestone 3 Lock (+3.0R)

When Milestone 3 triggers, stop loss ratchets to guarantee +3.0R minimum profit, while remaining shares enter uninhibited structural 5m trailing.

4. Tiered Peak Gain Retention

Once peak R ≥ 1.5R, stop ratchets dynamically:
• 1.5R to 2.5R: Locks 65% of peak gain
• 2.5R to 4.0R: Locks 75% of peak gain
• ≥ 4.0R: Locks 80% of peak gain

5. Afternoon Theta Stagnation

Post-13:00 IST, if an option in profit makes no new high for 25 minutes (or 15 minutes under EXPIRY_GAMMA), the stop aggressively snaps to 85% of peak gains.

06

Interactive Live Scaling Simulator

Test trade allocations, realized profits, and stop ratchets across any configuration in real-time:

QuadraTrades Live Scaling Engine Simulator

Simulates exchange lot allocation and stop ratchets.

Initial Risk Per Unit
INR 20.00
Total Account Risk
INR 6,500.00
Total Booked (Milestones)
INR 14,300.00
Final Runner Remaining
1 Lot (65 shares)
EXECUTION MILESTONES & STOP PROGRESSION STANDARD_BALANCED
07

Core Code Architecture & Module Integration

The system was implemented with 100% backward compatibility across four key modules:

# 1. nifty_expansion_runner/core/enums.py class ScalingProfile(str, Enum): TREND_RUNNER = "TREND_RUNNER" # 25% @ 1.5R, 25% @ 3.0R, 20% @ 5.0R -> 30% Runner STANDARD_BALANCED = "STANDARD_BALANCED"# 40% @ 1.5R, 30% @ 3.0R, 15% @ 5.0R -> 15% Runner QUICK_HARVEST = "QUICK_HARVEST" # 50% @ 1.5R, 35% @ 2.5R -> 15% Runner EXPIRY_GAMMA = "EXPIRY_GAMMA" # 50% @ 1.5R, 40% @ 2.5R -> 10% Runner (0DTE) # 2. nifty_expansion_runner/core/models.py (Trade dataclass attributes) @dataclass(slots=True) class Trade: # ... existing fields ... scaling_profile: ScalingProfile = ScalingProfile.STANDARD_BALANCED milestone_1_r: float = 1.5 milestone_1_pct: float = 0.40 milestone_2_r: float = 3.0 milestone_2_pct: float = 0.30 milestone_2_stop_r: float = 2.0 milestone_3_r: float = 5.0 milestone_3_pct: float = 0.15 # 3. nifty_expansion_runner/trade_management/runner_engine.py # 15-minute stagnation timeout for EXPIRY_GAMMA timeout_mins = (15 if getattr(trade, "scaling_profile", None) == ScalingProfile.EXPIRY_GAMMA else self.stagnation_timeout_minutes)