Jump to content

Alpha Research1: Difference between revisions

From PlusEV Wiki Page
Created page with "= Multi-Layer Confluence Strategy (MLC) = == Systematic Intraday Trading System == === MCX Crude Oil Futures === ---- = PART 1: STRATEGY OVERVIEW = == What Is This Strategy? == '''Multi-Layer Confluence (MLC)''' is a systematic intraday trading strategy that requires multiple analytical layers to align before taking a trade. Think of it as a '''layered cake''' - each layer must be present for a valid setup. == The Layered Architecture (Read Top-Down) == <pre> ┌..."
 
No edit summary
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
= Multi-Layer Confluence Strategy (MLC) =
  == Component: setup_quality_detection.py ==
== Systematic Intraday Trading System ==
=== MCX Crude Oil Futures ===


----
  === Purpose (Trading Context) ===
  '''The Grader''' - This component answers: "How good is this trading setup?"


= PART 1: STRATEGY OVERVIEW =
  Think of it like a teacher grading an exam: Each setup is scored on 5 factors, penalties are applied for bad conditions, and a final grade (A+ to F) is assigned. The grade determines position size and whether we should trade at all.


== What Is This Strategy? ==
  '''Key Philosophy''': Not all setups are equal. A+ setups get bigger positions. C/D/F setups are rejected by signal generation.


'''Multi-Layer Confluence (MLC)''' is a systematic intraday trading strategy that requires multiple analytical layers to align before taking a trade. Think of it as a '''layered cake''' - each layer must be present for a valid setup.
  === What It Does (Simple Terms) ===
  1. Receives analyzed data from upstream components
  2. Scores each setup on 5 weighted factors (0-100 each)
  3. Applies penalties for adverse market conditions (creeper, MA struggle, etc.)
  4. Caps score if A+ criteria not met
  5. Assigns letter grade (A+ to F)
  6. Recommends position size based on grade


== The Layered Architecture (Read Top-Down) ==
  === Inputs ===
  {| class="wikitable"
  |-
  ! Input !! Source !! What It Provides
  |-
  | timeframe_analysis || multi_timeframe_analysis.py || Alignment score, aligned flag
  |-
  | market_state || market_state_analysis.py || Creeper move, MA struggle, railroad trend, trend phase, institutional fight
  |-
  | entry_data || Calculated in main.py || near_key_level, near_ma, clean_entry, risk_reward
  |-
  | strategy_config || Configuration || Strategy ID
  |-
  | timestamp || Current bar || Timestamp for logging
  |}


<pre>
  === Outputs (SetupQualityResult) ===
┌─────────────────────────────────────────────────────────────┐
  {| class="wikitable"
│                                                            │
   |-
  LAYER 1: MULTI-TIMEFRAME ANALYSIS  ◄── THE FOUNDATION    │
   ! Field !! Type !! Description
  5 timeframes analyzed for trend alignment                │
   |-
  Daily → 4H → 1H → 15M → 5M                              │
   | grade || SetupQualityGrade || A+, A, B, C, D, or F
│                                                            │
   |-
├─────────────────────────────────────────────────────────────┤
   | score || float || 0-100 final score after all penalties
│                                                            │
   |-
  LAYER 2: MARKET STATE ANALYSIS                          │  ← Context
   | factor_scores || Dict || Individual scores for each of 5 factors
│  7 algorithms: Railroad, Creeper, Phase, BOS, etc.        │
   |-
  Calculates penalties and bonuses                          │
   | position_size || int || Recommended lots (1 or 2)
│                                                            │
   |-
├─────────────────────────────────────────────────────────────┤
  | risk_percent || float || Risk % based on grade
│                                                            │
   |-
  LAYER 3: SETUP QUALITY GRADING                          │  ← Scoring
   | can_auto_trade || bool || Only A+ and A are auto-tradeable
  5-factor weighted scoring → Assigns grade A+ to F        │
  |}
│                                                            │
├─────────────────────────────────────────────────────────────┤
│                                                            │
  LAYER 4: HARD FILTERS  ◄── GATE (Pass/Fail)              │
  • Direction: MA21 slope must match trade direction        │
  • Grade: D/F grades blocked (A+/A/B/C can trade)         │
  • Hours: Block hours 9, 22, 23                            │
│                                                            │
├─────────────────────────────────────────────────────────────┤
│                                                            │
  LAYER 5: ENTRY TECHNIQUE                                │  ← Final trigger
  Price must be near 21-period MA (±25 points)              │
│                                                            │
└─────────────────────────────────────────────────────────────┘
</pre>


<div style="background:#ffffcc; border:1px solid #ffcc00; padding:10px; margin:10px 0;">
  === The 5-Factor Scoring System ===
'''Key Insight:''' A trade only happens when ALL layers align. MTF Analysis is the foundation - without trend alignment across timeframes, nothing else matters.
  '''Total Weight = 100%''' (must sum to exactly 1.0)
</div>


== Instrument Details ==
  {| class="wikitable"
  |-
  ! Factor !! Weight !! What It Measures !! Calculation
  |-
  | Timeframe Alignment || '''30%''' || Are all timeframes pointing same direction? || alignment_score × 100
  |-
  | Trend Strength || '''20%''' || Is trend healthy? || 100 - penalties + bonuses
  |-
  | Entry Quality || '''15%''' || Is entry at a good spot? || 100 + bonuses - penalties
  |-
  | Key Level Proximity || '''20%''' || Is price near important level? || 100 - 50 if not near key level
  |-
  | Risk/Reward || '''15%''' || Is R:R acceptable? || Lookup table (see below)
  |}


{| class="wikitable"
  === Risk/Reward Scoring Table ===
|-
  '''EXACT boundaries from specification:'''
! Parameter !! Value
  {| class="wikitable"
|-
  |-
| '''Instrument''' || MCX Crude Oil Futures
  ! R:R Range !! Score !! Rating
|-
  |-
| '''Lot Size''' || 100 barrels
  | < 1.0 || 0 || Unacceptable
|-
  |-
| '''Tick Value''' || 1 point = Rs 100 per lot
  | [1.0, 1.5) || 40 || Poor
|-
  |-
| '''Market Hours''' || 9:00 AM - 11:30 PM IST
  | [1.5, 2.0) || 70 || Acceptable
|-
  |-
| '''Strategy Hours''' || 10:00 AM - 9:59 PM IST (blocks hours 9, 22, 23)
  | [2.0, 3.0) || 90 || Good
|}
  |-
  | >= 3.0 || 100 || Excellent
  |}


== Backtest Results ==
  === Penalties & Bonuses (Trend Strength Factor) ===
  '''Applied to Factor 2: Trend Strength'''


{| class="wikitable"
  {| class="wikitable"
|-
  |-
! Metric !! Value
  ! Condition !! Adjustment !! Trigger Field
|-
  |-
| '''Period''' || 19 months
  | Creeper Move || '''-50''' || is_creeper_move = True
|-
  |-
| '''Total Trades''' || 7,534
  | MA Struggle || '''-30''' || price_ma_struggle = True
|-
  |-
| '''Win Rate''' || 57.6%
  | No Two-Day Trend || '''-30''' || has_two_day_trend = False
|-
  |-
| '''Profit Factor''' || 1.20
  | Not Middle Phase || '''-25''' || trend_phase ≠ MIDDLE
|-
  |-
| '''Initial Capital''' || Rs 1.00 Lakhs
  | Railroad Trend || '''+15''' || is_railroad_trend = True
|-
  |}
| '''Final Value''' || Rs 26.48 Lakhs
|-
| '''Total Return''' || '''2,548%'''
|-
| '''Total Costs''' || Rs 5.93 Lakhs (brokerage + taxes)
|-
| '''Avg Holding Period''' || 2.43 hours
|}


=== Trade Distribution ===
  === Penalties & Bonuses (Entry Quality Factor) ===
  '''Applied to Factor 3: Entry Quality'''


{| class="wikitable"
  {| class="wikitable"
|-
  |-
! Category !! Count !! Percentage
  ! Condition !! Adjustment !! Trigger
|-
  |-
| colspan="3" | '''By Setup Grade'''
  | Near Key Level || '''+10''' || entry_data['near_key_level'] = True
|-
  |-
| A+ Grade || 3,457 || 45.9%
  | Not Near MA || '''-40''' || entry_data['near_ma'] = False
|-
  |-
| A Grade || 551 || 7.3%
  | Clean Entry || '''+10''' || entry_data['clean_entry'] = True
|-
  |}
| C Grade || 3,526 || 46.8%
|-
| colspan="3" | '''By Direction'''
|-
| SHORT || 6,024 || '''80.0%'''
|-
| LONG || 1,510 || 20.0%
|-
| colspan="3" | '''By Exit Reason'''
|-
| Stop (including trailing) || 5,444 || 72.3%
|-
| Target || 1,716 || 22.8%
|-
| Timeout (end of day) || 374 || 5.0%
|}


----
  === Institutional Fight Penalty (Algorithm 4) ===
  '''Philosophy''': When institutions are battling each other, don't trade.


= PART 2: THE EDGE (Why This Works) =
  * Trigger: institutional_fight_in_progress = True
  * Effect: Score × 0.7 (30% haircut)
  * Applied AFTER weighted score calculation


== Core Philosophy ==
  === A+ Criteria Enforcement (Algorithm 5) ===
  '''Philosophy''': A+ is earned, not given. Must meet ALL criteria.


The edge comes from '''requiring multiple independent confirmations''' before trading. Each layer filters out bad trades:
  To qualify for A+ (score >= 90):
  1. All timeframes aligned (timeframe_analysis.aligned = True)
  2. Entry near MA (entry_data['near_ma'] = True)
  3. Has two-day trend (market_state.has_two_day_trend = True)


{| class="wikitable"
  '''If ANY criterion fails''': Score capped at 79 (forced to B grade)
|-
! Layer !! What It Filters Out
|-
| 1. MTF Analysis || Counter-trend trades, choppy markets
|-
| 2. Market State || Dangerous conditions (creeper moves, institutional fights)
|-
| 3. Quality Grading || Scores the setup, adjusts position size
|-
| 4. Hard Filters || Wrong direction, very low grades (D/F), blocked hours
|-
| 5. Entry Technique || Chasing price far from value (MA21)
|}


== The Math ==
  === Grade Thresholds (Algorithm 6) ===
  {| class="wikitable"
  |-
  ! Grade !! Min Score !! Position Size !! Risk % !! Auto-Trade?
  |-
  | A+ || 90 || '''2 lots''' || 1.5% || Yes
  |-
  | A || 80 || 1 lot || 1.2% || Yes
  |-
  | B || 70 || 1 lot || 1.0% || No
  |-
  | C || 60 || 1 lot || 0.8% || No
  |-
  | D || 50 || 1 lot || 0.5% || No
  |-
  | F || <50 || 1 lot || 0.3% || No
  |}


If each layer has 70% accuracy independently:
  '''Note''': C/D/F grades are REJECTED by signal_generation (no trade taken).
* Single layer: 70% edge
* 2 layers: 70% × 70% = 49% of trades pass, but higher quality
* 5 layers: Only the '''best setups''' survive all filters


'''Result:''' Fewer trades, but each trade has multiple confluences supporting it.
  === Key Methods (For Developers) ===


----
  {| class="wikitable"
  |-
  ! Method !! Purpose !! Critical Notes
  |-
  | analyze() || Main orchestration || Runs all 6 algorithms in sequence
  |-
  | _calculate_factor_scores() || Calculate all 5 factors || Returns Dict with 5 scores
  |-
  | _calculate_trend_strength_score() || Factor 2 with penalties/bonuses || Most complex - many conditions
  |-
  | _calculate_risk_reward_score() || Factor 5 lookup table || EXACT boundary comparisons
  |-
  | _apply_institutional_fight_penalty() || Algorithm 4: 0.7x multiplier || Check institutional_fight_in_progress
  |-
  | _enforce_a_plus_criteria() || Algorithm 5: Cap at 79 if not qualified || 3 criteria must ALL pass
  |-
  | _assign_setup_grade() || Algorithm 6: Score → Grade || Simple threshold comparison
  |-
  | _calculate_position_sizing() || Grade → lots, risk% || TICKET-5: Realistic sizing
  |}


= PART 3: LAYER 1 - MULTI-TIMEFRAME ANALYSIS (The Foundation) =
  === Configuration Constants ===
  <code>
  # Factor Weights (MUST sum to 1.0)
  timeframe_alignment_weight = 0.30
  trend_strength_weight = 0.20
  entry_technique_weight = 0.15
  key_level_proximity_weight = 0.20
  risk_reward_weight = 0.15


<div style="background:#e6ffe6; border:1px solid #00cc00; padding:10px; margin:10px 0;">
  # Penalties
'''THIS IS THE FOUNDATION''' - Everything else builds on top of MTF alignment. If timeframes disagree, we don't trade.
  creeper_move_penalty = -50
</div>
  ma_struggle_penalty = -30
  two_day_trend_penalty = -30
  phase_mismatch_penalty = -25
  ma_distance_penalty = -40
  no_key_level_penalty = -50
  institutional_fight_multiplier = 0.7


== The 5 Timeframes ==
  # Bonuses
  railroad_trend_bonus = +15
  key_level_bonus = +10
  clean_entry_bonus = +10


{| class="wikitable"
  # Grade Thresholds
|-
  a_plus_min_score = 90
! Timeframe !! Role !! Weight
  a_min_score = 80
|-
  b_min_score = 70
| '''Daily (1D)''' || Overall market bias || Highest
  c_min_score = 60
|-
  d_min_score = 50
| '''4-Hour (4H)''' || Primary trend direction || High
  </code>
|-
| '''1-Hour (1H)''' || Trend confirmation || Medium
|-
| '''15-Minute (15M)''' || Entry timing context || Lower
|-
| '''5-Minute (5M)''' || Execution timeframe || Lowest
|}


== What We Analyze Per Timeframe ==
  === Common Debugging Questions ===
  '''Q: Why is grade capped at B (score 79) even though raw score is higher?'''
  Check A+ criteria:
  1. Is timeframe_analysis.aligned = True?
  2. Is entry_data['near_ma'] = True?
  3. Is market_state.has_two_day_trend = True?
  If ANY is False → score capped at 79.


For each of the 5 timeframes, the system calculates:
  '''Q: Why is trend_strength score so low?'''
  Check penalties applied:
  * is_creeper_move = True? (-50)
  * price_ma_struggle = True? (-30)
  * has_two_day_trend = False? (-30)
  * trend_phase ≠ MIDDLE? (-25)
  Multiple penalties can stack!


{| class="wikitable"
  '''Q: Why is position_size always 1 except for A+?'''
|-
  TICKET-5 fix: Realistic sizing for Rs 1 lakh capital.
! Analysis !! Description !! Source
  Only A+ setups get 2 lots (premium setups).
|-
| '''MA21 Value''' || 21-period Moving Average || trend_analysis_core.py
|-
| '''MA21 Slope''' || Rising/Flat/Declining || trend_analysis_core.py
|-
| '''MA200 Value''' || 200-period Moving Average || trend_analysis_core.py
|-
| '''Price vs MA21''' || Above/Below/At the MA || trend_analysis_core.py
|-
| '''Trend Direction''' || UP/DOWN/NEUTRAL || trend_analysis_core.py
|}


== MTF Alignment Score ==
   '''Q: How do I trace which penalties were applied?'''
 
   Check SetupQualityResult.penalties_applied list and analysis_comments.
<pre>
For each timeframe:
  1. Determine trend direction (UP/DOWN/NEUTRAL)
  2. Check if aligned with trade direction
  3. Apply timeframe weight
  4. Sum weighted alignment scores
 
Example (LONG trade):
   Daily:  UP (aligned)    × 1.00 weight = 1.00
  4H:    UP (aligned)    × 0.86 weight = 0.86
  1H:    UP (aligned)    × 0.72 weight = 0.72
  15M:    DOWN (not aligned) × 0.58 weight = 0.00
  5M:    UP (aligned)    × 0.44 weight = 0.44
  ─────────────────────────────────────────────
  Total MTF Score: 3.02 / 3.60 = 83.9% aligned
</pre>
 
== Why MTF Matters ==
 
{| class="wikitable"
|-
! Scenario !! MTF Alignment !! Action
|-
| All 5 timeframes aligned || 100% || '''High conviction trade'''
|-
| 4 of 5 aligned || ~85% || Trade with normal size
|-
| 3 of 5 aligned || ~70% || Proceed with caution
|-
| 2 or fewer aligned || <60% || '''Reduced quality score'''
|}
 
----
 
= PART 4: LAYER 2 - MARKET STATE ANALYSIS =
 
== The 7 Market State Algorithms ==
 
The system runs 7 independent algorithms to understand current market context:
 
{| class="wikitable"
|-
! # !! Algorithm !! What It Detects !! Impact
|-
| 1 || '''Railroad Tracks''' || Strong momentum bars in sequence || +15% bonus
|-
| 2 || '''Creeper Move''' || Slow grinding trend (dangerous) || '''-50% penalty'''
|-
| 3 || '''Two-Day Trend''' || Trend visible on Daily for 2+ days || Required for A+
|-
| 4 || '''Phase Analysis''' || Accumulation/Distribution/Markup/Markdown || Phase mismatch = -25%
|-
| 5 || '''Institutional Activity''' || Big player accumulation/distribution || Fight = 0.7× multiplier
|-
| 6 || '''Break of Structure (BOS)''' || Key level breaks || Affects stop placement
|-
| 7 || '''Volatility Regime''' || High/Normal/Low volatility || Adjusts expectations
|}
 
== Penalty System ==
 
{| class="wikitable"
|-
! Condition !! Penalty !! Rationale
|-
| Creeper Move Detected || '''-50 points''' || Slow trends often reverse suddenly
|-
| MA Struggle (price fighting MA) || -30 points || Indecision, likely to chop
|-
| No Two-Day Trend || -30 points || Trend not established enough
|-
| Phase Mismatch || -25 points || Trading against market phase
|-
| No Key Level Nearby || -50 points || No technical confluence
|-
| Institutional Fight || '''×0.70 multiplier''' || Big players fighting each other
|}
 
== Bonus System ==
 
{| class="wikitable"
|-
! Condition !! Bonus !! Rationale
|-
| Railroad Tracks || '''+15 points''' || Strong momentum confirmation
|-
| At Key Level || +10 points || Technical confluence present
|-
| Clean Entry Setup || +10 points || Clear technical pattern
|}
 
== Probability Zone Analysis ==
 
<div style="background:#e6f3ff; border:1px solid #3399ff; padding:10px; margin:10px 0;">
'''Source:''' trade_philosophy.pdf concepts implemented in probability_zone_analysis.py
</div>
 
=== The Halves & Thirds Rule ===
 
Price position within the recent range determines continuation probability:
 
{| class="wikitable"
|-
! Zone !! Position !! Continuation Probability !! Action
|-
| '''Top Third''' || >66.7% of range || '''80%''' likely to continue higher || Favor LONG
|-
| '''Top Half''' || >50% of range || '''65%''' continuation || Moderate LONG bias
|-
| '''Bottom Half''' || <50% of range || '''35%''' continuation higher || Moderate SHORT bias
|-
| '''Bottom Third''' || <33.3% of range || '''15%''' continuation ('''85% reversal''') || Favor SHORT
|}
 
=== Three-Finger Spread ===
 
Measures separation between Price, 21 MA, and 200 MA:
 
<pre>
Three-Finger Spread Detection:
  - Large spread between Price/21MA/200MA
  - Indicates profit-taking pressure imminent
  - Minimum spread threshold: 2% of price
 
Structure Types:
  UPTREND:    Price > 21 MA > 200 MA (bullish stack)
  DOWNTREND:  Price < 21 MA < 200 MA (bearish stack)
  SIDEWAYS:  No clear MA separation
</pre>
 
=== Crash Bar Detection ===
 
Identifies structural breaks via unusually large bars:
 
{| class="wikitable"
|-
! Parameter !! Value !! Meaning
|-
| crash_bar_multiplier || 2.0 || Bar must be 2× average size
|-
| crash_bar_lookback || 10 bars || Average calculated over 10 bars
|-
| crash_bar_close_threshold || 30% || Close within 30% of bar extreme
|}
 
'''Trading Rule:''' After crash bar, short the bounce back to MA21.
 
=== Pullback Classification ===
 
{| class="wikitable"
|-
! Type !! Characteristics !! Action
|-
| '''Healthy Pullback''' || 45° drift, holds above halfway point || Good entry opportunity
|-
| '''Collapse''' || Vertical drop (>60% retracement) || Avoid entry, wait for structure
|-
| '''Bounce''' || Recovery after crash bar || Short opportunity
|}
 
=== Signal Filtering ===
 
Probability zones filter signals:
 
<source lang="python">
# Source: signal_generation_trade_management.py
# Zone-based filtering (soft filter - affects score, doesn't block)
 
if zone_position < 33.3%:  # Bottom third
    # Block LONG signals (only 15% chance of continuation)
    # Allow SHORT signals
 
if zone_position > 66.7%:  # Top third
    # Allow LONG signals (80% continuation)
    # Block SHORT signals
</source>
 
<div style="background:#ffffcc; border:1px solid #ffcc00; padding:10px; margin:10px 0;">
'''Note:''' Color Change confirmation (color_change.pdf) is implemented but '''DISABLED''' in current backtest (<code>enable_color_change_filter = False</code>) as it was too restrictive.
</div>
 
----
 
= PART 5: LAYER 3 - SETUP QUALITY GRADING =
 
== The 5-Factor Scoring System ==
 
Every potential trade is scored on 5 factors:
 
{| class="wikitable"
|-
! Factor !! Weight !! What It Measures
|-
| '''Timeframe Alignment''' || '''30%''' || How well all 5 timeframes agree
|-
| '''Trend Strength''' || '''20%''' || Quality of the trend (Railroad vs Creeper)
|-
| '''Key Level Proximity''' || '''20%''' || Is entry near significant S/R level?
|-
| '''Entry Quality''' || '''15%''' || How clean is the entry technique?
|-
| '''Risk:Reward''' || '''15%''' || Is the R:R ratio favorable?
|}
 
<div style="background:#e6f3ff; border:1px solid #3399ff; padding:10px; margin:10px 0;">
'''Note:''' Weights sum to 100%. Timeframe Alignment has highest weight (30%) because MTF is the foundation.
</div>
 
== Grade Thresholds ==
 
{| class="wikitable"
|-
! Grade !! Score Range !! Action !! Position Size
|-
| '''A+''' || 90-100 || Trade with full conviction || 2 lots
|-
| '''A''' || 80-89 || Trade with confidence || 1 lot
|-
| '''B''' || 70-79 || Trade normally || 1 lot
|-
| '''C''' || 60-69 || Trade with caution || 1 lot
|-
| '''D''' || 50-59 || '''NO TRADE''' || -
|-
| '''F''' || <50 || '''NO TRADE''' || -
|}
 
<div style="background:#e6f3ff; border:1px solid #3399ff; padding:10px; margin:10px 0;">
'''Backtest Results by Grade:'''
* A+ trades: 3,457 (45.9%)
* A trades: 551 (7.3%)
* C trades: 3,526 (46.8%)
* No B-grade trades in this backtest period
</div>
 
== A+ Grade Special Requirements ==
 
To achieve A+ grade, ALL conditions must be true:
* Final score ≥ 90
* All 5 timeframes aligned with trade direction
* Entry within ±25 points of MA21
* Two-day trend present on Daily
* No institutional fight detected
 
== Score Calculation Example ==
 
<pre>
Trade Setup: LONG on 5-min chart
 
Factor Scores (0-100 each):
  Timeframe Alignment: 85  × 0.30 = 25.5
  Trend Strength:      90  × 0.20 = 18.0
  Key Level Proximity: 70  × 0.20 = 14.0
  Entry Quality:      80  × 0.15 = 12.0
  Risk:Reward:        75  × 0.15 = 11.25
                              ──────────
  Base Score:                    80.75
 
Penalties Applied:
  - No Railroad Tracks: 0
  - No Creeper: 0
  - Has Two-Day: 0
                              ──────────
  Final Score: 80.75 → Grade: A
</pre>
 
----
 
= PART 6: LAYER 4 - HARD FILTERS (The Gate) =
 
<div style="background:#ffe6e6; border:1px solid #ff0000; padding:10px; margin:10px 0;">
'''HARD FILTERS''' block trades completely. If ANY hard filter fails, NO TRADE happens regardless of how good the setup looks.
</div>
 
== The Three Hard Filters ==
 
{| class="wikitable"
|-
! Filter !! Rule !! Effect
|-
| '''1. Direction Filter''' || MA21 slope must match trade direction || Wrong direction = BLOCKED
|-
| '''2. Grade Filter''' || D/F grades blocked || D/F grades = BLOCKED (A+/A/B/C allowed)
|-
| '''3. Hour Filter''' || Block hours 9, 22, 23 || Blocked hours = BLOCKED
|}
 
== Filter 1: Direction (MA21 Slope) ==
 
{| class="wikitable"
|-
! MA21 Slope !! Allowed Direction !! Logic
|-
| '''Rising''' (↗) || LONG only || Trade with uptrend, never short
|-
| '''Declining''' (↘) || SHORT only || Trade with downtrend, never long
|-
| '''Flat''' (→) || Use MTF direction || Higher timeframes decide
|}
 
<pre>
Slope Calculation:
  Slope % = (MA21[current] - MA21[previous]) / MA21[previous] × 100
 
Thresholds:
  > +0.01%  → RISING (LONG only)
  < -0.01%  → DECLINING (SHORT only)
  ±0.01%  → FLAT (use MTF consensus)
</pre>
 
== Filter 2: Grade ==
 
{| class="wikitable"
|-
! Grade !! Action !! Position Size
|-
| A+ || '''PASS''' - High conviction || 2 lots
|-
| A || '''PASS''' - Trade with confidence || 1 lot
|-
| B || '''PASS''' - Trade normally || 1 lot
|-
| C || Trade with reduced size || 1 lot
|-
| D, F || '''BLOCKED''' - No trade || -
|}
 
<div style="background:#ffffcc; border:1px solid #ffcc00; padding:10px; margin:10px 0;">
'''Note on Backtest:''' The backtest included C-grade trades (46.8% of total). The current code has a stricter filter that blocks C/D/F grades for live trading:
</div>
 
<source lang="python">
# Source: signal_generation_trade_management.py:568 (Current Code)
if setup_quality.grade in [SetupQualityGrade.C, SetupQualityGrade.D, SetupQualityGrade.F]:
    return None  # No signal generated - trade blocked
</source>
 
== Filter 3: Hour ==
 
{| class="wikitable"
|-
! Hour !! Status !! Reason
|-
| 9 (9:00-9:59 AM) || '''BLOCKED''' || Market open volatility
|-
| 10-21 (10:00 AM - 9:59 PM) || '''ALLOWED''' || Normal trading hours
|-
| 22 (10:00-10:59 PM) || '''BLOCKED''' || Near market close
|-
| 23 (11:00-11:59 PM) || '''BLOCKED''' || Market close
|}
 
== Why 80% of Trades Were SHORT ==
 
In the backtest period, MA21 was predominantly declining:
* Market was in a sustained downtrend
* Rising MA periods were shorter/fewer
* This is '''expected behavior''' - strategy adapts to market conditions
 
----
 
= PART 7: LAYER 5 - ENTRY TECHNIQUE =
 
== The MA21 Zone Principle ==
 
<blockquote>
'''"The MA is a ZONE, not a thin line"'''
 
Entry is allowed within '''±25 points''' of MA21, not just at the exact MA value.
</blockquote>
 
== Why ±25 Points? ==
 
* Price rarely touches MA exactly
* Allows for normal market noise
* Captures the "value zone" around the average
* Based on typical Crude Oil volatility
 
== Available Entry Techniques ==
 
{| class="wikitable"
|-
! Technique !! Direction !! Description
|-
| '''NEAR_MA''' || Both || Price within ±25 pts of MA21 (most common)
|-
| MA_BOUNCE_LONG || Long || Price touches MA21 and bounces up
|-
| MA_BOUNCE_SHORT || Short || Price touches MA21 and rejects down
|-
| GREEN_BAR_AFTER_PULLBACK || Long || Bullish candle after pullback to MA
|-
| RED_BAR_AFTER_RALLY || Short || Bearish candle after rally to MA
|-
| BOS_ENTRY_LONG || Long || Break of structure to upside
|-
| BOS_ENTRY_SHORT || Short || Break of structure to downside
|}
 
== Entry Selection Logic ==
 
<source lang="python">
def select_entry_technique(price, ma21, direction, market_state):
    """
    Select best entry technique based on conditions.
    Source: signal_generation_trade_management.py
    """
    ma_distance = abs(price - ma21)
 
    # Most common: price in MA zone
    if ma_distance <= 25:  # ±25 points
        return NEAR_MA
 
    # Break of structure detected
    if market_state.has_bos:
        return BOS_ENTRY_LONG if direction == LONG else BOS_ENTRY_SHORT
 
    # Pullback/Rally pattern
    if market_state.has_pullback:
        return GREEN_BAR_AFTER_PULLBACK if direction == LONG else RED_BAR_AFTER_RALLY
 
    return NEAR_MA  # Default
</source>
 
----
 
= PART 8: STOP LOSS CALCULATION =
 
== Stop Loss Methods (Priority Order) ==
 
{| class="wikitable"
|-
! Priority !! Method !! Description
|-
| 1 || '''BOS-Based Stop''' || Below/above break of structure level
|-
| 2 || '''Swing-Based Stop''' || Below recent swing low (LONG) or above swing high (SHORT)
|-
| 3 || '''Default Stop''' || Fixed 40 points from entry
|}
 
== Minimum Stop Distance ==
 
<div style="background:#ffffcc; border:1px solid #ffcc00; padding:10px; margin:10px 0;">
'''MINIMUM: 40 points''' - Stops closer than 40 points are automatically widened to 40.
</div>
 
This prevents:
* Getting stopped out by normal noise
* Excessive trading costs from tight stops
* Whipsaws in volatile Crude Oil market
 
== Stop Calculation Algorithm ==
 
<source lang="python">
def calculate_stop_loss(entry_price, direction, market_state):
    """
    Calculate stop loss with minimum enforcement.
    Source: signal_generation_trade_management.py
    """
    MIN_STOP_DISTANCE = 40.0  # points
 
    # Try BOS-based stop first
    if market_state.bos_level:
        stop = market_state.bos_level - 5  # 5pt buffer
 
    # Try swing-based stop
    elif market_state.swing_low and direction == LONG:
        stop = market_state.swing_low - 5
 
    # Default stop
    else:
        if direction == LONG:
            stop = entry_price - MIN_STOP_DISTANCE
        else:
            stop = entry_price + MIN_STOP_DISTANCE
 
    # ENFORCE MINIMUM
    actual_distance = abs(entry_price - stop)
    if actual_distance < MIN_STOP_DISTANCE:
        if direction == LONG:
            stop = entry_price - MIN_STOP_DISTANCE
        else:
            stop = entry_price + MIN_STOP_DISTANCE
 
    return stop
</source>
 
----
 
= PART 9: TARGET CALCULATION =
 
== The 50% Rule ==
 
<div style="background:#e6f3ff; border:1px solid #3399ff; padding:10px; margin:10px 0;">
'''Target = 50% of distance to MA21'''
 
For mean reversion trades, we target halfway back to the moving average.
</div>
 
== Why 50%? ==
 
* Conservative target ensures higher hit rate
* Based on "divide the move in half" principle
* Captures partial reversion without being greedy
* Works well with trailing stop to capture more
 
== Minimum Target Rule ==
 
<pre>
Minimum Target = Risk × 1.5
 
Example:
  Entry: 5700
  Stop: 5660 (40 points risk)
 
  50% to MA might give: 30 points
  But minimum is: 40 × 1.5 = 60 points
 
  Final Target: 5760 (60 points)
</pre>
 
== Target Calculation ==
 
<source lang="python">
def calculate_target(entry_price, stop_price, ma21, direction):
    """
    PDF-based target: 50% of distance to MA, with minimum.
    Source: signal_generation_trade_management.py
    """
    risk_distance = abs(entry_price - stop_price)
    min_target = risk_distance * 1.5  # Minimum 1.5:1 R:R
 
    # Calculate 50% move toward MA
    distance_to_ma = abs(entry_price - ma21)
    target_distance = distance_to_ma * 0.5
 
    # Enforce minimum
    target_distance = max(target_distance, min_target)
 
    if direction == LONG:
        return entry_price + target_distance
    else:
        return entry_price - target_distance
</source>
 
----
 
= PART 10: DYNAMIC STOP MANAGEMENT =
 
== Two-Phase Protection ==
 
After entry, stops are managed dynamically in two phases:
 
{| class="wikitable"
|-
! Phase !! Trigger !! Action
|-
| '''Phase 1: Breakeven''' || +25 points profit || Move stop to entry + 2 points
|-
| '''Phase 2: Trailing''' || +20 points profit || Trail stop using ATR × 2
|}
 
== Phase 1: Breakeven Stop ==
 
<pre>
Configuration:
   breakeven_activation = 25 points
  breakeven_buffer = 2 points
 
Example (LONG from 5700):
  Price reaches 5725 (+25 pts profit)
  → Stop moves from 5660 to 5702 (entry + 2)
  → Trade is now "risk-free"
</pre>
 
== Phase 2: Trailing Stop ==
 
<pre>
Configuration:
  trailing_stop_activation = 20 points
  trailing_stop_method = ATR_MULTIPLE
  atr_period = 14 bars
  atr_multiplier = 2.0
  minimum_trail_distance = 15 points
 
Example (LONG from 5700, ATR = 12):
  Trailing Distance = 12 × 2 = 24 points
 
  Price at 5740:
  → Trail stop = 5740 - 24 = 5716
 
  Price at 5760:
  → Trail stop = 5760 - 24 = 5736 (moved UP)
 
  Price drops to 5736:
  → STOPPED OUT at 5736 (profit locked)
</pre>
 
== Why Both Phases? ==
 
{| class="wikitable"
|-
! Phase !! Purpose
|-
| Breakeven || Eliminate risk quickly once trade moves in favor
|-
| Trailing || Let winners run while protecting accumulated profit
|}
 
----
 
= PART 11: SLIPPAGE & COSTS =
 
== Realistic Slippage Model ==
 
{| class="wikitable"
|-
! Event !! Slippage !! Rationale
|-
| '''Entry''' || +1.0 point || Normal market fill
|-
| '''Stop Loss Exit''' || +2.0 points || Stops slip more in fast moves
|-
| '''Target Exit''' || +0.5 points || Limit orders have minimal slippage
|}
 
== Cost Structure ==
 
{| class="wikitable"
|-
! Cost Type !! Value
|-
| Commission || Rs 20 per lot per side
|-
| STT || 0.01% on sell side
|-
| Exchange Fees || ~Rs 2 per lot
|-
| Stamp Duty || State-dependent
|}
 
== Why Model Slippage? ==
 
* Backtest results must reflect real trading
* Prevents over-optimistic performance estimates
* Stop loss slippage is higher because stops often trigger during fast moves
* Total costs ~Rs 79 per round-trip lot
 
----
 
= PART 12: EXIT RULES =
 
== Three Exit Conditions ==
 
{| class="wikitable"
|-
! Exit Type !! Condition !! % of Exits
|-
| '''Stop Loss''' || Price hits stop (original or trailing) || 72.3%
|-
| '''Target''' || Price hits take profit level || 22.8%
|-
| '''Timeout''' || End of day (no overnight holds) || 5.0%
|}
 
== Why 72% Stop Exits but 57% Win Rate? ==
 
This seems contradictory but makes sense:
* '''Trailing stops lock in profits''' - many "stop exits" are actually winning trades
* Breakeven stops trigger at +25 pts, trailing at +20 pts
* A trade can be stopped out at +30 pts profit (counted as stop exit but is a WIN)
 
== End-of-Day Exit ==
 
<pre>
All positions closed before market close:
  - Market closes at 11:30 PM IST
  - 15-minute buffer before close
  - Prevents overnight gap risk
</pre>
 
----
 
= PART 13: PUTTING IT ALL TOGETHER =
 
== Trade Flow ==
 
<pre>
┌─────────────────────────────────────────────────────────────────┐
│  STEP 1: Load data for all 5 timeframes                        │
│  Daily, 4H, 1H, 15M, 5M OHLCV data                            │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 2: LAYER 1 - MTF Analysis (Foundation)                    │
│  Calculate MA21, MA200, trend direction for each timeframe      │
│  Compute MTF alignment score                                    │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 3: LAYER 2 - Market State Analysis                        │
│  Run 7 algorithms: Railroad, Creeper, Phase, BOS, etc.          │
│  Calculate penalties and bonuses                                │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 4: LAYER 3 - Setup Quality Grading                        │
│  Score 5 factors, apply penalties/bonuses                      │
│  Assign grade: A+ / A / B / C / D / F                          │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 5: LAYER 4 - HARD FILTERS (The Gate)  ◄── PASS/FAIL      │
│  • Direction: MA21 slope matches trade direction?              │
│  • Grade: Is grade A+, A, B, or C? (D/F blocked)                │
│  • Hour: Is current hour allowed (not 9, 22, 23)?              │
│  ANY FAIL → NO TRADE                                            │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 6: LAYER 5 - Entry Technique                              │
│  Is price within ±25 points of MA21?                            │
│  Select entry technique (NEAR_MA, BOS_ENTRY, etc.)              │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 7: Calculate Stop Loss                                    │
│  BOS-based → Swing-based → Default (40 pts minimum)            │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 8: Calculate Target                                      │
│  50% of distance to MA (minimum 1.5× risk)                      │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 9: Execute Trade                                          │
│  Apply entry slippage (+1 pt), create trade record              │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│  STEP 10: Manage Trade                                          │
│  Monitor: Breakeven at +25 pts → Trail at +20 pts              │
│  Exit: Stop hit | Target hit | Timeout                          │
└─────────────────────────────────────────────────────────────────┘
</pre>
 
----
 
= PART 14: HARD vs SOFT FILTERS =
 
== Understanding the Difference ==
 
{| class="wikitable"
|-
! Filter Type !! Behavior !! Examples
|-
| '''HARD''' || Blocks trade completely || Direction filter, Hour filter, Grade D/F
|-
| '''SOFT''' || Affects quality score || MTF alignment, Market state penalties
|}
 
== Complete Filter List ==
 
{| class="wikitable"
|-
! Filter !! Type !! Effect
|-
| MA21 Direction || '''HARD''' || Wrong direction = NO TRADE
|-
| Hour Filter || '''HARD''' || Hours 9, 22, 23 = NO TRADE
|-
| Grade D/F || '''HARD''' || D/F grades = NO TRADE
|-
| MTF Alignment || SOFT || Low alignment = reduced score (30% weight)
|-
| Creeper Move || SOFT || -50 points penalty
|-
| No Two-Day Trend || SOFT || -30 points penalty
|-
| Institutional Fight || SOFT || 0.7× score multiplier
|-
| Far from MA21 || SOFT || -40 points penalty
|}
 
----
 
= APPENDIX A: CONFIGURATION VALUES =
 
== MTF Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File !! Description
|-
| context_timeframe || DAILY || main.py:162 || Highest timeframe for overall bias
|-
| primary_timeframe || 1-HOUR || main.py:163 || Primary trend direction
|-
| confirmation_timeframe || 15-MIN || main.py:164 || Entry timing confirmation
|-
| entry_timeframe || 5-MIN || main.py:165 || Execution timeframe
|-
| require_all_timeframes_aligned || '''False''' || main.py:166 || Allow partial alignment
|-
| min_alignment_score || '''0.70 (70%)''' || main.py:167 || Minimum MTF alignment score
|-
| wait_for_15min_alignment || '''True''' || main.py:168 || Wait for 15M confirmation
|-
| min_15min_confirmation_bars || '''2 bars''' || main.py:169 || Bars needed for 15M confirmation
|}
 
== Entry Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| entry_timeframe || 5-Minute || main.py:165
|-
| ma_buffer_points || 25 points || signal_generation_trade_management.py:68
|-
| blocked_hours || [9, 22, 23] || signal_generation_trade_management.py:137
|-
| enable_hour_filter || True || signal_generation_trade_management.py:89
|-
| enable_ma_direction_filter || True || signal_generation_trade_management.py:97
|}
 
== Stop/Target Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| min_stop_distance || 40 points || signal_generation_trade_management.py:59
|-
| default_risk_reward || 1.5 || signal_generation_trade_management.py:62
|-
| bos_stop_buffer_points || 5 points || signal_generation_trade_management.py:81
|}
 
== Dynamic Stop Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| enable_trailing_stop || True || trade_execution_engine.py:58
|-
| trailing_stop_method || ATR_MULTIPLE || trade_execution_engine.py:63
|-
| atr_period || 14 bars || trade_execution_engine.py:64
|-
| atr_multiplier || 2.0 || trade_execution_engine.py:65
|-
| trailing_stop_activation || 20 points || trade_execution_engine.py:60
|-
| enable_breakeven_stop || True || trade_execution_engine.py:69
|-
| breakeven_activation || 25 points || trade_execution_engine.py:70
|-
| breakeven_buffer || 2 points || trade_execution_engine.py:71
|-
| minimum_trail_distance || 15 points || trade_execution_engine.py:370
|}
 
== Slippage Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| base_slippage_points || 1.0 point || trade_execution_engine.py:38
|-
| volatility_slippage_factor || 0.5 || trade_execution_engine.py:39
|-
| market_impact_factor || 0.1 || trade_execution_engine.py:40
|-
| max_market_impact_slippage || 2.0 points || trade_execution_engine.py:43
|-
| stop_loss_slippage || 2.0 points || trade_execution_engine.py:50
|-
| take_profit_slippage || 0.5 points || trade_execution_engine.py:51
|}
 
== Trade Execution Limits ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File !! Description
|-
| max_holding_period_minutes || '''480 (8 hours)''' || trade_execution_engine.py:46 || Maximum time a trade can stay open
|-
| min_holding_period_minutes || '''5 minutes''' || trade_execution_engine.py:47 || Minimum holding before exit
|-
| max_position_size || '''200 lots''' || trade_execution_engine.py:54 || Maximum lots per single trade
|-
| max_concurrent_trades || '''3''' || trade_execution_engine.py:55 || Maximum simultaneous open trades
|-
| market_close_buffer_minutes || '''15 minutes''' || trade_execution_engine.py:75 || Close trades before market close
|-
| avoid_news_minutes || 30 minutes || trade_execution_engine.py:74 || Buffer around news events
|}
 
== Cost Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File !! Description
|-
| commission_per_lot || '''Rs 20/lot/leg''' || signal_generation_trade_management.py:49 || Dhan broker commission
|-
| transaction_tax_rate || '''0.005% per leg''' || signal_generation_trade_management.py:55 || CTT (0.01% round-trip)
|-
| lot_size_multiplier || '''100 barrels''' || signal_generation_trade_management.py:56 || MCX Crude lot size
|-
| initial_capital || '''Rs 1,00,000''' || main.py:1131 || Starting capital for backtest
|}
 
== Grading Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| timeframe_alignment_weight || 30% || setup_quality_detection.py:44
|-
| trend_strength_weight || 20% || setup_quality_detection.py:45
|-
| key_level_proximity_weight || 20% || setup_quality_detection.py:47
|-
| entry_technique_weight || 15% || setup_quality_detection.py:46
|-
| risk_reward_weight || 15% || setup_quality_detection.py:48
|-
| a_plus_min_score || 90 || setup_quality_detection.py:51
|-
| a_min_score || 80 || setup_quality_detection.py:52
|-
| b_min_score || 70 || setup_quality_detection.py:53
|}
 
== Probability Zone Configuration ==
 
{| class="wikitable"
|-
! Parameter !! Value !! Source File
|-
| enable_probability_zone_filter || True || signal_generation_trade_management.py:104
|-
| probability_zone_swing_lookback || 20 bars || signal_generation_trade_management.py:105
|-
| probability_zone_min_range || 20 points || signal_generation_trade_management.py:106
|-
| top_third_threshold || 66.7% || probability_zone_analysis.py:125
|-
| top_third_probability || 80% || probability_zone_analysis.py:131
|-
| bottom_third_probability || 15% || probability_zone_analysis.py:134
|-
| crash_bar_multiplier || 2.0 || probability_zone_analysis.py:145
|-
| three_finger_min_spread_pct || 2% || probability_zone_analysis.py:141
|-
| enable_color_change_filter || '''False''' (disabled) || signal_generation_trade_management.py:115
|}
 
----
 
= APPENDIX B: SOURCE CODE REFERENCE =
 
{| class="wikitable"
|-
! File !! Purpose
|-
| <code>main.py</code> || Entry point, timeframe configuration
|-
| <code>trend_analysis_core.py</code> || MA calculation, slope detection, trend direction
|-
| <code>multi_timeframe_analysis.py</code> || MTF alignment scoring across 5 timeframes
|-
| <code>market_state_analysis.py</code> || 7 market state detection algorithms
|-
| <code>setup_quality_detection.py</code> || 5-factor grading system with penalties/bonuses
|-
| <code>probability_zone_analysis.py</code> || Halves/Thirds, Three-Finger Spread, Crash Bar
|-
| <code>signal_generation_trade_management.py</code> || Entry/Exit logic, stop/target calculation
|-
| <code>trade_execution_engine.py</code> || Breakeven, Trailing stop, Slippage modeling
|-
| <code>data_manager.py</code> || OHLCV data loading and management
|-
| <code>backtesting_analytics.py</code> || Performance metrics (Sharpe, Sortino, VaR, drawdown)
|}
 
----
 
''Document generated from source code analysis - January 2026''
 
''Strategy: Multi-Layer Confluence (MLC) v1.0''
 
[[Category:Trading Strategies]]
[[Category:Systematic Trading]]
[[Category:MCX Crude Oil]]

Latest revision as of 15:08, 7 January 2026

 == Component: setup_quality_detection.py ==
 === Purpose (Trading Context) ===
 The Grader - This component answers: "How good is this trading setup?"
 Think of it like a teacher grading an exam: Each setup is scored on 5 factors, penalties are applied for bad conditions, and a final grade (A+ to F) is assigned. The grade determines position size and whether we should trade at all.
 Key Philosophy: Not all setups are equal. A+ setups get bigger positions. C/D/F setups are rejected by signal generation.
 === What It Does (Simple Terms) ===
 1. Receives analyzed data from upstream components
 2. Scores each setup on 5 weighted factors (0-100 each)
 3. Applies penalties for adverse market conditions (creeper, MA struggle, etc.)
 4. Caps score if A+ criteria not met
 5. Assigns letter grade (A+ to F)
 6. Recommends position size based on grade
 === Inputs ===
Input Source What It Provides
timeframe_analysis multi_timeframe_analysis.py Alignment score, aligned flag
market_state market_state_analysis.py Creeper move, MA struggle, railroad trend, trend phase, institutional fight
entry_data Calculated in main.py near_key_level, near_ma, clean_entry, risk_reward
strategy_config Configuration Strategy ID
timestamp Current bar Timestamp for logging
 === Outputs (SetupQualityResult) ===
Field Type Description
grade SetupQualityGrade A+, A, B, C, D, or F
score float 0-100 final score after all penalties
factor_scores Dict Individual scores for each of 5 factors
position_size int Recommended lots (1 or 2)
risk_percent float Risk % based on grade
can_auto_trade bool Only A+ and A are auto-tradeable
 === The 5-Factor Scoring System ===
 Total Weight = 100% (must sum to exactly 1.0)
Factor Weight What It Measures Calculation
Timeframe Alignment 30% Are all timeframes pointing same direction? alignment_score × 100
Trend Strength 20% Is trend healthy? 100 - penalties + bonuses
Entry Quality 15% Is entry at a good spot? 100 + bonuses - penalties
Key Level Proximity 20% Is price near important level? 100 - 50 if not near key level
Risk/Reward 15% Is R:R acceptable? Lookup table (see below)
 === Risk/Reward Scoring Table ===
 EXACT boundaries from specification:
R:R Range Score Rating
< 1.0 0 Unacceptable
[1.0, 1.5) 40 Poor
[1.5, 2.0) 70 Acceptable
[2.0, 3.0) 90 Good
>= 3.0 100 Excellent
 === Penalties & Bonuses (Trend Strength Factor) ===
 Applied to Factor 2: Trend Strength
Condition Adjustment Trigger Field
Creeper Move -50 is_creeper_move = True
MA Struggle -30 price_ma_struggle = True
No Two-Day Trend -30 has_two_day_trend = False
Not Middle Phase -25 trend_phase ≠ MIDDLE
Railroad Trend +15 is_railroad_trend = True
 === Penalties & Bonuses (Entry Quality Factor) ===
 Applied to Factor 3: Entry Quality
Condition Adjustment Trigger
Near Key Level +10 entry_data['near_key_level'] = True
Not Near MA -40 entry_data['near_ma'] = False
Clean Entry +10 entry_data['clean_entry'] = True
 === Institutional Fight Penalty (Algorithm 4) ===
 Philosophy: When institutions are battling each other, don't trade.
 * Trigger: institutional_fight_in_progress = True
 * Effect: Score × 0.7 (30% haircut)
 * Applied AFTER weighted score calculation
 === A+ Criteria Enforcement (Algorithm 5) ===
 Philosophy: A+ is earned, not given. Must meet ALL criteria.
 To qualify for A+ (score >= 90):
 1. All timeframes aligned (timeframe_analysis.aligned = True)
 2. Entry near MA (entry_data['near_ma'] = True)
 3. Has two-day trend (market_state.has_two_day_trend = True)
 If ANY criterion fails: Score capped at 79 (forced to B grade)
 === Grade Thresholds (Algorithm 6) ===
Grade Min Score Position Size Risk % Auto-Trade?
A+ 90 2 lots 1.5% Yes
A 80 1 lot 1.2% Yes
B 70 1 lot 1.0% No
C 60 1 lot 0.8% No
D 50 1 lot 0.5% No
F <50 1 lot 0.3% No
 Note: C/D/F grades are REJECTED by signal_generation (no trade taken).
 === Key Methods (For Developers) ===
Method Purpose Critical Notes
analyze() Main orchestration Runs all 6 algorithms in sequence
_calculate_factor_scores() Calculate all 5 factors Returns Dict with 5 scores
_calculate_trend_strength_score() Factor 2 with penalties/bonuses Most complex - many conditions
_calculate_risk_reward_score() Factor 5 lookup table EXACT boundary comparisons
_apply_institutional_fight_penalty() Algorithm 4: 0.7x multiplier Check institutional_fight_in_progress
_enforce_a_plus_criteria() Algorithm 5: Cap at 79 if not qualified 3 criteria must ALL pass
_assign_setup_grade() Algorithm 6: Score → Grade Simple threshold comparison
_calculate_position_sizing() Grade → lots, risk% TICKET-5: Realistic sizing
 === Configuration Constants ===
 
 # Factor Weights (MUST sum to 1.0)
 timeframe_alignment_weight = 0.30
 trend_strength_weight = 0.20
 entry_technique_weight = 0.15
 key_level_proximity_weight = 0.20
 risk_reward_weight = 0.15
 # Penalties
 creeper_move_penalty = -50
 ma_struggle_penalty = -30
 two_day_trend_penalty = -30
 phase_mismatch_penalty = -25
 ma_distance_penalty = -40
 no_key_level_penalty = -50
 institutional_fight_multiplier = 0.7
 # Bonuses
 railroad_trend_bonus = +15
 key_level_bonus = +10
 clean_entry_bonus = +10
 # Grade Thresholds
 a_plus_min_score = 90
 a_min_score = 80
 b_min_score = 70
 c_min_score = 60
 d_min_score = 50
 
 === Common Debugging Questions ===
 Q: Why is grade capped at B (score 79) even though raw score is higher?
 Check A+ criteria:
 1. Is timeframe_analysis.aligned = True?
 2. Is entry_data['near_ma'] = True?
 3. Is market_state.has_two_day_trend = True?
 If ANY is False → score capped at 79.
 Q: Why is trend_strength score so low?
 Check penalties applied:
 * is_creeper_move = True? (-50)
 * price_ma_struggle = True? (-30)
 * has_two_day_trend = False? (-30)
 * trend_phase ≠ MIDDLE? (-25)
 Multiple penalties can stack!
 Q: Why is position_size always 1 except for A+?
 TICKET-5 fix: Realistic sizing for Rs 1 lakh capital.
 Only A+ setups get 2 lots (premium setups).
 Q: How do I trace which penalties were applied?
 Check SetupQualityResult.penalties_applied list and analysis_comments.