Spaces:
Paused
Paused
Update trade_manager.py
Browse files- trade_manager.py +30 -26
trade_manager.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# trade_manager.py
|
| 2 |
-
# (
|
| 3 |
# Linked with AdaptiveHub via register_trade_outcome
|
| 4 |
|
| 5 |
import asyncio
|
|
@@ -22,7 +22,7 @@ class TradeManager:
|
|
| 22 |
self.running = True
|
| 23 |
|
| 24 |
# متغير لتمرير الرسائل إلى الواجهة (UI Log Bridge)
|
| 25 |
-
self.latest_guardian_log = "🛡️ Guardian
|
| 26 |
|
| 27 |
# إعدادات الرسوم
|
| 28 |
self.FEE_RATE = 0.001
|
|
@@ -39,7 +39,7 @@ class TradeManager:
|
|
| 39 |
}
|
| 40 |
|
| 41 |
self.execution_lock = asyncio.Lock()
|
| 42 |
-
print(f"🛡️ [TradeManager
|
| 43 |
|
| 44 |
async def initialize_sentry_exchanges(self):
|
| 45 |
print("🛡️ [TradeManager] Syncing state with R2...")
|
|
@@ -226,10 +226,10 @@ class TradeManager:
|
|
| 226 |
traceback.print_exc()
|
| 227 |
|
| 228 |
# ==============================================================================
|
| 229 |
-
# 🛡️
|
| 230 |
# ==============================================================================
|
| 231 |
async def _guardian_loop(self, symbol: str):
|
| 232 |
-
print(f"🛡️ [
|
| 233 |
last_ai_check_time = 0
|
| 234 |
|
| 235 |
while self.running:
|
|
@@ -263,9 +263,10 @@ class TradeManager:
|
|
| 263 |
await self._execute_exit(symbol, trade['sl_price'], "SL_HIT")
|
| 264 |
break
|
| 265 |
|
| 266 |
-
#
|
| 267 |
if time.time() - last_ai_check_time > 60:
|
| 268 |
-
|
|
|
|
| 269 |
t5 = self.data_manager.get_latest_ohlcv(symbol, '5m', 100)
|
| 270 |
t15 = self.data_manager.get_latest_ohlcv(symbol, '15m', 100)
|
| 271 |
|
|
@@ -274,7 +275,8 @@ class TradeManager:
|
|
| 274 |
except:
|
| 275 |
continue
|
| 276 |
|
| 277 |
-
|
|
|
|
| 278 |
context_data = {
|
| 279 |
'entry_price': trade['entry_price'],
|
| 280 |
'tp_price': trade['tp_price'],
|
|
@@ -282,37 +284,34 @@ class TradeManager:
|
|
| 282 |
'entry_time': trade['entry_time'],
|
| 283 |
'oracle_conf': trade.get('decision_data', {}).get('oracle_conf', 0.8),
|
| 284 |
'l2_score': trade.get('l1_score', 0.7),
|
| 285 |
-
'
|
| 286 |
-
'highest_price': float(trade['highest_price'])
|
|
|
|
| 287 |
}
|
| 288 |
|
| 289 |
-
#
|
| 290 |
-
decision = self.processor.
|
| 291 |
|
| 292 |
action = decision.get('action', 'HOLD')
|
| 293 |
-
|
| 294 |
-
p_crash = probs.get('crash', 0.0)
|
| 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%} | "
|
| 301 |
-
f"Stagnation: {p_stag:.0%}")
|
| 302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
self.latest_guardian_log = log_msg
|
| 304 |
|
| 305 |
if action in ['EXIT_HARD', 'EXIT_SOFT']:
|
| 306 |
-
print(f"🐲 [
|
| 307 |
async with self.execution_lock:
|
| 308 |
-
await self._execute_exit(symbol, current_ticker_price, f"
|
| 309 |
break
|
| 310 |
|
| 311 |
elif action == 'TIGHTEN_SL':
|
| 312 |
entry_p = float(trade['entry_price'])
|
| 313 |
curr_sl = float(trade['sl_price'])
|
| 314 |
if curr_sl < entry_p:
|
| 315 |
-
print(f"
|
| 316 |
self.open_positions[symbol]['sl_price'] = entry_p
|
| 317 |
self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
|
| 318 |
await self.r2.save_open_trades_async(list(self.open_positions.values()))
|
|
@@ -324,12 +323,12 @@ class TradeManager:
|
|
| 324 |
potential_sl = entry_p + ((curr_p - entry_p) * 0.5)
|
| 325 |
curr_sl = float(trade['sl_price'])
|
| 326 |
if potential_sl > curr_sl:
|
| 327 |
-
print(f"
|
| 328 |
self.open_positions[symbol]['sl_price'] = potential_sl
|
| 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"📡
|
| 333 |
|
| 334 |
last_ai_check_time = time.time()
|
| 335 |
self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
|
|
@@ -407,15 +406,20 @@ class TradeManager:
|
|
| 407 |
usd_impact = change_pct * position_size_usd
|
| 408 |
is_good_exit = change_pct < 0
|
| 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)
|
|
|
|
| 1 |
# trade_manager.py
|
| 2 |
+
# (V34.0 - GEM-Architect: Dual-Core Guardian Edition)
|
| 3 |
# Linked with AdaptiveHub via register_trade_outcome
|
| 4 |
|
| 5 |
import asyncio
|
|
|
|
| 22 |
self.running = True
|
| 23 |
|
| 24 |
# متغير لتمرير الرسائل إلى الواجهة (UI Log Bridge)
|
| 25 |
+
self.latest_guardian_log = "🛡️ Guardian Dual-Core Initialized."
|
| 26 |
|
| 27 |
# إعدادات الرسوم
|
| 28 |
self.FEE_RATE = 0.001
|
|
|
|
| 39 |
}
|
| 40 |
|
| 41 |
self.execution_lock = asyncio.Lock()
|
| 42 |
+
print(f"🛡️ [TradeManager V34.0] Dual-Core Engine Online.")
|
| 43 |
|
| 44 |
async def initialize_sentry_exchanges(self):
|
| 45 |
print("🛡️ [TradeManager] Syncing state with R2...")
|
|
|
|
| 226 |
traceback.print_exc()
|
| 227 |
|
| 228 |
# ==============================================================================
|
| 229 |
+
# 🛡️ Dual-Core Guardian Loop (The Active Manager)
|
| 230 |
# ==============================================================================
|
| 231 |
async def _guardian_loop(self, symbol: str):
|
| 232 |
+
print(f"🛡️ [Dual-Core] STARTING WATCH for {symbol}...")
|
| 233 |
last_ai_check_time = 0
|
| 234 |
|
| 235 |
while self.running:
|
|
|
|
| 263 |
await self._execute_exit(symbol, trade['sl_price'], "SL_HIT")
|
| 264 |
break
|
| 265 |
|
| 266 |
+
# Dual AI Check (Processor determines Policy)
|
| 267 |
if time.time() - last_ai_check_time > 60:
|
| 268 |
+
# ✅ زيادة الحد الأدنى للشمعات لدعم الحارس القديم (يحتاج EMA200)
|
| 269 |
+
t1 = self.data_manager.get_latest_ohlcv(symbol, '1m', 300)
|
| 270 |
t5 = self.data_manager.get_latest_ohlcv(symbol, '5m', 100)
|
| 271 |
t15 = self.data_manager.get_latest_ohlcv(symbol, '15m', 100)
|
| 272 |
|
|
|
|
| 275 |
except:
|
| 276 |
continue
|
| 277 |
|
| 278 |
+
# التحقق من كفاية البيانات للحارس القديم
|
| 279 |
+
if d1 and d5 and d15 and len(d1) >= 200:
|
| 280 |
context_data = {
|
| 281 |
'entry_price': trade['entry_price'],
|
| 282 |
'tp_price': trade['tp_price'],
|
|
|
|
| 284 |
'entry_time': trade['entry_time'],
|
| 285 |
'oracle_conf': trade.get('decision_data', {}).get('oracle_conf', 0.8),
|
| 286 |
'l2_score': trade.get('l1_score', 0.7),
|
| 287 |
+
'target_class_int': trade.get('target_class_int', 3),
|
| 288 |
+
'highest_price': float(trade['highest_price']),
|
| 289 |
+
'time_in_trade_mins': (datetime.now() - datetime.fromisoformat(trade['entry_time'])).total_seconds() / 60
|
| 290 |
}
|
| 291 |
|
| 292 |
+
# ✅ استشارة الحارس المزدوج (Dual Guardians)
|
| 293 |
+
decision = self.processor.consult_dual_guardians(symbol, d1, d5, d15, context_data)
|
| 294 |
|
| 295 |
action = decision.get('action', 'HOLD')
|
| 296 |
+
reason = decision.get('reason', '')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 297 |
|
| 298 |
+
# دمج النتائج (Probs من الهيدرا أو Scores من القديم)
|
| 299 |
+
ai_metrics = decision.get('probs') or decision.get('scores') or {}
|
| 300 |
+
|
| 301 |
+
log_msg = f"🛡️ {action} | {reason}"
|
| 302 |
self.latest_guardian_log = log_msg
|
| 303 |
|
| 304 |
if action in ['EXIT_HARD', 'EXIT_SOFT']:
|
| 305 |
+
print(f"🐲 [Dual-Core Trigger] {action}: {reason}")
|
| 306 |
async with self.execution_lock:
|
| 307 |
+
await self._execute_exit(symbol, current_ticker_price, f"DualGuard_{action}", ai_scores=ai_metrics)
|
| 308 |
break
|
| 309 |
|
| 310 |
elif action == 'TIGHTEN_SL':
|
| 311 |
entry_p = float(trade['entry_price'])
|
| 312 |
curr_sl = float(trade['sl_price'])
|
| 313 |
if curr_sl < entry_p:
|
| 314 |
+
print(f"🛡️ [Dual-Core] TIGHTEN_SL: Moving Stop to Entry {entry_p}")
|
| 315 |
self.open_positions[symbol]['sl_price'] = entry_p
|
| 316 |
self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
|
| 317 |
await self.r2.save_open_trades_async(list(self.open_positions.values()))
|
|
|
|
| 323 |
potential_sl = entry_p + ((curr_p - entry_p) * 0.5)
|
| 324 |
curr_sl = float(trade['sl_price'])
|
| 325 |
if potential_sl > curr_sl:
|
| 326 |
+
print(f"🛡️ [Dual-Core] TRAIL_SL: Moving Stop to {potential_sl:.4f}")
|
| 327 |
self.open_positions[symbol]['sl_price'] = potential_sl
|
| 328 |
self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
|
| 329 |
await self.r2.save_open_trades_async(list(self.open_positions.values()))
|
| 330 |
else:
|
| 331 |
+
self.latest_guardian_log = f"📡 Gathering Deep Data (Need 200+ candles)..."
|
| 332 |
|
| 333 |
last_ai_check_time = time.time()
|
| 334 |
self.open_positions[symbol]['last_update'] = datetime.now().isoformat()
|
|
|
|
| 406 |
usd_impact = change_pct * position_size_usd
|
| 407 |
is_good_exit = change_pct < 0
|
| 408 |
|
| 409 |
+
# تحديث الإحصائيات العامة
|
| 410 |
self._update_specific_stat("hybrid", is_good_exit, usd_impact)
|
| 411 |
|
| 412 |
+
# تحديث الإحصائيات التفصيلية (سواء جاءت من Hydra probs أو Legacy scores)
|
| 413 |
if ai_scores:
|
| 414 |
+
# Hydra Keys
|
| 415 |
if ai_scores.get('crash', 0) >= 0.60:
|
| 416 |
self._update_specific_stat("crash", is_good_exit, usd_impact)
|
| 417 |
if ai_scores.get('giveback', 0) >= 0.70:
|
| 418 |
self._update_specific_stat("giveback", is_good_exit, usd_impact)
|
| 419 |
if ai_scores.get('stagnation', 0) >= 0.50:
|
| 420 |
self._update_specific_stat("stagnation", is_good_exit, usd_impact)
|
| 421 |
+
|
| 422 |
+
# Legacy Keys (ممكن تحويلها إذا لزم الأمر، لكن حالياً نتركها ضمن hybrid)
|
| 423 |
|
| 424 |
record = {"symbol": symbol, "exit_price": exit_price, "price_15m": curr, "usd_impact": usd_impact, "verdict": "SUCCESS" if is_good_exit else "MISS"}
|
| 425 |
await self.r2.append_deep_steward_audit(record)
|