GoshawkVortexAI commited on
Commit
4d1fcc1
Β·
verified Β·
1 Parent(s): 55db2dd

Delete veto.py

Browse files
Files changed (1) hide show
  1. veto.py +0 -124
veto.py DELETED
@@ -1,124 +0,0 @@
1
- """
2
- veto.py β€” Hard filters. Any single veto cancels the setup entirely.
3
-
4
- Key fixes vs prior version:
5
- - Absorption is now a hard veto (was missing)
6
- - Climax volume is a hard veto (was only a score penalty)
7
- - Failed breakout in last N bars = hard veto
8
- - Price too extended from mean = hard veto (separate per direction)
9
- - Vol ratio threshold lowered to 2.2 (fires more reliably)
10
- - No volatility compression = veto (require setups to emerge from bases)
11
- - Regime confidence below minimum = veto (new structural gate)
12
- """
13
-
14
- from typing import Dict, Any, Tuple
15
-
16
- from config import (
17
- VETO_VOLUME_MIN,
18
- VETO_VOL_RATIO_MAX,
19
- VETO_STRUCTURE_MIN,
20
- VETO_CLIMAX,
21
- VETO_ABSORPTION,
22
- VETO_EXTENDED_PRICE,
23
- VETO_NO_COMPRESSION,
24
- REGIME_CONFIDENCE_MIN,
25
- VOL_COMPRESSION_LOOKBACK,
26
- )
27
-
28
- _FAILED_BREAKOUT_LOOKBACK = 5 # bars to look back for recent fake signals
29
- _CONSEC_FAILED_MAX = 2 # veto if N or more recent fakes
30
-
31
-
32
- def apply_veto(
33
- regime_data: Dict[str, Any],
34
- volume_data: Dict[str, Any],
35
- structure_score: float,
36
- direction: int = 1, # +1 = evaluating long, -1 = evaluating short
37
- ) -> Tuple[bool, str]:
38
- """
39
- Returns (vetoed: bool, reason: str).
40
- direction controls which extension check applies.
41
- """
42
- reasons = []
43
-
44
- volume_score = volume_data.get("volume_score", 0.0)
45
- vol_ratio = regime_data.get("vol_ratio", 1.0)
46
- trend = regime_data.get("trend", "ranging")
47
- vol_compressed = regime_data.get("vol_compressed", False)
48
- vol_expanding = regime_data.get("vol_expanding", False)
49
- regime_confidence = regime_data.get("regime_confidence", 0.0)
50
- price_extended_long = regime_data.get("price_extended_long", False)
51
- price_extended_short = regime_data.get("price_extended_short", False)
52
- adx = regime_data.get("adx", 0.0)
53
-
54
- spike = volume_data.get("spike", False)
55
- climax = volume_data.get("climax", False)
56
- absorption = volume_data.get("absorption", False)
57
- failed_breakout = volume_data.get("failed_breakout", False)
58
- recent_failed = volume_data.get("recent_failed_count", 0)
59
- weak = volume_data.get("weak", False)
60
-
61
- # ── VOLUME GATES ─────────────────────────────────────────────────────────
62
- if volume_score < VETO_VOLUME_MIN:
63
- reasons.append(f"WEAK_VOLUME_SCORE ({volume_score:.2f} < {VETO_VOLUME_MIN})")
64
-
65
- if weak:
66
- reasons.append(f"VOLUME_BELOW_MA (ratio={volume_data.get('vol_ratio', 0):.2f})")
67
-
68
- if VETO_CLIMAX and climax:
69
- reasons.append("CLIMAX_VOLUME β€” potential exhaustion, not entry")
70
-
71
- if VETO_ABSORPTION and absorption:
72
- reasons.append("ABSORPTION_DETECTED β€” institutional supply at resistance")
73
-
74
- # ── BREAKOUT INTEGRITY ────────────────────────────────────────────────────
75
- if failed_breakout:
76
- reasons.append("FAILED_BREAKOUT β€” most recent breakout reversed")
77
-
78
- if recent_failed >= _CONSEC_FAILED_MAX:
79
- reasons.append(f"REPEATED_FAKE_BREAKOUTS ({recent_failed} in last 10 bars)")
80
-
81
- # ── VOLATILITY GATES ──────────────────────────────────────────────────────
82
- if vol_ratio > VETO_VOL_RATIO_MAX:
83
- reasons.append(f"EXTREME_VOLATILITY (ratio={vol_ratio:.2f} > {VETO_VOL_RATIO_MAX})")
84
-
85
- if VETO_NO_COMPRESSION and not vol_compressed and not vol_expanding:
86
- # Allow through if currently expanding β€” expansion from base is fine
87
- # Only veto if vol is neither compressed nor just broke out
88
- if vol_ratio < 0.9 or vol_ratio > 1.6:
89
- reasons.append(
90
- f"NO_VOLATILITY_BASE (ratio={vol_ratio:.2f}, compressed={vol_compressed})"
91
- )
92
-
93
- # ── STRUCTURE GATE ────────────────────────────────────────────────────────
94
- if structure_score < VETO_STRUCTURE_MIN:
95
- reasons.append(f"WEAK_STRUCTURE ({structure_score:.2f} < {VETO_STRUCTURE_MIN})")
96
-
97
- if trend == "bearish" and direction == 1:
98
- reasons.append("BEARISH_TREND β€” long entry contra-trend")
99
-
100
- if trend == "bullish" and direction == -1:
101
- reasons.append("BULLISH_TREND β€” short entry contra-trend")
102
-
103
- # ── REGIME CONFIDENCE GATE ────────────────────────────────────────────────
104
- if regime_confidence < REGIME_CONFIDENCE_MIN:
105
- reasons.append(
106
- f"LOW_REGIME_CONFIDENCE ({regime_confidence:.2f} < {REGIME_CONFIDENCE_MIN})"
107
- )
108
-
109
- # ── PRICE EXTENSION GATE ─────────────────────────────────────────────────
110
- if VETO_EXTENDED_PRICE:
111
- if direction == 1 and price_extended_long:
112
- dist = regime_data.get("dist_atr", 0.0)
113
- reasons.append(f"PRICE_EXTENDED_LONG ({dist:.2f} ATR above mean)")
114
- if direction == -1 and price_extended_short:
115
- dist = regime_data.get("dist_atr", 0.0)
116
- reasons.append(f"PRICE_EXTENDED_SHORT ({dist:.2f} ATR below mean)")
117
-
118
- if reasons:
119
- return True, " | ".join(reasons)
120
- return False, ""
121
-
122
-
123
- def veto_summary(vetoed: bool, reason: str) -> str:
124
- return f"VETOED β€” {reason}" if vetoed else "APPROVED"