Riy777 commited on
Commit
7bd954f
·
verified ·
1 Parent(s): 39397dc

Update trade_manager.py

Browse files
Files changed (1) hide show
  1. trade_manager.py +9 -36
trade_manager.py CHANGED
@@ -1,4 +1,4 @@
1
- # trade_manager.py (V15.5 - GEM-Architect Fix: Strict Singleton Locking)
2
  import asyncio
3
  import json
4
  import uuid
@@ -22,7 +22,7 @@ class TradeManager:
22
 
23
  self.execution_lock = asyncio.Lock()
24
 
25
- print(f"🛡️ [TradeManager V15.5] Sentry Module Initialized (Strict Single Trade).")
26
  if self.guard:
27
  print(f" -> Guard V2 (Exit Protector) CREATED.")
28
  else:
@@ -39,7 +39,6 @@ class TradeManager:
39
  async def sync_internal_state_with_r2(self):
40
  try:
41
  open_trades_list = await self.r2.get_open_trades_async()
42
- # تحويل القائمة إلى قاموس مع تنظيف البيانات
43
  self.open_positions = {trade['symbol']: trade for trade in open_trades_list}
44
  print(f" -> [Sync] تم استعادة {len(self.open_positions)} صفقة مفتوحة من R2.")
45
  except Exception as e:
@@ -50,13 +49,6 @@ class TradeManager:
50
  # 🎯 دالة الفرز والتنفيذ
51
  # ==============================================================================
52
  async def select_and_execute_best_signal(self, oracle_approved_signals: List[Dict[str, Any]]):
53
- """
54
- 1. يفحص جميع الإشارات المعتمدة من العقل باستخدام القناص.
55
- 2. يفرزها وينفذ الأفضل.
56
- 3. يتحقق من عدم وجود صفقات مفتوحة قبل البدء.
57
- """
58
-
59
- # [GEM-FIX] تحقق سريع قبل بدء معالجة القناص
60
  if len(self.open_positions) > 0:
61
  print(f"⛔ [TradeManager] تم إلغاء الفرز. توجد صفقة مفتوحة بالفعل.")
62
  return
@@ -119,7 +111,6 @@ class TradeManager:
119
  print(f" -> (خسرت أمامها: {i+2}. {loser['symbol']} (Sniper: {loser['sniper_confidence']:.2f}, L2: {loser['final_total_score']:.2f}))")
120
 
121
  async with self.execution_lock:
122
- # [GEM-FIX] تحقق مزدوج داخل القفل
123
  if len(self.open_positions) > 0:
124
  print(f"⛔ [TradeManager] تم إلغاء التنفيذ في اللحظة الأخيرة. توجد صفقة مفتوحة.")
125
  return
@@ -131,22 +122,14 @@ class TradeManager:
131
  await self._execute_entry_from_signal(best_signal['symbol'], best_signal)
132
 
133
  async def _handle_new_signal(self, symbol, signal_data):
134
- """
135
- (Legacy) معالج الإشارات القديم.
136
- """
137
  print(f"⚠️ [TradeManager] _handle_new_signal (Legacy) called for {symbol}. Redirecting to Batch Select Logic...")
138
  await self.select_and_execute_best_signal([signal_data])
139
 
140
  # ==============================================================================
141
- # 🎯 تنفيذ الدخول (المعدل)
142
  # ==============================================================================
143
  async def _execute_entry_from_signal(self, symbol, signal_data):
144
- """
145
- تنفيذ عملية الدخول (وهمي حالياً) مع قفل صارم.
146
- """
147
- # ملاحظة: يجب استدعاء هذه الدالة داخل execution_lock من الدالة الأم، ولكن للسلامة نتحقق هنا أيضاً
148
  try:
149
- # [GEM-FIX] قفل صارم جداً
150
  if len(self.open_positions) > 0:
151
  print(f"⛔ [Entry BLOCKED] لا يمكن فتح {symbol}، توجد صفقة مفتوحة بالفعل.")
152
  return
@@ -154,9 +137,7 @@ class TradeManager:
154
  trade_id = str(uuid.uuid4())
155
  current_price = float(signal_data.get('current_price', 0.0))
156
 
157
- # [GEM-FIX] معالجة السعر الصفري
158
  if current_price <= 0.0:
159
- # محاولة طارئة
160
  current_price = await self.data_manager.get_latest_price_async(symbol)
161
  if current_price <= 0.0:
162
  print(f"⚠️ [Entry ERROR] {symbol} السعر 0، لا يمكن التنفيذ.")
@@ -175,7 +156,6 @@ class TradeManager:
175
  tp_price = current_price + (atr_mock * 2.0)
176
  sl_price = current_price - (atr_mock * 1.0)
177
 
178
- # [GEM-FIX] ضمان أن القيم Float
179
  tp_price = float(tp_price)
180
  sl_price = float(sl_price)
181
 
@@ -201,23 +181,21 @@ class TradeManager:
201
  'l3_oracle_sl': float(signal_data.get('sl_price', 0.0) or 0.0),
202
  }
203
 
204
- # 1. تحديث الحالة الداخلية
205
  self.open_positions[symbol] = new_trade
206
 
207
  if self.watchlist:
208
- print(f" -> [Watchlist] مسح {len(self.watchlist)} عنصر من قائمة المراقبة (للتركيز على الصفقة الجديدة).")
209
  self.watchlist.clear()
210
 
211
- # 2. حفظ في R2
212
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
213
 
214
- # 3. بدء حارس الخروج
215
  if symbol in self.sentry_tasks:
216
  self.sentry_tasks[symbol].cancel()
217
 
218
  self.sentry_tasks[symbol] = asyncio.create_task(self._guardian_loop(symbol))
219
 
220
- print(f"✅ [ENTRY EXECUTED] {symbol} | Price: {current_price:.4f} | TP: {tp_price:.4f} | SL: {sl_price:.4f}")
 
221
  print(f" -> L2 Score: {new_trade['l1_score']:.2f}, L4 Conf: {new_trade['l2_sniper_confidence']:.2f}")
222
 
223
  except Exception as e:
@@ -291,13 +269,13 @@ class TradeManager:
291
  continue
292
 
293
  if current_price >= trade['tp_price']:
294
- print(f"✅ [Sentry EXIT] {symbol} (TP Hit) at {current_price}")
295
  async with self.execution_lock:
296
  await self._execute_exit(symbol, current_price, "TP_HIT")
297
  break
298
 
299
  if current_price <= trade['sl_price']:
300
- print(f"🛑 [Sentry EXIT] {symbol} (SL Hit) at {current_price}")
301
  async with self.execution_lock:
302
  await self._execute_exit(symbol, current_price, "SL_HIT")
303
  break
@@ -352,9 +330,6 @@ class TradeManager:
352
  profit = (price - trade['entry_price']) / trade['entry_price']
353
  trade['profit_pct'] = profit * 100
354
 
355
- # await self.r2.archive_closed_trade_async(trade)
356
- print(" -> [Info] تم تخطي archive_closed_trade_async (غير موجودة في r2.py)")
357
-
358
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
359
 
360
  print(f"✅ [EXIT EXECUTED] {symbol} | Reason: {reason} | PnL: {trade['profit_pct']:.2f}%")
@@ -381,19 +356,17 @@ class TradeManager:
381
  self.open_positions[symbol] = trade
382
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
383
 
384
- print(f"🎯 [Targets Updated] {symbol} | TP: {old_tp:.4f}->{trade['tp_price']:.4f} | SL: {old_sl:.4f}->{trade['sl_price']:.4f} | Reason: {reason}")
385
  else:
386
  print(f"⚠️ [Target Update Failed] {symbol} is not currently open.")
387
 
388
  async def start_sentry_loops(self):
389
- """بدء أو استئناف جميع مهام الحراسة"""
390
  for symbol in list(self.open_positions.keys()):
391
  if symbol not in self.sentry_tasks or self.sentry_tasks[symbol].done():
392
  print(f"🛡️ [Sentry Restart] Activating guardian for existing trade: {symbol}")
393
  self.sentry_tasks[symbol] = asyncio.create_task(self._guardian_loop(symbol))
394
 
395
  async def stop_sentry_loops(self):
396
- """إيقاف نظيف لجميع المهام الخلفية"""
397
  print("🛑 [TradeManager] Stopping all sentry loops...")
398
  self.running = False
399
  for sym, task in self.sentry_tasks.items():
 
1
+ # trade_manager.py (V15.6 - GEM-Architect Fix: Precision Logging)
2
  import asyncio
3
  import json
4
  import uuid
 
22
 
23
  self.execution_lock = asyncio.Lock()
24
 
25
+ print(f"🛡️ [TradeManager V15.6] Sentry Module Initialized (Precision Logs).")
26
  if self.guard:
27
  print(f" -> Guard V2 (Exit Protector) CREATED.")
28
  else:
 
39
  async def sync_internal_state_with_r2(self):
40
  try:
41
  open_trades_list = await self.r2.get_open_trades_async()
 
42
  self.open_positions = {trade['symbol']: trade for trade in open_trades_list}
43
  print(f" -> [Sync] تم استعادة {len(self.open_positions)} صفقة مفتوحة من R2.")
44
  except Exception as e:
 
49
  # 🎯 دالة الفرز والتنفيذ
50
  # ==============================================================================
51
  async def select_and_execute_best_signal(self, oracle_approved_signals: List[Dict[str, Any]]):
 
 
 
 
 
 
 
52
  if len(self.open_positions) > 0:
53
  print(f"⛔ [TradeManager] تم إلغاء الفرز. توجد صفقة مفتوحة بالفعل.")
54
  return
 
111
  print(f" -> (خسرت أمامها: {i+2}. {loser['symbol']} (Sniper: {loser['sniper_confidence']:.2f}, L2: {loser['final_total_score']:.2f}))")
112
 
113
  async with self.execution_lock:
 
114
  if len(self.open_positions) > 0:
115
  print(f"⛔ [TradeManager] تم إلغاء التنفيذ في اللحظة الأخيرة. توجد صفقة مفتوحة.")
116
  return
 
122
  await self._execute_entry_from_signal(best_signal['symbol'], best_signal)
123
 
124
  async def _handle_new_signal(self, symbol, signal_data):
 
 
 
125
  print(f"⚠️ [TradeManager] _handle_new_signal (Legacy) called for {symbol}. Redirecting to Batch Select Logic...")
126
  await self.select_and_execute_best_signal([signal_data])
127
 
128
  # ==============================================================================
129
+ # 🎯 تنفيذ الدخول (المعدل لدقة الأرقام)
130
  # ==============================================================================
131
  async def _execute_entry_from_signal(self, symbol, signal_data):
 
 
 
 
132
  try:
 
133
  if len(self.open_positions) > 0:
134
  print(f"⛔ [Entry BLOCKED] لا يمكن فتح {symbol}، توجد صفقة مفتوحة بالفعل.")
135
  return
 
137
  trade_id = str(uuid.uuid4())
138
  current_price = float(signal_data.get('current_price', 0.0))
139
 
 
140
  if current_price <= 0.0:
 
141
  current_price = await self.data_manager.get_latest_price_async(symbol)
142
  if current_price <= 0.0:
143
  print(f"⚠️ [Entry ERROR] {symbol} السعر 0، لا يمكن التنفيذ.")
 
156
  tp_price = current_price + (atr_mock * 2.0)
157
  sl_price = current_price - (atr_mock * 1.0)
158
 
 
159
  tp_price = float(tp_price)
160
  sl_price = float(sl_price)
161
 
 
181
  'l3_oracle_sl': float(signal_data.get('sl_price', 0.0) or 0.0),
182
  }
183
 
 
184
  self.open_positions[symbol] = new_trade
185
 
186
  if self.watchlist:
187
+ print(f" -> [Watchlist] مسح {len(self.watchlist)} عنصر من قائمة المراقبة.")
188
  self.watchlist.clear()
189
 
 
190
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
191
 
 
192
  if symbol in self.sentry_tasks:
193
  self.sentry_tasks[symbol].cancel()
194
 
195
  self.sentry_tasks[symbol] = asyncio.create_task(self._guardian_loop(symbol))
196
 
197
+ # [GEM-FIX] استخدام تنسيق 8 خانات في السجلات
198
+ print(f"✅ [ENTRY EXECUTED] {symbol} | Price: {current_price:.8f} | TP: {tp_price:.8f} | SL: {sl_price:.8f}")
199
  print(f" -> L2 Score: {new_trade['l1_score']:.2f}, L4 Conf: {new_trade['l2_sniper_confidence']:.2f}")
200
 
201
  except Exception as e:
 
269
  continue
270
 
271
  if current_price >= trade['tp_price']:
272
+ print(f"✅ [Sentry EXIT] {symbol} (TP Hit) at {current_price:.8f}")
273
  async with self.execution_lock:
274
  await self._execute_exit(symbol, current_price, "TP_HIT")
275
  break
276
 
277
  if current_price <= trade['sl_price']:
278
+ print(f"🛑 [Sentry EXIT] {symbol} (SL Hit) at {current_price:.8f}")
279
  async with self.execution_lock:
280
  await self._execute_exit(symbol, current_price, "SL_HIT")
281
  break
 
330
  profit = (price - trade['entry_price']) / trade['entry_price']
331
  trade['profit_pct'] = profit * 100
332
 
 
 
 
333
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
334
 
335
  print(f"✅ [EXIT EXECUTED] {symbol} | Reason: {reason} | PnL: {trade['profit_pct']:.2f}%")
 
356
  self.open_positions[symbol] = trade
357
  await self.r2.save_open_trades_async(list(self.open_positions.values()))
358
 
359
+ print(f"🎯 [Targets Updated] {symbol} | TP: {old_tp:.8f}->{trade['tp_price']:.8f} | SL: {old_sl:.8f}->{trade['sl_price']:.8f} | Reason: {reason}")
360
  else:
361
  print(f"⚠️ [Target Update Failed] {symbol} is not currently open.")
362
 
363
  async def start_sentry_loops(self):
 
364
  for symbol in list(self.open_positions.keys()):
365
  if symbol not in self.sentry_tasks or self.sentry_tasks[symbol].done():
366
  print(f"🛡️ [Sentry Restart] Activating guardian for existing trade: {symbol}")
367
  self.sentry_tasks[symbol] = asyncio.create_task(self._guardian_loop(symbol))
368
 
369
  async def stop_sentry_loops(self):
 
370
  print("🛑 [TradeManager] Stopping all sentry loops...")
371
  self.running = False
372
  for sym, task in self.sentry_tasks.items():