Jump to content

Alpha Research: Difference between revisions

From PlusEV Wiki Page
No edit summary
Blanked the page
Tags: Blanking Manual revert
Line 1: Line 1:
= Alpha Research: MCX Crude Oil MA21 Strategy =


'''Single Source of Truth for the PlusEV Trading System'''
----
== Quick Reference: Backtest Proof ==
{| class="wikitable"
! Metric !! Value !! Notes
|-
| '''Total P&L''' || Rs +25,48,101 || 19-month validation period
|-
| '''Win Rate''' || 57.6% || Above 55% threshold
|-
| '''Profit Factor''' || 1.20 || Risk-adjusted returns
|-
| '''Total Trades''' || 7,534 || Statistical significance
|-
| '''Initial Capital''' || Rs 1,00,000 || Starting portfolio
|-
| '''Final Capital''' || Rs 26,48,101 || 2548% return
|}
'''Branch''': <code>rikk_mtf_backtest001</code> | '''Commit''': <code>68dae212</code>
<blockquote>''In trading systems, empirical results > theoretical understanding. If the backtest shows it works, we ship it.''</blockquote>
----
= Part 1: Core Trading Philosophy =
== 1.1 Foundational Principles ==
<pre>
Simple systems outperform complex ones.
Market behavior is probabilistic, not predictive.
The goal is positioning with asymmetric probabilities, not prediction.
</pre>
=== The Asymmetric Probability Edge ===
When odds are low on one outcome, '''the opposite side usually carries high odds''':
* If new high probability drops to 15%, then '''85% odds favor reversal'''
* We position ourselves on the high-probability side
----
== 1.2 Probability Zones (Halves & Thirds) ==
Every large move is divided into '''halves and thirds''', creating probability zones.
=== Odds of Continuation After Pullback ===
<pre>
┌─────────────────────────────────────────────────────┐
│  SWING HIGH                                        │
├─────────────────────────────────────────────────────┤
│  TOP THIRD        →  ~80% chance of new high        │  ← IDEAL SHORT ZONE
├─────────────────────────────────────────────────────┤
│  TOP HALF        →  ~65% chance of new high        │
├─────────────────────────────────────────────────────┤
│  BOTTOM HALF      →  ~35% chance of new high        │
├─────────────────────────────────────────────────────┤
│  BOTTOM THIRD    →  ~15% chance of new high        │  ← IDEAL LONG ZONE
├─────────────────────────────────────────────────────┤
│  SWING LOW                                          │
└─────────────────────────────────────────────────────┘
</pre>
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:99-109
enable_probability_zone_filter: bool = True
probability_zone_swing_lookback: int = 20    # Bars to find swing H/L
probability_zone_min_range: float = 20.0    # Min range for valid zone
</source>
----
== 1.3 The Crash Play (Core Strategy) ==
=== What is a Crash Bar? ===
* '''Much larger''' than recent bars
* '''Fast, violent, elongated''' movement
* Indicates a '''structural break'''
=== The Crash Play Logic ===
<pre>
1. Identify crash bar (bar > 2x average size)
2. Divide it into halves and thirds
3. Watch for bounce INTO these zones
4. Enter when:
  - Color change confirms (red overtakes green), OR
  - Price reaches upper zones
</pre>
=== Key Statistics ===
* After a crash, bounces have only '''~15% odds''' of reclaiming highs
* '''~85% odds''' favor continuation lower
* '''Bounces after crashes are statistically SHORT opportunities'''
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:108
crash_bar_multiplier: float = 2.0  # Bar must be 2x average for crash detection
</source>
----
== 1.4 Pullback vs Collapse (Critical Distinction) ==
=== Healthy Pullback (Tradeable) ===
{| class="wikitable"
! Characteristic !! Description
|-
| Angle || 45-degree drifting decline, NOT vertical
|-
| Bars || No violent or oversized red bars
|-
| Depth || Holds '''above halfway point''' of prior run
|-
| Confirmation || Color change (green overtakes red)
|}
'''Interpretation''': Pullbacks are rests, not reversals. Odds favor continuation.
=== Collapse (NOT Tradeable) ===
{| class="wikitable"
! Characteristic !! Description
|-
| Angle || Vertical, elongated, violent first drop
|-
| Depth || Breaks deeply into or below prior run
|-
| Momentum || Abrupt and forceful
|}
'''Interpretation''': Indicates institutional selling. Bounces are sucker plays.
----
== 1.5 Identifying Market Tops (4 Characteristics) ==
Major tops usually exhibit '''at least 2 of these 4 characteristics''':
=== 1. Three-to-Five Leg Run-Up ===
<pre>
Markets top between leg 3 and leg 5.
- Buy: legs 1-2
- Ride: leg 3
- Take profits: legs 4-5
- Buying late (leg 4-5) = large downside vs small upside
</pre>
=== 2. Vertical Acceleration in Final Leg ===
<pre>
If the last leg is STEEPER than prior legs → likely final leg
The most vertical leg is usually the top.
</pre>
=== 3. Exhaustion Bar ===
<pre>
Final bar of final leg is:
- Larger than recent bars
- Often the largest bar of entire run
= Bulls deploy all remaining buying power
= Market becomes top-heavy and vulnerable
</pre>
=== 4. Three-Finger Spread (Dual Space) ===
<pre>
Large separation between:
- Price
- 21-period MA
- 200-period MA
= Many traders holding large unrealized profits
= Any red bar can trigger mass profit-taking
= Creates fast, violent declines
</pre>
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:107
three_finger_spread_threshold: float = 0.02  # 2% min spread for detection
</source>
----
= Part 2: Entry Methodology =
== 2.1 The Fab Four Concept ==
The '''Fab Four''' defines the key reference points for entries and stops:
<pre>
┌─────────────────────────────────────────────────────┐
│  FAB FOUR ELEMENTS                                  │
├─────────────────────────────────────────────────────┤
│  1. Previous Day High/Low (PDHL)                    │
│  2. 21-Period Moving Average                        │
│  3. 200-Period Moving Average                      │
│  4. Yesterday's Close                              │
└─────────────────────────────────────────────────────┘
</pre>
=== MA is a ZONE, Not a Line ===
<blockquote>''The MA is a zone, not a thin line. Don't be exact with this.''</blockquote>
<source lang="python">
# File: signal_generation_trade_management.py:68
ma_buffer_points: float = 25.0  # 21 MA zone width (not a thin line)
</source>
=== Fab Four Tightness = Explosive Potential ===
When the Fab Four elements are '''tight together''':
* Indicates compressed energy
* Expect '''powerful move''' (up or down)
* Best trades come from '''narrowness'''
----
== 2.2 Entry Position Hierarchy ==
=== Best Entry Positions ===
<pre>
FOR SHORTS:
┌─────────────────────────────────────────────────────┐
│  CEILING (Best short position)                      │
│  ═══════════════════════════════════════════        │  ← Price right under Fab Four
│  Price opens HERE                                  │
└─────────────────────────────────────────────────────┘
FOR LONGS:
┌─────────────────────────────────────────────────────┐
│  Price opens HERE                                  │
│  ═══════════════════════════════════════════        │  ← Price right above Fab Four
│  FLOOR (Best long position)                        │
└─────────────────────────────────────────────────────┘
</pre>
=== Multi-Timeframe Alignment ===
Check all timeframes simultaneously:
<pre>
┌────────┬────────┬────────┬────────┐
│  2min  │  5min  │  15min │  Daily │
│  ────  │  ────  │  ────  │  ────  │
│ Under  │ Under  │ Under  │ Under  │
│  200  │  200  │  200  │  200  │
│ Tight  │ Tight  │ Tight  │ Tight  │
└────────┴────────┴────────┴────────┘
        = ALIGNED = HIGH QUALITY SETUP
</pre>
=== Code Implementation ===
<source lang="python">
# File: setup_quality_detection.py:43-48
timeframe_alignment_weight: float = 0.30  # 30% of setup quality score
</source>
----
== 2.3 Bar-by-Bar vs Big Bar Stops ==
=== The Rule ===
{| class="wikitable"
! When to Use !! Stop Method !! Why
|-
| '''Near MA''' (hugging) || Big Bar stops || Eliminates noise
|-
| '''Far from MA''' (extended) || Bar-by-bar stops || Protect extended gains
|}
=== The Warning ===
<blockquote>''Bar-by-bar will knock you out of riches. If there is one stopout that is going to knock you out of the biggest gains of your life, it's going to be bar-by-bar.''</blockquote>
'''Use bar-by-bar ONLY when:'''
* Price has moved significantly away from MA
* "You had better be moving to Pluto"
* Slant on both 2min and 5min is sharp
----
= Part 3: Stop Loss Methodology =
== 3.1 Stop Placement Hierarchy ==
=== Two Stop Options ===
{| class="wikitable"
! Type !! Description !! When to Use
|-
| '''Event Stop''' || Based on price action event || Primary choice
|-
| '''Maximum Stop''' || Dollar-based max loss || Fallback when event too far
|}
=== The Goal ===
<pre>
┌─────────────────────────────────────────────────────┐
│  FAB FOUR ZONE (Helping Zone)                      │
├─────────────────────────────────────────────────────┤
│  ↑ STOP SHOULD BE HERE (above/below Fab Four)      │
├─────────────────────────────────────────────────────┤
│  Entry price                                        │
└─────────────────────────────────────────────────────┘
</pre>
<blockquote>''The real goal is to get your stop beyond the Fab Four helping zone.''</blockquote>
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:59-60
min_stop_distance: float = 40.0    # TICKET-13: Increased from 20
default_stop_distance: float = 40.0  # Minimum buffer for price noise
</source>
----
== 3.2 Stop and Reverse Rules ==
Three criteria for a valid '''Stop and Reverse''':
{| class="wikitable"
! Criteria !! Description
|-
| '''1. Immediate''' || Stop out happens INSTANTLY, not gradually
|-
| '''2. Violent''' || Move that stops you is hard, powerful, shakes earth
|-
| '''3. Decent Position''' || New position is NOT into resistance/support
|}
=== Invalid Stop and Reverse ===
<pre>
❌ Going LONG right INTO the 200 MA
❌ Going LONG right INTO tight Fab Four zone
❌ Going SHORT right INTO strong support
Even if immediate + violent, bad position = no reversal
</pre>
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:80-81
bos_structure_lookback: int = 10  # TICKET-11: Extended for BOS stops
bos_stop_buffer_points: float = 5.0  # Buffer for structure-based stops
</source>
----
= Part 4: Color Change Confirmation =
== 4.1 The Color Change Entry ==
=== Entry Trigger ===
<pre>
FOR SHORTS:
Red bar closes BELOW green bar's low → ENTER SHORT
Stop: Above the high
FOR LONGS:
Green bar closes ABOVE red bar's high → ENTER LONG
Stop: Below the low
</pre>
=== Key Rule: Don't Wait for Bar to Complete ===
<blockquote>''As soon as the red bar crosses below the green, boom boom boom boom boom. You're in.''</blockquote>
----
== 4.2 Profit Taking Rules ==
=== The Two-Bar Rule ===
<blockquote>''Take profits TWO bars after the opposite color, NOT one bar.''</blockquote>
<pre>
SHORT TRADE:
┌─────────────────────────────────────────────────────┐
│  GREEN bar (opposite color)                        │
├─────────────────────────────────────────────────────┤
│  RED bar 1 ← IGNITING bar (DO NOT take profit)      │
├─────────────────────────────────────────────────────┤
│  RED bar 2 ← FOLLOW-THROUGH bar (TAKE PROFIT)      │
└─────────────────────────────────────────────────────┘
</pre>
=== Position Management Flow ===
<pre>
Step 1: Enter with 2 lots
Step 2: Set stop above high
Step 3: Take profit on 1 lot (first follow-through bar)
Step 4: Move stop to break-even
Step 5: Take profit on remaining lot (second follow-through)
Step 6: Done
</pre>
<blockquote>''The first lot is your REAL trade. The second lot is the cherry on top.''</blockquote>
=== Code Implementation ===
<source lang="python">
# File: signal_generation_trade_management.py:111-118
enable_color_change_filter: bool = False    # DISABLED - too restrictive
color_change_ma_proximity: float = 20.0      # Points to consider "near" MA
require_ma_bounce: bool = False              # Don't require strict MA bounce
</source>
----
== 4.3 The Traffic Jam Concept ==
When price gaps below '''everything from prior day''':
<pre>
┌─────────────────────────────────────────────────────┐
│  Yesterday's 200 MA                                │
│  Yesterday's 20 MA                                  │
│  Yesterday's Close                                  │
│  ═══════════════════════════════════════════        │
│  TRAFFIC JAM ZONE (resistance on any rally)        │
│  ═══════════════════════════════════════════        │
│                                                    │
│  TODAY'S GAP DOWN OPEN                              │
└─────────────────────────────────────────────────────┘
</pre>
'''Rule''': Any move UP into the traffic jam meets resistance. Short rallies into this zone.
----
= Part 5: Trading Glossary for Engineers =
{| class="wikitable"
! Trading Term !! System Translation !! Code Location !! Why It Matters
|-
| '''Creeper Move''' || Small-bodied bars, consistent direction, low volume || <code>market_state_analysis.py:is_creeper_move</code> || Institutional accumulation before explosion. '''PENALTY: -50 points'''
|-
| '''Railroad Trend''' || Alternating green/red bars touching MA || <code>market_state_analysis.py:is_railroad_trend</code> || Healthy trend, not overextended. '''BONUS: +15 points'''
|-
| '''Two-Day Trend''' || Price consistently above/below MA for 2+ days || <code>market_state_analysis.py:has_two_day_trend</code> || Confirms trend maturity. '''Required for A+ grade'''
|-
| '''Institutional Fight''' || High volume with narrow range || <code>market_state_analysis.py:institutional_fight_in_progress</code> || Buyers vs sellers battle. '''MULTIPLIER: 0.7x score'''
|-
| '''Discount Zone''' || Price below 21 MA (for longs) || <code>probability_zone_analysis.py</code> || 80% continuation probability
|-
| '''Premium Zone''' || Price above 21 MA (for shorts) || <code>probability_zone_analysis.py</code> || Entry zone for short trades
|-
| '''Fab Four''' || PDHL, 21 MA, 200 MA, Yesterday's Close || <code>signal_generation.py:_calculate_stop_loss()</code> || Stop loss placement hierarchy
|-
| '''Color Change''' || Bar closes opposite color after move || <code>probability_zone_analysis.py:ColorChangeDetector</code> || Confirms reversal/continuation
|-
| '''Break of Structure (BOS)''' || Price closes beyond recent swing H/L || <code>market_state_analysis.py:bos_detected</code> || Confirms trend continuation/reversal
|-
| '''MA Zone''' || MA is a band, not thin line (21 MA +/- 25pts) || <code>signal_generation.py:ma_buffer_points=25</code> || "Fab Four" concept from philosophy
|-
| '''Trend Phase''' || EARLY / MIDDLE / LATE classification || <code>market_state_analysis.py:trend_phase</code> || MIDDLE phase = optimal entry timing
|-
| '''Crash Bar''' || Bar > 2x average size, violent || <code>probability_zone_analysis.py:crash_bar_multiplier</code> || Structural break indicator
|-
| '''Traffic Jam''' || Yesterday's price activity zone || Conceptual || Resistance zone for gaps
|-
| '''Three-Finger Spread''' || Large gap between Price, 21 MA, 200 MA || <code>signal_generation.py:three_finger_spread_threshold</code> || Market top indicator
|}
----
= Part 6: Component Architecture =
== 6.1 Pipeline Flow ==
<pre>
┌─────────────────┐  ┌───────────────────┐  ┌────────────────────┐
│  Data Manager  │ → │  Trend Analysis  │ → │  Market State      │
│  (1M/5M/1H/1D)  │  │  (MA21, MA200)    │  │  (7 Detections)    │
└─────────────────┘  └───────────────────┘  └────────────────────┘
                                                      ↓
┌─────────────────┐  ┌───────────────────┐  ┌────────────────────┐
│  Trade Exec    │ ← │  Signal Gen      │ ← │  Setup Quality    │
│  (P&L, Costs)  │  │  (Entry/Exit)    │  │  (5-Factor Score)  │
└─────────────────┘  └───────────────────┘  └────────────────────┘
</pre>
----
== 6.2 Setup Quality Detection ==
'''File''': <code>src/components/setup_quality_detection.py</code>
=== 5-Factor Weighted Scoring System ===
{| class="wikitable"
! Factor !! Weight !! What It Measures
|-
| Timeframe Alignment || '''30%''' || All timeframes agree on direction
|-
| Trend Strength || '''20%''' || Healthy trend without warnings
|-
| Entry Quality || '''15%''' || Entry near MA, clean execution
|-
| Key Level Proximity || '''20%''' || Entry near support/resistance
|-
| Risk/Reward || '''15%''' || Favorable profit potential
|}
=== Penalty System ===
{| class="wikitable"
! Condition !! Penalty !! Trading Reason
|-
| Creeper Move || -50 pts || Quiet accumulation = reversal coming
|-
| MA Struggle || -30 pts || Price can't break MA = weak trend
|-
| No Two-Day Trend || -30 pts || Trend not confirmed
|-
| Wrong Trend Phase || -25 pts || Too early or too late in trend
|-
| Not Near MA || -40 pts || Entry too far from edge
|-
| Institutional Fight || 0.7x || Wait for resolution
|}
=== Grade Thresholds ===
{| class="wikitable"
! Grade !! Score !! Position Size !! Auto-Trade?
|-
| A+ || >= 90 || 2 lots || Yes
|-
| A || >= 80 || 1 lot || Yes
|-
| B || >= 70 || 1 lot || No
|-
| C || >= 60 || 1 lot || No
|-
| D || >= 50 || 1 lot || No
|-
| F || < 50 || 1 lot || No
|}
----
== 6.3 Market State Analysis ==
'''File''': <code>src/components/market_state_analysis.py</code>
=== 7 Detection Algorithms ===
{| class="wikitable"
! # !! Algorithm !! What It Detects !! Trading Implication
|-
| 1 || Railroad Trend || Healthy alternating bars || +15 bonus, trend continuation likely
|-
| 2 || Creeper Move || Small bars, consistent direction || -50 penalty, reversal imminent
|-
| 3 || Volatility Calc || ATR-based regime || Adjust stop distance
|-
| 4 || Market State || TRENDING / SIDEWAYS / VOLATILE || Different strategy rules
|-
| 5 || Two-Day Trend || Multi-day momentum || Required for A+ grade
|-
| 6 || Trend Phase || EARLY / MIDDLE / LATE || MIDDLE = optimal entry
|-
| 7 || Institutional Behavior || Volume + price patterns || Fight = wait, Accumulation = prepare
|}
----
== 6.4 Signal Generation ==
'''File''': <code>src/components/signal_generation_trade_management.py</code>
=== Entry Filters Applied ===
{| class="wikitable"
! Filter !! Config Key !! Purpose
|-
| Hour Filter || <code>blocked_hours: [9, 22, 23]</code> || Block loss-making hours
|-
| MA Direction || <code>enable_ma_direction_filter: True</code> || LONG only if MA rising
|-
| Probability Zone || <code>enable_probability_zone_filter: True</code> || Entry in favorable zones
|-
| Color Change || <code>enable_color_change_filter: False</code> || Disabled (too restrictive)
|}
----
= Part 7: Branch Changes (service/backtest → rikk_mtf_backtest001) =
== 7.1 Complete Git Diff Summary ==
'''Total Changes''': 65 files changed across core source, scripts, and data
=== Modified (M) Source Files ===
{| class="wikitable"
! File !! Type !! Key Changes
|-
| <code>signal_generation_trade_management.py</code> || Component || TICKET-7,8,10,11,12,13,18,19,20,21,24 + PDF fixes + Grading fix
|-
| <code>trade_execution_engine.py</code> || Component || TICKET-9,13,15,17,20: Trailing stop, breakeven, ATR
|-
| <code>market_state_analysis.py</code> || Component || TICKET-25: 5MIN → 1HOUR data
|-
| <code>setup_quality_detection.py</code> || Component || TICKET-5: Position sizing fix
|-
| <code>timeframe_conversion.py</code> || Core || Date column fix, 1m skip, emoji removal
|-
| <code>data_structures.py</code> || Core || TICKET-15: <code>current_stop_price</code> field
|-
| <code>multi_timeframe_analysis.py</code> || Component || Whitespace cleanup
|-
| <code>main.py</code> || Entry || TICKET-12 config, emoji removal
|}
=== Added (A) Files ===
{| class="wikitable"
! File !! Purpose
|-
| <code>probability_zone_analysis.py</code> || '''NEW''': Implements trade_philosophy.pdf (974 lines)
|-
| <code>50+ scripts/analyze_*.py</code> || Analysis scripts for hypothesis building
|}
----
== 7.2 JIRA Ticket Fixes (Complete Details) ==
=== TICKET-5: Position Sizing Fix ===
'''File''': <code>setup_quality_detection.py:544-567</code>
'''Problem''': Previous sizing = 100-200 lots = Rs 5.7 Crore exposure on Rs 1 lakh capital (5700x!)
<source lang="python">
# BEFORE (service/backtest):
multipliers = {
    SetupQualityGrade.A_PLUS: 200,  # 200 lots (impossible!)
    SetupQualityGrade.A: 150,
    SetupQualityGrade.B: 100,
    # ...
}
# AFTER (rikk_mtf_backtest001):
position_sizes = {
    SetupQualityGrade.A_PLUS: 2,    # 2 lots (Rs 1.14L exposure - realistic)
    SetupQualityGrade.A: 1,        # 1 lot
    SetupQualityGrade.B: 1,
    SetupQualityGrade.C: 1,
    SetupQualityGrade.D: 1,
    SetupQualityGrade.F: 1
}
</source>
----
=== TICKET-7: R:R Preservation After Slippage ===
'''File''': <code>signal_generation_trade_management.py:241-285</code>
'''Problem''': Slippage moved entry but stop/target stayed fixed = corrupted R:R ratio
<source lang="python">
# BEFORE: Stop and target not adjusted after slippage
actual_execution_price = execution_price + market_slippage  # Entry moved
# BUT stop_loss_price and take_profit_price stayed at original levels!
# RESULT: R:R became inverted (target closer than stop)
# AFTER: Shift stop and target with entry to maintain R:R
# Example (LONG with +1.5 pts slippage):
#  Before: entry=5710, stop=5680, target=5740 (30 pts each, 1:1 R:R)
#  After slippage: entry=5711.5, stop=5680, target=5740
#  WRONG R:R: stop=31.5 pts, target=28.5 pts (INVERTED!)
#  FIX: entry=5711.5, stop=5681.5, target=5741.5 (30 pts each, 1:1 R:R)
if signal.direction == Direction.LONG:
    actual_execution_price = execution_price + market_slippage
    # TICKET-7: Shift stop and target UP by slippage to maintain R:R
    adjusted_stop_loss = signal.stop_loss_price + market_slippage
    adjusted_take_profit = signal.take_profit_price + market_slippage
else:  # SHORT
    actual_execution_price = execution_price - market_slippage
    # TICKET-7: Shift stop and target DOWN by slippage to maintain R:R
    adjusted_stop_loss = signal.stop_loss_price - market_slippage
    adjusted_take_profit = signal.take_profit_price - market_slippage
</source>
----
=== TICKET-8: CTT Rate Fix ===
'''File''': <code>signal_generation_trade_management.py:48-55</code>
'''Problem''': CTT was 0.05% (5x too high!). Dhan broker calculates Rs 52 on Rs 5.2L = 0.01%
<source lang="python">
# BEFORE:
transaction_tax_rate: float = 0.000500  # 0.05% - WRONG!
# AFTER:
# MCX CTT = 0.01% on SELL side only. Since code charges at entry+exit,
# use 0.005% per leg so round-trip = 0.01% total (matches actual CTT)
# Dhan verified: CTT Rs 52 on Rs 5,20,000 sell value = 0.01%
transaction_tax_rate: float = 0.000050  # 0.005% per leg × 2 = 0.01% total
</source>
----
=== TICKET-9: Market Impact Slippage Cap ===
'''File''': <code>trade_execution_engine.py:40-42, 585-605</code>
'''Problem''': 100 lots × 0.1 = 10 pts slippage (excessive!)
<source lang="python">
# BEFORE: No cap on market impact
size_impact = signal.position_size * self.config.market_impact_factor
# AFTER: Cap to prevent excessive slippage
max_market_impact_slippage: float = 2.0  # Maximum 2 points
raw_size_impact = signal.position_size * self.config.market_impact_factor
size_impact = min(raw_size_impact, self.config.max_market_impact_slippage)
# For 1-2 lots (after TICKET-5 fix):
#  - base: 1.0 pts
#  - market_impact: min(1×0.1, 2.0) = 0.1 pts (capped at 2.0)
#  - volatility: 0.5 pts
#  - total: ~1.6 pts (realistic for MCX crude)
</source>
----
=== TICKET-10: Entry Technique Alignment ===
'''File''': <code>signal_generation_trade_management.py:2012-2140</code>
'''Problem''': Entry technique logic didn't match strategy_engine.py priority order
<source lang="python">
# COMPLETE REWRITE of _determine_entry_technique():
# BEFORE: Random priority order, creeper before BOS, missing key level checks
# AFTER (aligned with strategy_engine.py::_classify_entry_technique_exact()):
# PRIORITY 1: Creeper move → NEAR_MA (NOT green_bar/red_bar!)
# PRIORITY 2: BOS detected → BOS_ENTRY (only if NOT creeper)
# PRIORITY 3: Near key level → DISCOUNT_ZONE / BREAKOUT_PULLBACK
# PRIORITY 4: Near MA → MA_BOUNCE
# PRIORITY 5: Two-day trend → TWO_GREEN_DAILY / TWO_RED_DAILY
# PRIORITY 6: Railroad trend → GREEN_BAR_AFTER_PULLBACK / RED_BAR_AFTER_RALLY
# PRIORITY 7: Fallback → NEAR_MA
</source>
----
=== TICKET-11: BOS Stop Settings ===
'''File''': <code>signal_generation_trade_management.py:78-81</code>
'''Problem''': 5-bar lookback + no buffer = stop too close in trending markets = 66.7% stop rate
<source lang="python">
# BEFORE:
structure_lookback: int = 5  # Too short for BOS
# AFTER:
bos_structure_lookback: int = 10    # Extended lookback for BOS stops
bos_stop_buffer_points: float = 5.0  # Buffer below/above structure
</source>
----
=== TICKET-12: Hour Filter ===
'''File''': <code>signal_generation_trade_management.py:83-93, 126-137, 571-581</code>
'''Problem''': Certain hours consistently lose money
<source lang="python">
# NEW CONFIGURATION:
enable_hour_filter: bool = True
blocked_hours: [9, 22, 23]  # Block 9-10 AM and after 10 PM
# Data-driven analysis showed (from 1439 trades):
# Worst hours: 15(-Rs244K), 22(-Rs209K), 09(-Rs199K), 21(-Rs101K), etc.
# Profitable hours: 16, 17, 18, 19, 23 (total +Rs341K)
# Applied in generate_signal():
if self.config.enable_hour_filter and self.config.blocked_hours:
    current_hour = current_timestamp.hour
    if current_hour in self.config.blocked_hours:
        return None  # No signal during blocked hours
</source>
----
=== TICKET-13: Minimum Stop Distance ===
'''File''': <code>signal_generation_trade_management.py:57-60, 852-870</code>
'''Problem''': 20pt stops hit too frequently due to normal price noise
<source lang="python">
# BEFORE:
default_stop_distance: float = 20.000000
# AFTER:
min_stop_distance: float = 40.000000    # Minimum stop distance
default_stop_distance: float = 40.000000  # Default increased
# ENFORCEMENT in generate_signal():
# TICKET-13 FIX: ENFORCE MINIMUM STOP DISTANCE (40 POINTS)
stop_distance = max(calculated_stop_distance, self.config.min_stop_distance)
</source>
----
=== TICKET-15: Trailing Stop Tracking ===
'''File''': <code>data_structures.py:2982-2984</code>, <code>trade_execution_engine.py:54-70, 295-392</code>
'''Problem''': No way to track current trailing stop position vs original
<source lang="python">
# NEW FIELD in Trade dataclass:
current_stop_price: Optional[float] = None  # Current trailing stop (moves with price)
# NEW METHOD in TradeExecutionEngine:
def _update_trailing_stop(self, trade: Trade, current_high: float, current_low: float):
    """
    TICKET-15/17/20: Update stop based on price movement.
    Two-Phase Stop Management:
    PHASE 1 - Breakeven (TICKET-17): Move stop to entry when profitable
    PHASE 2 - Trailing (TICKET-15/20): Trail stop behind price
    """
    if trade.current_stop_price is None:
        trade.current_stop_price = trade.original_stop_price
    # Calculate trailing distance (ATR-based or fixed)
    if self.config.trailing_stop_method == "ATR_MULTIPLE":
        trailing_distance = self.current_atr * self.config.atr_multiplier
        trailing_distance = max(trailing_distance, 15.0)  # Min 15 pts for Crude
    else:
        trailing_distance = self.config.trailing_stop_distance
    if trade.direction == Direction.LONG:
        current_profit = current_high - trade.entry_price
        if current_profit >= self.config.trailing_stop_activation:
            new_stop = current_high - trailing_distance
            if new_stop > trade.current_stop_price:
                trade.current_stop_price = new_stop  # Only move UP
</source>
----
=== TICKET-17: Breakeven Stop ===
'''File''': <code>trade_execution_engine.py:64-68</code>
'''Problem''': Needed automatic breakeven move when in profit
<source lang="python">
# NEW CONFIGURATION:
enable_breakeven_stop: bool = True
breakeven_activation: float = 25.0  # Points profit before moving to breakeven
breakeven_buffer: float = 2.0      # Points above/below entry for buffer
# Tested 10pt activation but cut winners too short (26% WR vs 49%)
# 25pt activation is the sweet spot
</source>
----
=== TICKET-18: Creeper Move Handling ===
'''File''': <code>signal_generation_trade_management.py:582-595</code>
'''Problem''': Previous implementation blocked creeper signals entirely (too aggressive)
<source lang="python">
# BEFORE: Creeper signals blocked with return None
# AFTER (comment explains fix):
# CORE BEHAVIOR: Creeper moves get -50 penalty + 0.7x target + uses NEAR_MA
# Previous implementation: Blocked entirely with return None (too aggressive)
#
# FIX: Let creeper signals through - penalty applied in setup_quality_detection,
# NEAR_MA technique used in _determine_entry_technique()
# Let the scoring system decide rather than blocking outright
</source>
----
=== TICKET-19: MA Direction Filter + Score Adjustment ===
'''File''': <code>signal_generation_trade_management.py:95-97, 987-1034, 1955-2010</code>
'''Problem''': Trades against MA21 slope direction had poor performance
<source lang="python">
# CONFIGURATION:
enable_ma_direction_filter: bool = True
# DIRECTION LOGIC COMPLETE REWRITE (_determine_signal_direction):
# BEFORE: Used alignment score threshold (>= 60%)
# AFTER: Uses MA21 slope as primary direction source
def _determine_signal_direction(self, timeframe_analysis, market_state, market_data=None):
    """MA21 SLOPE ALIGNMENT DIRECTION LOGIC (trade_philosophy.pdf)"""
    trend_direction = getattr(market_state, 'trend_direction', None)
    if trend_direction == "up":
        return Direction.LONG      # MA21 rising → only LONG
    elif trend_direction == "down":
        return Direction.SHORT    # MA21 declining → only SHORT
    else:
        # Fallback to MTF primary_direction if MA21 is flat/unknown
        return getattr(timeframe_analysis, 'primary_direction', None)
# SCORE ADJUSTMENT (lines 987-1034):
# +15% bonus if trade direction aligns with MA21 slope
# -10% penalty if trade direction against MA21 slope
</source>
----
=== TICKET-20: Probability Zone Filter + ATR Trailing ===
'''File''': <code>signal_generation_trade_management.py:99-109, 628-817</code>, <code>trade_execution_engine.py:57-63, 295-340</code>
'''Problem''': Needed trade_philosophy.pdf concepts in code
<source lang="python">
# NEW CONFIGURATION (Probability Zones):
enable_probability_zone_filter: bool = True
probability_zone_swing_lookback: int = 20
probability_zone_min_range: float = 20.0
three_finger_spread_threshold: float = 0.02
crash_bar_multiplier: float = 2.0
sideways_mean_reversion: bool = True
# NEW CONFIGURATION (ATR Trailing):
trailing_stop_method: str = "ATR_MULTIPLE"  # or "FIXED_POINTS"
atr_period: int = 14
atr_multiplier: float = 2.0  # 2x ATR = trailing distance
# NEW ATR CALCULATION in trade_execution_engine.py:295-340
def _calculate_atr(self, five_min_data: Dict) -> None:
    """Calculate Average True Range for dynamic trailing stop."""
    # TrueRange = max(high-low, abs(high-prev_close), abs(low-prev_close))
    # ATR = SMA(TrueRange, period)
    true_ranges = []
    for i in range(1, len(high_vals)):
        tr = max(
            high_vals[i] - low_vals[i],          # Current high - low
            abs(high_vals[i] - close_vals[i-1]),  # High - previous close
            abs(low_vals[i] - close_vals[i-1])    # Low - previous close
        )
        true_ranges.append(tr)
    self.current_atr = sum(true_ranges) / len(true_ranges)
</source>
----
=== TICKET-21: Color Change Filter (DISABLED) ===
'''File''': <code>signal_generation_trade_management.py:111-118</code>
'''Problem''': color_change.pdf patterns too restrictive for automation
<source lang="python">
# CONFIGURATION (disabled):
enable_color_change_filter: bool = False  # DISABLED - too restrictive
color_change_ma_proximity: float = 20.0  # Points to consider "near" MA
require_ma_bounce: bool = False          # Too strict
color_change_require_in_zones: bool = True
# NOTE: ColorChangeDetector class still exists for future use
# Implements liquidity sweep patterns:
# - LONG: Green bar sweeps BELOW red bar low + bounce from 21 MA
# - SHORT: Red bar sweeps ABOVE green bar high + rejection from 21 MA
</source>
----
=== TICKET-24: Creeper Move Entry Technique Fix ===
'''File''': <code>signal_generation_trade_management.py:2037-2050</code>
'''Problem''': strategy_engine.py bug - uses wrong entry technique for creeper moves
<source lang="python">
# STRATEGY ENGINE BUG FOUND:
# backtesting_standalone/src/strategy_engine.py lines 3338-3380
# checks bos_detected FIRST but doesn't consider is_creeper_move.
# This causes BOS entries in creeper moves (inappropriate).
# FIX: Check creeper FIRST before BOS
if is_creeper:
    # Creeper gets -50 penalty + 0.7x target from setup_quality_detection
    # But uses NEAR_MA as technique (NOT green_bar/red_bar!)
    return EntryTechnique.NEAR_MA  # Strategy engine fallback
</source>
----
=== TICKET-25: Market State 5MIN → 1HOUR ===
'''File''': <code>market_state_analysis.py:191-360</code>
'''Problem''': Creeper threshold 0.5% calibrated for 1H bars (~0.8-1.2% range), but code used 5MIN (~0.16% range) = 98.9% false positives!
<source lang="python">
# BEFORE:
required_tf = TimeframeValue.FIVE_MIN
# AFTER:
def validate_input(self, input_data: Dict, context: ComponentContext):
    """
    TICKET-25 FIX: Market state analysis uses 1-HOUR data (not 5MIN)
    to match strategy_engine.py behavior for creeper/railroad detection.
    """
    primary_tf = TimeframeValue.ONE_HOUR
    fallback_tf = TimeframeValue.FIVE_MIN
    if primary_tf in input_data and input_data[primary_tf] is not None:
        required_tf = primary_tf
    elif fallback_tf in input_data and input_data[fallback_tf] is not None:
        required_tf = fallback_tf
        # Warning: 5MIN fallback may cause inaccurate creeper detection
def _get_primary_timeframe(self, input_data: Dict) -> TimeframeValue:
    """
    TICKET-25 FIX: Use ONE_HOUR for market state analysis.
    The 0.5% creeper threshold is calibrated for 1-HOUR bars (~0.8-1.2% typical range),
    not 5-MIN bars (~0.16% typical range). Using 5MIN caused 98.9% false positives.
    """
    primary_tf = TimeframeValue.ONE_HOUR  # Was FIVE_MIN
</source>
----
=== PDF-FIX: MA Buffer Points ===
'''File''': <code>signal_generation_trade_management.py:67-68</code>
'''Source''': Fab Four concept - "MA is a zone, not a thin line"
<source lang="python">
# BEFORE:
ma_buffer_points: float = 5.000000  # Too tight!
# AFTER:
# PDF-FIX: MA is a "zone, not a thin line" (Fab Four) - use wider buffer
ma_buffer_points: float = 25.000000  # 21 MA zone width
</source>
----
=== PDF-FIX: Take Profit Calculation Rewrite ===
'''File''': <code>signal_generation_trade_management.py:1620-1677</code>
'''Problem''': Old method used strategy.entry_exit_settings with FIXED_POINTS, ATR_MULTIPLE, etc. PDF philosophy uses 50% of prior move.
<source lang="python">
# BEFORE: Used strategy config with multiple methods
def _calculate_take_profit(self, strategy, entry_price, stop_loss_price, direction):
    profit_target_method = strategy.entry_exit_settings.profit_target_method
    if profit_target_method == ProfitTargetMethod.FIXED_POINTS:
        profit_points = strategy.entry_exit_settings.profit_target_points or 25
        return entry_price + profit_points  # etc.
    elif profit_target_method == ProfitTargetMethod.ATR_MULTIPLE:
        # ... ATR logic
# AFTER: PDF-based 50% mean reversion target
def _calculate_take_profit(self, strategy, entry_price, stop_loss_price, direction, market_data=None):
    """PDF-FIX: Target = 50% of prior move (trade_philosophy.pdf)"""
    if market_data:
        ma21_series = tf_data.get("ma21")
        if ma21_series is not None:
            ma_21 = float(ma21_series.iloc[-1])
            # Calculate 50% move toward MA
            distance_to_ma = abs(entry_price - ma_21)
            target_distance = distance_to_ma * 0.5
            # But ensure minimum target based on risk
            risk_distance = abs(entry_price - stop_loss_price)
            min_target = risk_distance * 1.5  # At least 1.5:1 R:R
            target_distance = max(target_distance, min_target)
            return entry_price + target_distance  # (or minus for SHORT)
    # Fallback to 2:1 R:R if no MA data
    risk_distance = abs(entry_price - stop_loss_price)
    return entry_price + (risk_distance * 2)
</source>
----
=== PDF-FIX: CRASH SHORT Detection (Direction Override) ===
'''File''': <code>signal_generation_trade_management.py:700-750</code>
'''Logic''': In sideways market at top zone, big RED bar breaking below 21 MA overrides LONG direction to SHORT
<source lang="python">
# NEW CODE: Crash SHORT detection within probability zone filter
# Per PDF: In top third, big RED bar breaking 21 MA = SHORT signal
is_red_bar = current_close < current_open
is_big_bar = current_range > avg_range * 1.2  # 1.2x average = significant bar
breaks_below_ma = current_close < (ma_21 - 25.0)  # Below MA zone
was_above_ma = current_open > (ma_21 - 25.0)
is_top_zone = zone_result.zone in [ProbabilityZone.TOP_THIRD, ProbabilityZone.TOP_HALF]
is_sideways = market_state_str in ["creeper", "creeper_move", "sideways", "consolidation"]
# CRASH SHORT DETECTION: Override LONG to SHORT in sideways markets
if is_sideways and is_top_zone and is_big_bar and is_red_bar and breaks_below_ma and was_above_ma:
    self.logger.debug(f"CRASH SHORT DETECTED: Overriding {direction} to SHORT")
    direction = Direction.SHORT
    is_crash_short = True  # Flag to skip color change filter
</source>
----
=== PDF-FIX: Stop Loss Calculation (NEAR_MA technique) ===
'''File''': <code>signal_generation_trade_management.py:1490-1530</code>
'''Problem''': Old code placed stop relative to MA value. New code uses structure low/high.
<source lang="python">
# BEFORE: Stop below/above MA value
if entry_technique == EntryTechnique.NEAR_MA_LONG:
    if ma21_values is not None:
        ma_value = ma21_values[-1]
        buffer_points = self.config.ma_buffer_points
        stop_loss = ma_value - buffer_points  # Below MA
# AFTER: Stop below structure low (more robust)
if entry_technique == EntryTechnique.NEAR_MA_LONG:
    # PDF-FIX: Stop should be below recent structure low, not just below MA
    # When price is already below MA (LONG per new direction logic),
    # stop below MA would be above entry = wrong!
    lookback = self.config.structure_lookback  # 5 bars
    if len(low_values) >= lookback:
        structure_low = min(low_values[-lookback:])
        stop_loss = structure_low - self.config.ma_buffer_points
        # Ensure stop is below entry
        if stop_loss >= entry_price:
            stop_loss = entry_price - self.config.default_stop_distance
</source>
----
=== GRADING FIX: Score-to-Grade Recalculation ===
'''File''': <code>signal_generation_trade_management.py:1054, 1132-1170</code>
'''Problem''': Grade assigned from capped original score instead of adjusted score
<source lang="python">
# BEFORE:
setup_quality=setup_quality.grade,    # Grade from CAPPED original score (79)
setup_score=setup_quality.score,      # Original score (79)
# Problem: Score=79 → Grade=A, but if adjustment makes it 89, should be A+!
# AFTER:
setup_quality=self._calculate_grade_from_score(adjusted_score),  # RECALCULATED
setup_score=adjusted_score,  # MA-adjusted score
# NEW METHOD ADDED:
def _calculate_grade_from_score(self, score: float) -> SetupQualityGrade:
    """GRADING FIX: Calculate grade from FINAL adjusted score."""
    if score >= 90: return SetupQualityGrade.A_PLUS
    elif score >= 80: return SetupQualityGrade.A
    elif score >= 70: return SetupQualityGrade.B
    elif score >= 60: return SetupQualityGrade.C
    elif score >= 50: return SetupQualityGrade.D
    else: return SetupQualityGrade.F
</source>
----
== 7.3 New File: probability_zone_analysis.py (974 lines) ==
This file implements concepts from <code>trade_philosophy.pdf</code>:
=== Enums Defined ===
<source lang="python">
class ProbabilityZone(Enum):
    TOP_THIRD = "top_third"          # 80% continuation probability
    TOP_HALF = "top_half"            # 65% continuation probability
    BOTTOM_HALF = "bottom_half"      # 35% continuation probability
    BOTTOM_THIRD = "bottom_third"    # 15% continuation (85% reversal)
class MarketStructure(Enum):
    UPTREND = "uptrend"              # Price > 21 MA > 200 MA
    DOWNTREND = "downtrend"          # Price < 21 MA < 200 MA
    SIDEWAYS = "sideways"            # No clear structure
    THREE_FINGER_SPREAD_BULL = "..."  # Large spread (bearish signal)
    THREE_FINGER_SPREAD_BEAR = "..."  # Large spread (bullish signal)
class PullbackType(Enum):
    HEALTHY_PULLBACK = "healthy_pullback"  # 45-degree drift, holds above halfway
    COLLAPSE = "collapse"                  # Vertical drop, breaks deeply
    NO_PULLBACK = "no_pullback"            # Price at or near highs
    BOUNCE = "bounce"                      # Bounce after crash (short opportunity)
class ColorChangeType(Enum):
    BULLISH_REVERSAL = "bullish_reversal"  # Green bar takes out red bar high
    BEARISH_REVERSAL = "bearish_reversal"  # Red bar takes out green bar low
    NO_PATTERN = "no_pattern"
</source>
=== Key Classes ===
* <code>ProbabilityZoneResult</code> - Analysis result with zone, probabilities, MA structure
* <code>ColorChangeResult</code> - Pattern detection result
* <code>ProbabilityZoneConfig</code> - Configuration with thresholds
* <code>ProbabilityZoneAnalyzer</code> - Main analyzer class
* <code>ColorChangeDetector</code> - Detects liquidity sweep patterns
=== Configuration Defaults ===
<source lang="python">
@dataclass
class ProbabilityZoneConfig:
    top_third_probability: float = 0.80    # 80% continuation
    top_half_probability: float = 0.65    # 65% continuation
    bottom_half_probability: float = 0.35  # 35% continuation
    bottom_third_probability: float = 0.15 # 15% continuation
    swing_lookback_bars: int = 20          # Bars for swing H/L
    crash_bar_multiplier: float = 2.0      # Bar > 2x avg = crash
    three_finger_min_spread_pct: float = 0.02  # 2% spread threshold
</source>
----
== 7.4 timeframe_conversion.py Changes ==
'''File''': <code>src/core/timeframe_conversion.py</code>
=== Changes ===
# '''Emoji removal''' - All emoji characters replaced with <code>[OK]</code>, <code>[FAIL]</code>, <code>[CONV]</code>, etc.
# '''Date column fix''' - Handle 'date' as alias for 'timestamp'
# '''1m skip''' - Don't overwrite source file when saving
# '''Mixed timestamp format''' - Use <code>format='mixed'</code> for pandas parsing
<source lang="python">
# Date column alias:
if 'date' in source_df.columns and 'timestamp' not in source_df.columns:
    source_df = source_df.rename(columns={'date': 'timestamp'})
    logger.info("[FIX] Renamed 'date' column to 'timestamp'")
# Skip 1m overwrite:
if timeframe == '1m':
    logger.info(f"[SKIP] 1m: Source file preserved (not overwritten)")
    continue
# Mixed timestamp parsing:
pd.to_datetime(df['timestamp'], format='mixed')
</source>
----
== 7.5 main.py Changes ==
'''File''': <code>src/main.py</code>
=== Changes ===
# '''Hour filter configuration''' - TICKET-12 support
# '''Emoji removal''' - Console output cleanup
<source lang="python">
# TICKET-12: Hour Filter configuration:
enable_hour_filter=strategy_config.get('enable_hour_filter', False),
blocked_hours=strategy_config.get('blocked_hours', [])
print(f"  TICKET-12 Hour Filter: Enabled={signal_generator_config.enable_hour_filter}, "
      f"Blocked Hours={signal_generator_config.blocked_hours}")
</source>
----
== 7.6 Complete File Tree ==
<pre>
services/backtest/src/
├── components/
│  ├── market_state_analysis.py      # TICKET-25: 5MIN → 1HOUR
│  ├── multi_timeframe_analysis.py  # Whitespace cleanup
│  ├── probability_zone_analysis.py  # NEW: trade_philosophy.pdf (974 lines)
│  ├── setup_quality_detection.py    # TICKET-5: position sizing
│  ├── signal_generation_trade_management.py  # TICKET-7,8,10,11,12,13,18,19,20,21,24 + GRADING FIX
│  └── trade_execution_engine.py    # TICKET-9,13,15,17,20: trailing/breakeven/ATR
├── core/
│  ├── data_structures.py            # TICKET-15: current_stop_price field
│  └── timeframe_conversion.py      # Date fix, 1m skip, emoji removal
└── main.py                          # TICKET-12 config, emoji removal
services/backtest/scripts/          # 50+ NEW analysis scripts
├── analyze_alignment_pnl.py
├── analyze_alignment_pnl_v2.py
├── analyze_aplus.py
├── analyze_by_hour.py
├── analyze_combined_filters.py
├── analyze_crash_short_potential.py
├── analyze_hour_filter.py
├── analyze_hourly_pnl.py
├── analyze_long_short_detail.py
├── analyze_longs.py
├── analyze_ma_alignment.py
├── analyze_ma_slope_filter.py
├── analyze_morning_times.py
├── analyze_pdf_results.py
├── analyze_quick_exits.py
├── analyze_red_bar_rally.py
├── analyze_shorts.py
├── analyze_stop_exits.py
├── analyze_stop_loss_detail.py
├── analyze_test_summary.py
├── analyze_trade_bias.py
├── analyze_trading_hours_filter.py
├── analyze_trend_direction_at_entry.py
├── aplus_vs_a_analysis.py
├── check_all_data.py
├── check_costs.py
├── check_data_range.py
├── check_price_trend.py
├── comprehensive_analysis.py
├── comprehensive_backtest_analysis.py
├── comprehensive_summary.py
├── cost_impact_analysis.py
├── detailed_monthly.py
├── diagnose_color_change.py
├── diagnose_direction_bias.py
├── framework_comparison_analysis.py
├── generate_test_summary.py
├── grade_and_equity.py
├── monthly_breakdown.py
├── no_morning_analysis.py
├── path_to_profitability.py
├── philosophy_v1_blend_analysis.py
├── root_cause_summary.py
├── short_market_state_alignment.py
├── short_technique_analysis.py
├── simulate_target_rr.py
├── simulate_target_rr_v2.py
├── stop_out_deep_analysis.py
├── strategy_engine_gap_analysis.py
├── test_summary.py
└── v1_optimization_impact_analysis.py
</pre>
----
= Part 8: Strategy Configuration =
== 8.1 76D Parameter Vector ==
The strategy uses '''regime-aware configuration''' with 76 parameters:
* '''44 Global Parameters''' - Constant across all market regimes
* '''32 Regime Parameters''' - 8 parameters × 4 market regimes
'''File''': <code>src/config/strategy_config.py</code>
=== Key Parameters ===
{| class="wikitable"
! Parameter !! Default !! Description
|-
| <code>primary_ma_period</code> || 21 || Main trend MA
|-
| <code>secondary_ma_period</code> || 200 || Long-term trend MA
|-
| <code>default_stop_distance</code> || 40 pts || Minimum stop distance
|-
| <code>default_risk_reward</code> || 2.0 || Target R:R ratio
|-
| <code>ma_buffer_points</code> || 25 pts || MA zone width
|-
| <code>creeper_move_penalty</code> || -50 || Score reduction
|-
| <code>railroad_trend_bonus</code> || +15 || Score increase
|}
----
= Part 9: Decision Trees =
== 9.1 Should I Trade This Setup? ==
<pre>
START: Signal Generated
  │
  ▼
[Is hour blocked (9, 22, 23)?]
  │ Yes → SKIP (loss-making hours)
  │ No ↓
  ▼
[Is MA21 direction aligned with trade?]
  │ LONG + MA rising? → Continue
  │ SHORT + MA falling? → Continue
  │ No alignment → SKIP
  │
  ▼
[Is price in probability zone?]
  │ LONG + Bottom Third? → Continue (80% odds)
  │ SHORT + Top Third? → Continue (80% odds)
  │ Wrong zone → SKIP
  │
  ▼
[Calculate Setup Quality Score]
  │
  ├─ Apply 5-factor scoring (TF 30%, Trend 20%, Entry 15%, KeyLevel 20%, R:R 15%)
  ├─ Apply penalties (creeper -50, MA struggle -30, etc.)
  ├─ Apply institutional fight multiplier (0.7x)
  ├─ Apply MA direction adjustment (+15% aligned, -10% against)
  │
  ▼
[Recalculate Grade from ADJUSTED score]
  │
  ├─ A+ or A → Auto-trade eligible (2 lots for A+, 1 lot for A)
  ├─ B to D → Manual review (1 lot)
  ├─ F → Skip or minimal size
  │
  ▼
[Execute Trade with Position Size]
</pre>
----
== 9.2 Where to Place Stop? ==
<pre>
START: Trade Direction Determined
  │
  ▼
[Is Fab Four zone tight and close?]
  │ Yes → Place stop BEYOND Fab Four zone
  │ No ↓
  ▼
[Can I afford stop beyond Fab Four?]
  │ Yes → Use EVENT stop (beyond Fab Four)
  │ No → Use MAXIMUM loss stop ($6000 max)
  │
  ▼
[ENFORCE minimum 40pt stop (TICKET-13)]
  │
  ▼
[Once trade moves in favor:]
  │
  ├─ 25 pts profit → Move stop to breakeven (TICKET-17)
  ├─ 20+ pts profit → Start trailing (TICKET-15/20)
  ├─ Use ATR-based trail distance (2x ATR, min 15 pts)
  │
  ▼
[Stop Placement Complete]
</pre>
----
= Part 10: Code Review Guidelines =
== 10.1 What Reviewers Should Check ==
* Code correctness (syntax, bugs)
* Integration (doesn't break other components)
* Test coverage
* Precision (6-decimal places per spec)
* Performance (no excessive logging)
== 10.2 What Reviewers Should NOT Question ==
* The penalty values themselves (-50, -30, etc.)
* Why 21 MA and not 20 MA
* Why specific thresholds (these are trading decisions)
* Why certain hours are blocked
== 10.3 Trading Authority Principle ==
'''Rikk has final authority on:'''
* Entry/exit conditions
* Threshold values
* Setup definitions
* What constitutes a valid signal
* Penalty/bonus amounts
'''Engineers have authority on:'''
* Code quality and structure
* Performance optimization
* Error handling
* System integration
* Test coverage
----
= Part 11: Quick Reference Cards =
== Card 1: Probability Zones ==
<pre>
TOP THIRD    = 80% continuation (SHORT zone)
TOP HALF    = 65% continuation
BOTTOM HALF  = 35% continuation
BOTTOM THIRD = 15% continuation (LONG zone with 85% reversal odds)
</pre>
== Card 2: Setup Quality Formula ==
<pre>
Score = (TF_align × 0.30) + (Trend × 0.20) + (Entry × 0.15) + (KeyLevel × 0.20) + (R:R × 0.15)
Then apply:
- Creeper detected? → Score - 50
- MA struggle? → Score - 30
- No two-day trend? → Score - 30
- Wrong phase? → Score - 25
- Institutional fight? → Score × 0.7
- MA direction aligned? → Score + 15%
- MA direction against? → Score - 10%
Finally: Recalculate grade from ADJUSTED score (not original!)
</pre>
== Card 3: Profit Taking ==
<pre>
1. Enter with 2 lots
2. Set stop above high (short) / below low (long)
3. Wait for follow-through bar (2nd bar after opposite color)
4. Take profit on 1 lot
5. Move stop to break-even
6. Wait for next follow-through bar
7. Take profit on remaining lot
8. Done
</pre>
== Card 4: All Code Changes Summary ==
{| class="wikitable"
! Change !! One-Line Summary
|-
| '''TICKET-5''' || Position sizing: 200 lots → 2/1 lots (realistic for Rs 1L capital)
|-
| '''TICKET-7''' || R:R preservation: shift stop/target with slippage
|-
| '''TICKET-8''' || CTT rate: 0.05% → 0.005% per leg (5x fix)
|-
| '''TICKET-9''' || Market impact: cap slippage at 2 pts max
|-
| '''TICKET-10''' || Entry technique: align with strategy_engine.py priority order
|-
| '''TICKET-11''' || BOS stops: 5 → 10 bar lookback + 5pt buffer
|-
| '''TICKET-12''' || Hour filter: block hours 9, 22, 23 (loss-making)
|-
| '''TICKET-13''' || Min stop: 20 → 40 pts (noise protection)
|-
| '''TICKET-15''' || Trailing stop: add current_stop_price tracking
|-
| '''TICKET-17''' || Breakeven: move stop to entry at 25pt profit
|-
| '''TICKET-18''' || Creeper handling: let through (don't block), use penalty
|-
| '''TICKET-19''' || MA direction: use slope as primary direction source + score adjustment
|-
| '''TICKET-20''' || Probability zones + ATR trailing (trade_philosophy.pdf)
|-
| '''TICKET-21''' || Color change: disabled (too restrictive)
|-
| '''TICKET-24''' || Creeper entry: use NEAR_MA technique (not green/red bar)
|-
| '''TICKET-25''' || Market state: 5MIN → 1HOUR for creeper detection
|-
| '''GRADING FIX''' || Recalculate grade from adjusted score (not capped original)
|-
| '''PDF-FIX: MA Buffer''' || 5 → 25 pts (MA is zone, not line)
|-
| '''PDF-FIX: Take Profit''' || Rewrite to 50% of distance-to-MA (mean reversion)
|-
| '''PDF-FIX: Crash SHORT''' || Direction override: sideways + top zone + big red bar → SHORT
|-
| '''PDF-FIX: Stop Loss''' || NEAR_MA stop uses structure low (not MA value)
|-
| '''NEW: __post_init__''' || Initialize blocked_hours list after dataclass creation
|-
| '''NEW: _calculate_grade_from_score''' || New method to recalculate grade from adjusted score
|-
| '''NEW: probability_zone_analysis.py''' || 974-line new file implementing trade_philosophy.pdf
|-
| '''NEW: 50+ analysis scripts''' || Scripts for hypothesis building and analysis
|}
----
''Last Updated: 2026-01-05 | Branch: rikk_mtf_backtest001 | Validated: 19-month backtest''

Revision as of 04:15, 5 January 2026