Riy777 commited on
Commit
74b1521
ยท
verified ยท
1 Parent(s): d091c21

Update ml_engine/processor.py

Browse files
Files changed (1) hide show
  1. ml_engine/processor.py +104 -78
ml_engine/processor.py CHANGED
@@ -1,6 +1,6 @@
1
  # ============================================================
2
  # ๐Ÿง  ml_engine/processor.py
3
- # (V66.0 - GEM-Architect: Direct Context Injection Fixed)
4
  # ============================================================
5
 
6
  import asyncio
@@ -41,48 +41,47 @@ MODEL_V3_PATH = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Production.j
41
  MODEL_V3_FEAT = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Features.json")
42
 
43
  # ============================================================
44
- # ๐ŸŽ›๏ธ SYSTEM LIMITS (Fallback Only)
45
  # ============================================================
46
  class SystemLimits:
47
  """
48
- GEM-Architect: Fallback Values.
49
- The real values are now injected dynamically via 'dynamic_limits' per Coin Type.
50
  """
51
 
52
- # --- Layer 1 ---
53
- L1_MIN_AFFINITY_SCORE = 15.0
 
 
54
 
 
 
 
55
  # --- Layer 2 Weights ---
56
  L2_WEIGHT_TITAN = 0.40
57
- L2_WEIGHT_PATTERNS = 0.30
58
- L2_WEIGHT_MC = 0.10
59
 
60
  # Pattern Config
61
- PATTERN_TF_WEIGHTS = {'15m': 0.40, '1h': 0.30, '5m': 0.20, '4h': 0.10, '1d': 0.00}
62
  PATTERN_THRESH_BULLISH = 0.60
63
  PATTERN_THRESH_BEARISH = 0.40
64
 
65
- # --- Layer 3 ---
66
- L3_CONFIDENCE_THRESHOLD = 0.65
67
- L3_WHALE_IMPACT_MAX = 0.10
68
- L3_NEWS_IMPACT_MAX = 0.05
69
- L3_MC_ADVANCED_MAX = 0.10
70
-
71
- # --- Layer 4 ---
72
- L4_ENTRY_THRESHOLD = 0.40
73
- L4_WEIGHT_ML = 0.60
74
- L4_WEIGHT_OB = 0.40
75
  L4_OB_WALL_RATIO = 0.40
76
 
77
  # --- Layer 0: Hydra & Guardian Defaults ---
78
- HYDRA_CRASH_THRESH = 0.85
79
- HYDRA_GIVEBACK_THRESH = 0.85
80
- HYDRA_STAGNATION_THRESH = 0.80
81
 
82
- LEGACY_V2_PANIC_THRESH = 0.95
83
- LEGACY_V3_HARD_THRESH = 0.95
84
- LEGACY_V3_SOFT_THRESH = 0.88
85
- LEGACY_V3_ULTRA_THRESH = 0.99
86
 
87
  @classmethod
88
  def to_dict(cls) -> Dict[str, Any]:
@@ -114,7 +113,7 @@ class MLProcessor:
114
  v3_features_map_path=MODEL_V3_FEAT
115
  )
116
 
117
- print(f"๐Ÿง  [MLProcessor V66.0] Context-Aware Injection Active.")
118
 
119
  async def initialize(self):
120
  if self.initialized: return
@@ -141,8 +140,7 @@ class MLProcessor:
141
  self.sniper.configure_settings(
142
  threshold=SystemLimits.L4_ENTRY_THRESHOLD,
143
  wall_ratio=SystemLimits.L4_OB_WALL_RATIO,
144
- w_ml=SystemLimits.L4_WEIGHT_ML,
145
- w_ob=SystemLimits.L4_WEIGHT_OB
146
  )
147
  tasks.append(self.sniper.initialize())
148
 
@@ -158,12 +156,11 @@ class MLProcessor:
158
  else:
159
  self.guardian_legacy.initialize()
160
 
161
- # Default init
162
  self.guardian_legacy.configure_thresholds(
163
  v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
164
  v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
165
- v3_soft=SystemLimits.LEGACY_V3_SOFT_THRESH,
166
- v3_ultra=SystemLimits.LEGACY_V3_ULTRA_THRESH
167
  )
168
  print(f" ๐Ÿ›ก๏ธ [Guard 2] Legacy Steward: Active")
169
 
@@ -176,28 +173,27 @@ class MLProcessor:
176
 
177
  async def process_compound_signal(self, raw_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
178
  """
179
- L2 Processing with Dynamic Weight Injection
180
  """
181
  if not self.initialized: await self.initialize()
182
 
183
  symbol = raw_data.get('symbol')
184
  ohlcv_data = raw_data.get('ohlcv')
185
  current_price = raw_data.get('current_price', 0.0)
186
-
187
- # โœ… ุงู„ุญู‚ู† ุงู„ู…ุจุงุดุฑ ู„ู„ู‚ูŠู…
188
  limits = raw_data.get('dynamic_limits', {})
189
 
190
  if not symbol or not ohlcv_data: return None
191
 
192
  try:
193
- # 1. Titan
 
194
  score_titan = 0.5
195
  titan_res = {}
196
  if self.titan:
197
  titan_res = await asyncio.to_thread(self.titan.predict, ohlcv_data)
198
  score_titan = titan_res.get('score', 0.5)
199
 
200
- # 2. Pattern
201
  score_patterns = 0.5
202
  pattern_res = {}
203
  pattern_name = "Neutral"
@@ -206,7 +202,7 @@ class MLProcessor:
206
  score_patterns = pattern_res.get('pattern_confidence', 0.5)
207
  pattern_name = pattern_res.get('pattern_detected', 'Neutral')
208
 
209
- # 3. MC
210
  mc_score = 0.5
211
  if self.mc_analyzer and '1h' in ohlcv_data:
212
  closes = [c[4] for c in ohlcv_data['1h']]
@@ -214,21 +210,36 @@ class MLProcessor:
214
  mc_score = 0.5 + (raw_mc * 5.0)
215
  mc_score = max(0.0, min(1.0, mc_score))
216
 
217
- # 4. Hybrid Calc (Dynamic Injection)
 
 
 
 
 
 
 
 
 
 
 
218
  w_titan = limits.get('w_titan', SystemLimits.L2_WEIGHT_TITAN)
219
  w_patt = limits.get('w_patt', SystemLimits.L2_WEIGHT_PATTERNS)
220
- w_mc = SystemLimits.L2_WEIGHT_MC
221
 
222
  total_w = w_titan + w_patt + w_mc
223
  if total_w <= 0: total_w = 1.0
224
 
225
  hybrid_score = ((score_titan * w_titan) + (score_patterns * w_patt) + (mc_score * w_mc)) / total_w
226
 
 
 
 
 
227
  return {
228
  'symbol': symbol,
229
  'current_price': current_price,
230
  'enhanced_final_score': hybrid_score,
231
- 'dynamic_limits': limits, # ุชู…ุฑูŠุฑ ุงู„ุญุฏูˆุฏ ู„ู„ุทุจู‚ุงุช ุงู„ุชุงู„ูŠุฉ
232
  'asset_regime': raw_data.get('asset_regime', 'UNKNOWN'),
233
  'strategy_type': raw_data.get('strategy_type', 'NORMAL'),
234
  'titan_score': score_titan,
@@ -251,7 +262,6 @@ class MLProcessor:
251
  async def consult_oracle(self, symbol_data: Dict[str, Any]) -> Dict[str, Any]:
252
  if not self.initialized: await self.initialize()
253
 
254
- # โœ… ุงู„ุญู‚ู† ุงู„ู…ุจุงุดุฑ ู„ู„ุนุชุจุฉ
255
  limits = symbol_data.get('dynamic_limits', {})
256
  threshold = limits.get('l3_oracle_thresh', SystemLimits.L3_CONFIDENCE_THRESHOLD)
257
 
@@ -272,9 +282,7 @@ class MLProcessor:
272
  async def check_sniper_entry(self, ohlcv_1m_data: List, order_book_data: Dict[str, Any], context_data: Dict = None) -> Dict[str, Any]:
273
  if not self.initialized: await self.initialize()
274
 
275
- # โœ… ุงู„ุญู‚ู† ุงู„ู…ุจุงุดุฑ
276
  limits = context_data.get('dynamic_limits', {}) if context_data else {}
277
-
278
  thresh = limits.get('l4_sniper_thresh', SystemLimits.L4_ENTRY_THRESHOLD)
279
  wall_r = limits.get('l4_ob_wall_ratio', SystemLimits.L4_OB_WALL_RATIO)
280
 
@@ -283,8 +291,7 @@ class MLProcessor:
283
  self.sniper.configure_settings(
284
  threshold=thresh,
285
  wall_ratio=wall_r,
286
- w_ml=SystemLimits.L4_WEIGHT_ML,
287
- w_ob=SystemLimits.L4_WEIGHT_OB
288
  )
289
  return await self.sniper.check_entry_signal_async(ohlcv_1m_data, order_book_data)
290
 
@@ -292,27 +299,28 @@ class MLProcessor:
292
 
293
  def consult_dual_guardians(self, symbol, ohlcv_1m, ohlcv_5m, ohlcv_15m, trade_context, order_book_snapshot=None):
294
  """
295
- ๐Ÿ’Ž GEM-Architect: ุงู„ุญู‚ู† ุงู„ู…ุจุงุดุฑ ู„ุนุชุจุงุช ุงู„ุญุฑุงุณ ู…ู† ุณูŠุงู‚ ุงู„ุตูู‚ุฉ
296
- ูŠุถู…ู† ุฃู† ูƒู„ ู†ูˆุน ุนู…ู„ุฉ ูŠุชู… ุญู…ุงูŠุชู‡ ุจุงู„ุนุชุจุงุช ุงู„ุฎุงุตุฉ ุจู‡ (High Precision)
297
  """
298
  response = {'action': 'HOLD', 'detailed_log': '', 'probs': {}}
299
-
300
- # 1. ุงุณุชุฎุฑุงุฌ ุงู„ุญุฏูˆุฏ ุงู„ุฏูŠู†ุงู…ูŠูƒูŠุฉ ู…ู† ุณูŠุงู‚ ุงู„ุตูู‚ุฉ
301
- # trade_context ูŠู…ุฑุฑ ู…ู† TradeManager ูˆูŠุญุชูˆูŠ ุนู„ู‰ dynamic_limits
302
  limits = trade_context.get('dynamic_limits', {})
303
 
304
- # ๏ฟฝ๏ฟฝ ุณุญุจ ุงู„ู‚ูŠู… ู…ุน Fallback ุขู…ู†
305
  h_crash_thresh = limits.get('hydra_crash', SystemLimits.HYDRA_CRASH_THRESH)
306
  h_giveback_thresh = limits.get('hydra_giveback', SystemLimits.HYDRA_GIVEBACK_THRESH)
307
  h_stag_thresh = limits.get('hydra_stagnation', SystemLimits.HYDRA_STAGNATION_THRESH)
308
 
309
- l_v2_thresh = limits.get('legacy_v2', SystemLimits.LEGACY_V2_PANIC_THRESH)
310
- l_v3_hard = limits.get('legacy_v3_hard', SystemLimits.LEGACY_V3_HARD_THRESH)
311
- l_v3_soft = limits.get('legacy_v3_soft', SystemLimits.LEGACY_V3_SOFT_THRESH)
312
- l_v3_ultra = limits.get('legacy_v3_ultra', SystemLimits.LEGACY_V3_ULTRA_THRESH)
 
 
 
 
 
313
 
314
  # -----------------------------------------------
315
- # 1. Hydra Execution
316
  # -----------------------------------------------
317
  hydra_result = {'action': 'HOLD', 'reason': 'Disabled', 'probs': {}}
318
  if self.guardian_hydra and self.guardian_hydra.initialized:
@@ -321,32 +329,45 @@ class MLProcessor:
321
 
322
  p_crash = h_probs.get('crash', 0.0)
323
  p_giveback = h_probs.get('giveback', 0.0)
 
324
 
325
- # ๐Ÿ”ฅ ุงุณุชุฎุฏุงู… ุงู„ุนุชุจุงุช ุงู„ู…ุญู‚ูˆู†ุฉ
326
- if hydra_result['action'] == 'HOLD':
327
- if p_crash >= h_crash_thresh:
328
- hydra_result['action'] = 'EXIT_HARD'
329
- hydra_result['reason'] = f"Hydra Crash Risk {p_crash:.2f} >= {h_crash_thresh}"
330
- elif p_giveback >= h_giveback_thresh:
 
 
 
331
  hydra_result['action'] = 'EXIT_SOFT'
332
- hydra_result['reason'] = f"Hydra Giveback Risk {p_giveback:.2f} >= {h_giveback_thresh}"
333
-
 
 
 
 
 
 
 
 
 
 
 
334
  # -----------------------------------------------
335
- # 2. Legacy Execution
336
  # -----------------------------------------------
337
  legacy_result = {'action': 'HOLD', 'reason': 'Disabled', 'scores': {}}
338
  if self.guardian_legacy and self.guardian_legacy.initialized:
339
- # ๐Ÿ”ฅ ุญู‚ู† ุงู„ุฅุนุฏุงุฏุงุช ุฏูŠู†ุงู…ูŠูƒูŠุงู‹ ู‚ุจู„ ุงู„ุชุดุบูŠู„
340
  self.guardian_legacy.configure_thresholds(
341
- v2_panic=l_v2_thresh,
342
- v3_hard=l_v3_hard,
343
- v3_soft=l_v3_soft,
344
- v3_ultra=l_v3_ultra
345
  )
346
 
347
- entry_price = float(trade_context.get('entry_price', 0.0))
348
  vol_30m = trade_context.get('volume_30m_usd', 0.0)
349
-
350
  legacy_result = self.guardian_legacy.analyze_position(
351
  ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price,
352
  order_book=order_book_snapshot,
@@ -361,19 +382,24 @@ class MLProcessor:
361
 
362
  h_c = h_probs.get('crash', 0.0)
363
  h_g = h_probs.get('giveback', 0.0)
364
- h_s = h_probs.get('stagnation', 0.0)
365
  l_v2 = l_scores.get('v2', 0.0)
366
- l_v3 = l_scores.get('v3', 0.0)
367
 
368
- stamp_str = f"๐Ÿฒ[C:{h_c:.0%}|G:{h_g:.0%}] ๐Ÿ•ธ๏ธ[V2:{l_v2:.0%}]"
369
 
370
  final_action = 'HOLD'
371
  final_reason = f"Safe. {stamp_str}"
372
 
373
- if hydra_result['action'] in ['EXIT_HARD', 'EXIT_SOFT', 'TIGHTEN_SL', 'TRAIL_SL']:
 
 
 
 
 
 
 
374
  final_action = hydra_result['action']
375
  final_reason = f"๐Ÿฒ HYDRA: {hydra_result['reason']}"
376
- elif legacy_result['action'] in ['EXIT_HARD', 'EXIT_SOFT']:
377
  final_action = legacy_result['action']
378
  final_reason = f"๐Ÿ•ธ๏ธ LEGACY: {legacy_result['reason']}"
379
 
 
1
  # ============================================================
2
  # ๐Ÿง  ml_engine/processor.py
3
+ # (V67.0 - GEM-Architect: Hybrid Gates & Conditional Hydra)
4
  # ============================================================
5
 
6
  import asyncio
 
41
  MODEL_V3_FEAT = os.path.join(BASE_DIR, "ml_models", "DeepSteward_V3_Features.json")
42
 
43
  # ============================================================
44
+ # ๐ŸŽ›๏ธ SYSTEM LIMITS (Baseline Defaults - Balanced Profile)
45
  # ============================================================
46
  class SystemLimits:
47
  """
48
+ GEM-Architect: Baseline Values (Balanced).
49
+ Real values are injected dynamically from AdaptiveHub.
50
  """
51
 
52
+ # --- Layer 2 Hard Gates (Minimums to Qualify) ---
53
+ L2_GATE_TITAN = 0.70
54
+ L2_GATE_PATTERN = 0.60
55
+ L2_GATE_MC = 0.55
56
 
57
+ # --- Layer 2 Weighted Score Threshold ---
58
+ L2_MIN_SCORE = 0.75
59
+
60
  # --- Layer 2 Weights ---
61
  L2_WEIGHT_TITAN = 0.40
62
+ L2_WEIGHT_PATTERNS = 0.40
63
+ L2_WEIGHT_MC = 0.20
64
 
65
  # Pattern Config
66
+ PATTERN_TF_WEIGHTS = {'1h': 0.35, '15m': 0.25, '1d': 0.20, '5m': 0.10, '4h': 0.10}
67
  PATTERN_THRESH_BULLISH = 0.60
68
  PATTERN_THRESH_BEARISH = 0.40
69
 
70
+ # --- Layer 4 (Oracle) ---
71
+ L3_CONFIDENCE_THRESHOLD = 0.90 # High Precision
72
+
73
+ # --- Layer 5 (Sniper) ---
74
+ L4_ENTRY_THRESHOLD = 0.45
 
 
 
 
 
75
  L4_OB_WALL_RATIO = 0.40
76
 
77
  # --- Layer 0: Hydra & Guardian Defaults ---
78
+ HYDRA_CRASH_THRESH = 0.60 # Increased Capture
79
+ HYDRA_GIVEBACK_THRESH = 0.80 # Needs Activation Condition
80
+ HYDRA_STAGNATION_THRESH = 0.60 # Needs Time Condition
81
 
82
+ # Fixed Legacy Guards
83
+ LEGACY_V2_PANIC_THRESH = 0.98 # High Precision
84
+ LEGACY_V3_HARD_THRESH = 0.95 # High Precision
 
85
 
86
  @classmethod
87
  def to_dict(cls) -> Dict[str, Any]:
 
113
  v3_features_map_path=MODEL_V3_FEAT
114
  )
115
 
116
+ print(f"๐Ÿง  [MLProcessor V67.0] Hybrid Scoring & Conditional Hydra Active.")
117
 
118
  async def initialize(self):
119
  if self.initialized: return
 
140
  self.sniper.configure_settings(
141
  threshold=SystemLimits.L4_ENTRY_THRESHOLD,
142
  wall_ratio=SystemLimits.L4_OB_WALL_RATIO,
143
+ w_ml=0.60, w_ob=0.40
 
144
  )
145
  tasks.append(self.sniper.initialize())
146
 
 
156
  else:
157
  self.guardian_legacy.initialize()
158
 
159
+ # Default init (Fixed values)
160
  self.guardian_legacy.configure_thresholds(
161
  v2_panic=SystemLimits.LEGACY_V2_PANIC_THRESH,
162
  v3_hard=SystemLimits.LEGACY_V3_HARD_THRESH,
163
+ v3_soft=0.88, v3_ultra=0.99
 
164
  )
165
  print(f" ๐Ÿ›ก๏ธ [Guard 2] Legacy Steward: Active")
166
 
 
173
 
174
  async def process_compound_signal(self, raw_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
175
  """
176
+ L2 Processing with Hybrid Gated Scoring (Gate -> Weight -> Final)
177
  """
178
  if not self.initialized: await self.initialize()
179
 
180
  symbol = raw_data.get('symbol')
181
  ohlcv_data = raw_data.get('ohlcv')
182
  current_price = raw_data.get('current_price', 0.0)
 
 
183
  limits = raw_data.get('dynamic_limits', {})
184
 
185
  if not symbol or not ohlcv_data: return None
186
 
187
  try:
188
+ # --- 1. Raw Predictions ---
189
+ # Titan
190
  score_titan = 0.5
191
  titan_res = {}
192
  if self.titan:
193
  titan_res = await asyncio.to_thread(self.titan.predict, ohlcv_data)
194
  score_titan = titan_res.get('score', 0.5)
195
 
196
+ # Patterns
197
  score_patterns = 0.5
198
  pattern_res = {}
199
  pattern_name = "Neutral"
 
202
  score_patterns = pattern_res.get('pattern_confidence', 0.5)
203
  pattern_name = pattern_res.get('pattern_detected', 'Neutral')
204
 
205
+ # Monte Carlo
206
  mc_score = 0.5
207
  if self.mc_analyzer and '1h' in ohlcv_data:
208
  closes = [c[4] for c in ohlcv_data['1h']]
 
210
  mc_score = 0.5 + (raw_mc * 5.0)
211
  mc_score = max(0.0, min(1.0, mc_score))
212
 
213
+ # --- 2. Hybrid Gated Logic ---
214
+ # Extract Gates (Injectable, fallback to SystemLimits)
215
+ gate_titan = limits.get('l2_gate_titan', SystemLimits.L2_GATE_TITAN)
216
+ gate_patt = limits.get('l2_gate_pattern', SystemLimits.L2_GATE_PATTERN)
217
+ gate_mc = limits.get('l2_gate_mc', SystemLimits.L2_GATE_MC)
218
+
219
+ # A) HARD GATES Check (Reject if component is too weak)
220
+ if score_titan < gate_titan: return None
221
+ if score_patterns < gate_patt: return None
222
+ if mc_score < gate_mc: return None
223
+
224
+ # B) Weighted Score Calculation
225
  w_titan = limits.get('w_titan', SystemLimits.L2_WEIGHT_TITAN)
226
  w_patt = limits.get('w_patt', SystemLimits.L2_WEIGHT_PATTERNS)
227
+ w_mc = limits.get('w_mc', SystemLimits.L2_WEIGHT_MC)
228
 
229
  total_w = w_titan + w_patt + w_mc
230
  if total_w <= 0: total_w = 1.0
231
 
232
  hybrid_score = ((score_titan * w_titan) + (score_patterns * w_patt) + (mc_score * w_mc)) / total_w
233
 
234
+ # C) Final Score Gate
235
+ min_l2_score = limits.get('l2_min_score', SystemLimits.L2_MIN_SCORE)
236
+ if hybrid_score < min_l2_score: return None
237
+
238
  return {
239
  'symbol': symbol,
240
  'current_price': current_price,
241
  'enhanced_final_score': hybrid_score,
242
+ 'dynamic_limits': limits,
243
  'asset_regime': raw_data.get('asset_regime', 'UNKNOWN'),
244
  'strategy_type': raw_data.get('strategy_type', 'NORMAL'),
245
  'titan_score': score_titan,
 
262
  async def consult_oracle(self, symbol_data: Dict[str, Any]) -> Dict[str, Any]:
263
  if not self.initialized: await self.initialize()
264
 
 
265
  limits = symbol_data.get('dynamic_limits', {})
266
  threshold = limits.get('l3_oracle_thresh', SystemLimits.L3_CONFIDENCE_THRESHOLD)
267
 
 
282
  async def check_sniper_entry(self, ohlcv_1m_data: List, order_book_data: Dict[str, Any], context_data: Dict = None) -> Dict[str, Any]:
283
  if not self.initialized: await self.initialize()
284
 
 
285
  limits = context_data.get('dynamic_limits', {}) if context_data else {}
 
286
  thresh = limits.get('l4_sniper_thresh', SystemLimits.L4_ENTRY_THRESHOLD)
287
  wall_r = limits.get('l4_ob_wall_ratio', SystemLimits.L4_OB_WALL_RATIO)
288
 
 
291
  self.sniper.configure_settings(
292
  threshold=thresh,
293
  wall_ratio=wall_r,
294
+ w_ml=0.60, w_ob=0.40 # Fixed Weights per diagnosis
 
295
  )
296
  return await self.sniper.check_entry_signal_async(ohlcv_1m_data, order_book_data)
297
 
 
299
 
300
  def consult_dual_guardians(self, symbol, ohlcv_1m, ohlcv_5m, ohlcv_15m, trade_context, order_book_snapshot=None):
301
  """
302
+ ๐Ÿ’Ž GEM-Architect: Conditional Hydra Logic & Fixed Legacy
 
303
  """
304
  response = {'action': 'HOLD', 'detailed_log': '', 'probs': {}}
 
 
 
305
  limits = trade_context.get('dynamic_limits', {})
306
 
307
+ # --- Thresholds ---
308
  h_crash_thresh = limits.get('hydra_crash', SystemLimits.HYDRA_CRASH_THRESH)
309
  h_giveback_thresh = limits.get('hydra_giveback', SystemLimits.HYDRA_GIVEBACK_THRESH)
310
  h_stag_thresh = limits.get('hydra_stagnation', SystemLimits.HYDRA_STAGNATION_THRESH)
311
 
312
+ # --- Context Data for Conditions ---
313
+ entry_price = float(trade_context.get('entry_price', 0.0))
314
+ current_price = 0.0
315
+ if ohlcv_1m: current_price = float(ohlcv_1m[-1][4])
316
+
317
+ highest_price = trade_context.get('highest_price', entry_price)
318
+ max_pnl_pct = ((highest_price - entry_price) / entry_price) * 100 if entry_price > 0 else 0.0
319
+
320
+ time_in_trade_mins = trade_context.get('time_in_trade_mins', 0.0)
321
 
322
  # -----------------------------------------------
323
+ # 1. Hydra Execution (Conditional)
324
  # -----------------------------------------------
325
  hydra_result = {'action': 'HOLD', 'reason': 'Disabled', 'probs': {}}
326
  if self.guardian_hydra and self.guardian_hydra.initialized:
 
329
 
330
  p_crash = h_probs.get('crash', 0.0)
331
  p_giveback = h_probs.get('giveback', 0.0)
332
+ p_stagnation = h_probs.get('stagnation', 0.0)
333
 
334
+ # ๐Ÿ›‘ CRASH: Always Active (Safety Net)
335
+ if p_crash >= h_crash_thresh:
336
+ hydra_result['action'] = 'EXIT_HARD'
337
+ hydra_result['reason'] = f"Hydra Crash Risk {p_crash:.2f} >= {h_crash_thresh}"
338
+
339
+ # ๐Ÿ›‘ GIVEBACK: Conditional Activation
340
+ # Trigger ONLY if we had decent profit (>0.6%)
341
+ elif p_giveback >= h_giveback_thresh:
342
+ if max_pnl_pct >= 0.6:
343
  hydra_result['action'] = 'EXIT_SOFT'
344
+ hydra_result['reason'] = f"Hydra Giveback {p_giveback:.2f} (Max PnL {max_pnl_pct:.2f}%)"
345
+ else:
346
+ hydra_result['action'] = 'HOLD' # Ignore noise if no profit to protect
347
+
348
+ # ๐Ÿ›‘ STAGNATION: Conditional Activation (Time)
349
+ # Trigger ONLY if stuck for > 90 mins
350
+ elif p_stagnation >= h_stag_thresh:
351
+ if time_in_trade_mins > 90:
352
+ hydra_result['action'] = 'EXIT_SOFT'
353
+ hydra_result['reason'] = f"Hydra Stagnation {p_stagnation:.2f} (>90m)"
354
+ else:
355
+ hydra_result['action'] = 'HOLD' # Too early to judge stagnation
356
+
357
  # -----------------------------------------------
358
+ # 2. Legacy Execution (Fixed Thresholds)
359
  # -----------------------------------------------
360
  legacy_result = {'action': 'HOLD', 'reason': 'Disabled', 'scores': {}}
361
  if self.guardian_legacy and self.guardian_legacy.initialized:
362
+ # Fixed V2/V3 thresholds per diagnosis
363
  self.guardian_legacy.configure_thresholds(
364
+ v2_panic=0.98,
365
+ v3_hard=0.95,
366
+ v3_soft=0.88,
367
+ v3_ultra=0.99
368
  )
369
 
 
370
  vol_30m = trade_context.get('volume_30m_usd', 0.0)
 
371
  legacy_result = self.guardian_legacy.analyze_position(
372
  ohlcv_1m, ohlcv_5m, ohlcv_15m, entry_price,
373
  order_book=order_book_snapshot,
 
382
 
383
  h_c = h_probs.get('crash', 0.0)
384
  h_g = h_probs.get('giveback', 0.0)
 
385
  l_v2 = l_scores.get('v2', 0.0)
 
386
 
387
+ stamp_str = f"๐Ÿฒ[C:{h_c:.2f}|G:{h_g:.2f}] ๐Ÿ•ธ๏ธ[V2:{l_v2:.2f}]"
388
 
389
  final_action = 'HOLD'
390
  final_reason = f"Safe. {stamp_str}"
391
 
392
+ # Priority: Hydra Crash > Legacy V2 > Hydra Giveback > Legacy V3
393
+ if hydra_result['action'] in ['EXIT_HARD']:
394
+ final_action = hydra_result['action']
395
+ final_reason = f"๐Ÿฒ HYDRA: {hydra_result['reason']}"
396
+ elif legacy_result['action'] in ['EXIT_HARD']:
397
+ final_action = legacy_result['action']
398
+ final_reason = f"๐Ÿ•ธ๏ธ LEGACY: {legacy_result['reason']}"
399
+ elif hydra_result['action'] in ['EXIT_SOFT']:
400
  final_action = hydra_result['action']
401
  final_reason = f"๐Ÿฒ HYDRA: {hydra_result['reason']}"
402
+ elif legacy_result['action'] in ['EXIT_SOFT']:
403
  final_action = legacy_result['action']
404
  final_reason = f"๐Ÿ•ธ๏ธ LEGACY: {legacy_result['reason']}"
405