Riy777 commited on
Commit
0b6828b
·
verified ·
1 Parent(s): ed354c8

Update trade_manager.py

Browse files
Files changed (1) hide show
  1. trade_manager.py +13 -33
trade_manager.py CHANGED
@@ -1,10 +1,6 @@
1
  # trade_manager.py
2
- # (V28.1 - GEM-Architect: Clear Hydra Logging Edition)
3
- # Fixes:
4
- # 1. Full wording for Hydra Stats (Crash, Giveback, Stagnation).
5
- # 2. Handles "Cold Start" zeros by showing "Gathering Data" status.
6
- # 3. Improved formatting to percentages for better readability.
7
- # 4. [GEM-FIX] Added 'highest_price' tracking for accurate Giveback detection.
8
 
9
  import asyncio
10
  import uuid
@@ -18,7 +14,7 @@ class TradeManager:
18
  self.r2 = r2_service
19
  self.data_manager = data_manager
20
  self.processor = processor
21
- self.learning_hub = None
22
 
23
  self.open_positions = {}
24
  self.watchlist = {}
@@ -34,17 +30,16 @@ class TradeManager:
34
  # إعدادات المراجعة الاستراتيجية (Oracle Re-check)
35
  self.ORACLE_CHECK_INTERVAL = 900 # كل 15 دقيقة
36
 
37
- # إحصائيات AI (محدثة لتعكس رؤوس Hydra)
38
  self.ai_stats = {
39
  "hybrid": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
40
- # رؤوس الهيدرا الثلاثة
41
  "crash": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
42
  "giveback": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
43
  "stagnation": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0}
44
  }
45
 
46
  self.execution_lock = asyncio.Lock()
47
- print(f"🛡️ [TradeManager V28.1] Hydra Policy Engine Online (Verbose Mode).")
48
 
49
  async def initialize_sentry_exchanges(self):
50
  print("🛡️ [TradeManager] Syncing state with R2...")
@@ -178,7 +173,6 @@ class TradeManager:
178
  oracle_strength = float(signal_data.get('strength', 0.5))
179
  oracle_class = signal_data.get('target_class', 'TP2')
180
 
181
- # Map target class to int for Hydra if needed (TP1=1, TP2=2...)
182
  target_class_int = 3
183
  if isinstance(oracle_class, str) and oracle_class.startswith('TP'):
184
  try: target_class_int = int(oracle_class[-1])
@@ -204,13 +198,11 @@ class TradeManager:
204
  'entry_capital': current_capital,
205
  'entry_fee_usd': entry_fee_usd,
206
  'l1_score': float(signal_data.get('enhanced_final_score', 0.0)),
207
- # نحفظ target_class كـ int لسهولة استخدامه في Hydra لاحقاً
208
  'target_class_int': target_class_int,
209
  'decision_data': {
210
  'components': signal_data.get('components', {}),
211
  'oracle_conf': signal_data.get('confidence', 0)
212
  },
213
- # [GEM-FIX] Initialize highest_price at entry
214
  'highest_price': current_price
215
  }
216
 
@@ -249,18 +241,16 @@ class TradeManager:
249
  trade = self.open_positions.get(symbol)
250
  if not trade:
251
  break
252
- # 1. تحديث السعر الفوري
253
  current_ticker_price = await self.data_manager.get_latest_price_async(symbol)
254
 
255
- # [GEM-FIX] Track Highest Price for Giveback Logic (Dynamic Update)
256
  if 'highest_price' not in trade:
257
  trade['highest_price'] = float(trade['entry_price'])
258
 
259
  if current_ticker_price > float(trade['highest_price']):
260
  trade['highest_price'] = current_ticker_price
261
- # Note: We update memory instantly. Persistence happens on next save event.
262
 
263
- # 2. فحص الحدود الصلبة (Hard Limits)
264
  if current_ticker_price >= trade['tp_price']:
265
  print(f"🎯 [TP HIT] Price {current_ticker_price} hit Target {trade['tp_price']}")
266
  async with self.execution_lock:
@@ -273,9 +263,9 @@ class TradeManager:
273
  await self._execute_exit(symbol, trade['sl_price'], "SL_HIT")
274
  break
275
 
276
- # 3. الحارس الذكي (Hydra AI Check) - كل دقيقة
277
  if time.time() - last_ai_check_time > 60:
278
- t1 = self.data_manager.get_latest_ohlcv(symbol, '1m', 200) # نحتاج تاريخ أطول للميزات
279
  t5 = self.data_manager.get_latest_ohlcv(symbol, '5m', 100)
280
  t15 = self.data_manager.get_latest_ohlcv(symbol, '15m', 100)
281
 
@@ -284,9 +274,7 @@ class TradeManager:
284
  except:
285
  continue
286
 
287
- # [MODIFIED] Clear Check: Only run if data is sufficient
288
  if d1 and d5 and d15 and len(d1) >= 100:
289
- # ✅ تجهيز سياق الصفقة لـ Hydra
290
  context_data = {
291
  'entry_price': trade['entry_price'],
292
  'tp_price': trade['tp_price'],
@@ -295,11 +283,10 @@ class TradeManager:
295
  'oracle_conf': trade.get('decision_data', {}).get('oracle_conf', 0.8),
296
  'l2_score': trade.get('l1_score', 0.7),
297
  'target_class': trade.get('target_class_int', 3),
298
- # [GEM-FIX] Pass the highest price reached so far
299
  'highest_price': float(trade['highest_price'])
300
  }
301
 
302
- # استدعاء الحارس عبر Processor
303
  decision = self.processor.consult_guardian(symbol, d1, d5, d15, context_data)
304
 
305
  action = decision.get('action', 'HOLD')
@@ -308,7 +295,6 @@ class TradeManager:
308
  p_giveback = probs.get('giveback', 0.0)
309
  p_stag = probs.get('stagnation', 0.0)
310
 
311
- # [UPDATED LOG] Full words + Percentage display
312
  log_msg = (f"🛡️ {action} | "
313
  f"Crash: {p_crash:.0%} | "
314
  f"Giveback: {p_giveback:.0%} | "
@@ -316,7 +302,6 @@ class TradeManager:
316
 
317
  self.latest_guardian_log = log_msg
318
 
319
- # تنفيذ القرار
320
  if action in ['EXIT_HARD', 'EXIT_SOFT']:
321
  print(f"🐲 [Hydra] {action}: {decision.get('reason')}")
322
  async with self.execution_lock:
@@ -344,13 +329,12 @@ class TradeManager:
344
  self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
345
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
346
  else:
347
- # [ADDED] Inform user why zeros/waiting exists
348
  self.latest_guardian_log = f"📡 Hydra: Gathering Data (Need 100 candles)..."
349
 
350
  last_ai_check_time = time.time()
351
  self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
352
 
353
- # 4. الطبقة الاستراتيجية (Oracle Re-Check)
354
  last_oracle_check = datetime.fromisoformat(trade.get('last_oracle_check', datetime.now().isoformat()))
355
  if (datetime.now() - last_oracle_check).total_seconds() > self.ORACLE_CHECK_INTERVAL:
356
  self.open_positions[symbol]['last_oracle_check'] = datetime.now().isoformat()
@@ -425,23 +409,21 @@ class TradeManager:
425
 
426
  self._update_specific_stat("hybrid", is_good_exit, usd_impact)
427
 
428
- # تحديث إحصائيات Hydra
429
  if ai_scores:
430
- # إذا كان الاحتمال عالياً وتصرفنا بناءً عليه، هل كان التصرف صحيحاً؟
431
  if ai_scores.get('crash', 0) >= 0.60:
432
  self._update_specific_stat("crash", is_good_exit, usd_impact)
433
  if ai_scores.get('giveback', 0) >= 0.70:
434
  self._update_specific_stat("giveback", is_good_exit, usd_impact)
435
  if ai_scores.get('stagnation', 0) >= 0.50:
436
- # للركود، الخروج الجيد يعني السعر لم يصعد بقوة بعدنا
437
  self._update_specific_stat("stagnation", is_good_exit, usd_impact)
438
 
439
  record = {"symbol": symbol, "exit_price": exit_price, "price_15m": curr, "usd_impact": usd_impact, "verdict": "SUCCESS" if is_good_exit else "MISS"}
440
  await self.r2.append_deep_steward_audit(record)
441
 
 
442
  if self.learning_hub and trade_obj:
443
  trade_obj['pnl_percent'] = trade_obj.get('profit_pct', 0.0)
444
- await self.learning_hub.analyze_trade_and_learn(trade_obj, trade_obj.get('exit_reason', 'UNKNOWN'))
445
 
446
  except Exception as e:
447
  print(f"⚠️ [Ghost/Learning Error] {e}")
@@ -458,7 +440,6 @@ class TradeManager:
458
  entry_capital = float(trade.get('entry_capital', 100.0))
459
  entry_fee_usd = float(trade.get('entry_fee_usd', 0.0))
460
 
461
- # Spot PnL
462
  exit_value_gross = (exit_price / entry_price) * entry_capital
463
  exit_fee_usd = exit_value_gross * self.FEE_RATE
464
  net_exit_value = exit_value_gross - exit_fee_usd
@@ -498,7 +479,6 @@ class TradeManager:
498
 
499
  self._launch_post_exit_analysis(symbol, exit_price, trade.get('exit_time'), entry_capital, ai_scores, trade)
500
 
501
- # Update UI Log
502
  self.latest_guardian_log = f"✅ Closed {symbol} ({reason})"
503
 
504
  if symbol in self.sentry_tasks:
 
1
  # trade_manager.py
2
+ # (V33.0 - GEM-Architect: Adaptive Feedback Loop Edition)
3
+ # Linked with AdaptiveHub via register_trade_outcome
 
 
 
 
4
 
5
  import asyncio
6
  import uuid
 
14
  self.r2 = r2_service
15
  self.data_manager = data_manager
16
  self.processor = processor
17
+ self.learning_hub = None # سيتم حقن AdaptiveHub هنا من app.py
18
 
19
  self.open_positions = {}
20
  self.watchlist = {}
 
30
  # إعدادات المراجعة الاستراتيجية (Oracle Re-check)
31
  self.ORACLE_CHECK_INTERVAL = 900 # كل 15 دقيقة
32
 
33
+ # إحصائيات AI
34
  self.ai_stats = {
35
  "hybrid": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
 
36
  "crash": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
37
  "giveback": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0},
38
  "stagnation": {"total": 0, "good": 0, "saved": 0.0, "missed": 0.0}
39
  }
40
 
41
  self.execution_lock = asyncio.Lock()
42
+ print(f"🛡️ [TradeManager V33.0] Adaptive Feedback Engine Online.")
43
 
44
  async def initialize_sentry_exchanges(self):
45
  print("🛡️ [TradeManager] Syncing state with R2...")
 
173
  oracle_strength = float(signal_data.get('strength', 0.5))
174
  oracle_class = signal_data.get('target_class', 'TP2')
175
 
 
176
  target_class_int = 3
177
  if isinstance(oracle_class, str) and oracle_class.startswith('TP'):
178
  try: target_class_int = int(oracle_class[-1])
 
198
  'entry_capital': current_capital,
199
  'entry_fee_usd': entry_fee_usd,
200
  'l1_score': float(signal_data.get('enhanced_final_score', 0.0)),
 
201
  'target_class_int': target_class_int,
202
  'decision_data': {
203
  'components': signal_data.get('components', {}),
204
  'oracle_conf': signal_data.get('confidence', 0)
205
  },
 
206
  'highest_price': current_price
207
  }
208
 
 
241
  trade = self.open_positions.get(symbol)
242
  if not trade:
243
  break
244
+
245
  current_ticker_price = await self.data_manager.get_latest_price_async(symbol)
246
 
 
247
  if 'highest_price' not in trade:
248
  trade['highest_price'] = float(trade['entry_price'])
249
 
250
  if current_ticker_price > float(trade['highest_price']):
251
  trade['highest_price'] = current_ticker_price
 
252
 
253
+ # Hard Limits
254
  if current_ticker_price >= trade['tp_price']:
255
  print(f"🎯 [TP HIT] Price {current_ticker_price} hit Target {trade['tp_price']}")
256
  async with self.execution_lock:
 
263
  await self._execute_exit(symbol, trade['sl_price'], "SL_HIT")
264
  break
265
 
266
+ # Hydra AI Check (Processor determines Policy)
267
  if time.time() - last_ai_check_time > 60:
268
+ t1 = self.data_manager.get_latest_ohlcv(symbol, '1m', 200)
269
  t5 = self.data_manager.get_latest_ohlcv(symbol, '5m', 100)
270
  t15 = self.data_manager.get_latest_ohlcv(symbol, '15m', 100)
271
 
 
274
  except:
275
  continue
276
 
 
277
  if d1 and d5 and d15 and len(d1) >= 100:
 
278
  context_data = {
279
  'entry_price': trade['entry_price'],
280
  'tp_price': trade['tp_price'],
 
283
  'oracle_conf': trade.get('decision_data', {}).get('oracle_conf', 0.8),
284
  'l2_score': trade.get('l1_score', 0.7),
285
  'target_class': trade.get('target_class_int', 3),
 
286
  'highest_price': float(trade['highest_price'])
287
  }
288
 
289
+ # Processor consults Guardian AND applies SystemLimits overrides
290
  decision = self.processor.consult_guardian(symbol, d1, d5, d15, context_data)
291
 
292
  action = decision.get('action', 'HOLD')
 
295
  p_giveback = probs.get('giveback', 0.0)
296
  p_stag = probs.get('stagnation', 0.0)
297
 
 
298
  log_msg = (f"🛡️ {action} | "
299
  f"Crash: {p_crash:.0%} | "
300
  f"Giveback: {p_giveback:.0%} | "
 
302
 
303
  self.latest_guardian_log = log_msg
304
 
 
305
  if action in ['EXIT_HARD', 'EXIT_SOFT']:
306
  print(f"🐲 [Hydra] {action}: {decision.get('reason')}")
307
  async with self.execution_lock:
 
329
  self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
330
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
331
  else:
 
332
  self.latest_guardian_log = f"📡 Hydra: Gathering Data (Need 100 candles)..."
333
 
334
  last_ai_check_time = time.time()
335
  self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
336
 
337
+ # 4. Oracle Re-Check
338
  last_oracle_check = datetime.fromisoformat(trade.get('last_oracle_check', datetime.now().isoformat()))
339
  if (datetime.now() - last_oracle_check).total_seconds() > self.ORACLE_CHECK_INTERVAL:
340
  self.open_positions[symbol]['last_oracle_check'] = datetime.now().isoformat()
 
409
 
410
  self._update_specific_stat("hybrid", is_good_exit, usd_impact)
411
 
 
412
  if ai_scores:
 
413
  if ai_scores.get('crash', 0) >= 0.60:
414
  self._update_specific_stat("crash", is_good_exit, usd_impact)
415
  if ai_scores.get('giveback', 0) >= 0.70:
416
  self._update_specific_stat("giveback", is_good_exit, usd_impact)
417
  if ai_scores.get('stagnation', 0) >= 0.50:
 
418
  self._update_specific_stat("stagnation", is_good_exit, usd_impact)
419
 
420
  record = {"symbol": symbol, "exit_price": exit_price, "price_15m": curr, "usd_impact": usd_impact, "verdict": "SUCCESS" if is_good_exit else "MISS"}
421
  await self.r2.append_deep_steward_audit(record)
422
 
423
+ # ✅ [Adaptive Loop] Feed results back to AdaptiveHub
424
  if self.learning_hub and trade_obj:
425
  trade_obj['pnl_percent'] = trade_obj.get('profit_pct', 0.0)
426
+ await self.learning_hub.register_trade_outcome(trade_obj)
427
 
428
  except Exception as e:
429
  print(f"⚠️ [Ghost/Learning Error] {e}")
 
440
  entry_capital = float(trade.get('entry_capital', 100.0))
441
  entry_fee_usd = float(trade.get('entry_fee_usd', 0.0))
442
 
 
443
  exit_value_gross = (exit_price / entry_price) * entry_capital
444
  exit_fee_usd = exit_value_gross * self.FEE_RATE
445
  net_exit_value = exit_value_gross - exit_fee_usd
 
479
 
480
  self._launch_post_exit_analysis(symbol, exit_price, trade.get('exit_time'), entry_capital, ai_scores, trade)
481
 
 
482
  self.latest_guardian_log = f"✅ Closed {symbol} ({reason})"
483
 
484
  if symbol in self.sentry_tasks: