Riy777 commited on
Commit
6f41fff
·
1 Parent(s): fc2dc2c

Update trade_manger.py

Browse files
Files changed (1) hide show
  1. trade_manger.py +4 -48
trade_manger.py CHANGED
@@ -1,4 +1,5 @@
1
  import asyncio
 
2
  from datetime import datetime, timedelta
3
  from helpers import safe_float_conversion, _apply_patience_logic
4
 
@@ -11,13 +12,11 @@ class TradeManager:
11
  self.is_running = False
12
 
13
  async def open_trade(self, symbol, decision, current_price):
14
- """فتح صفقة جديدة باستخدام رأس المال المتاح بالكامل"""
15
  try:
16
  portfolio_state = await self.r2_service.get_portfolio_state_async()
17
  available_capital = portfolio_state.get("current_capital_usd", 0)
18
 
19
  if available_capital < 1:
20
- print(f"❌ رأس مال غير كافٍ (${available_capital:.2f}) لفتح صفقة جديدة.")
21
  return None
22
 
23
  expected_target_minutes = decision.get('expected_target_minutes', 15)
@@ -27,7 +26,6 @@ class TradeManager:
27
  strategy = decision.get('strategy')
28
  if not strategy or strategy == 'unknown':
29
  strategy = 'GENERIC'
30
- print(f"⚠️ الاستراتيجية مفقودة أو غير معروفة. تعيين إلى GENERIC لـ {symbol}")
31
 
32
  trades = await self.r2_service.get_open_trades_async()
33
  new_trade = {
@@ -50,12 +48,6 @@ class TradeManager:
50
  trades.append(new_trade)
51
  await self.r2_service.save_open_trades_async(trades)
52
 
53
- original_expected = decision.get('expected_target_minutes', 15)
54
- if original_expected > 45:
55
- print(f"⚠️ النموذج طلب {original_expected} دقيقة، تم التحديد إلى 45 دقيقة لتناسق الاستراتيجية")
56
-
57
- print(f"✅ صفقة جديدة لـ {symbol} محفوظة بحجم ${available_capital:.2f}. الاستراتيجية: {strategy}. النتائج المتوقعة في {expected_target_minutes} دقيقة.")
58
-
59
  portfolio_state["invested_capital_usd"] = available_capital
60
  portfolio_state["current_capital_usd"] = 0.0
61
  portfolio_state["total_trades"] = portfolio_state.get("total_trades", 0) + 1
@@ -73,11 +65,9 @@ class TradeManager:
73
  return new_trade
74
 
75
  except Exception as e:
76
- print(f"❌ فشل فتح صفقة جديدة: {e}")
77
  raise
78
 
79
  async def close_trade(self, trade_to_close, close_price, reason="إغلاق بالنظام"):
80
- """إغلاق صفقة وتحديث المحفظة وتحليل النتيجة"""
81
  try:
82
  trade_to_close['status'] = 'CLOSED'
83
  trade_to_close['close_price'] = close_price
@@ -100,17 +90,10 @@ class TradeManager:
100
  elif trade_type == 'SHORT':
101
  pnl_percent = ((entry_price - close_price) / entry_price) * 100
102
  pnl = position_size * (pnl_percent / 100)
103
-
104
- print(f"💰 حساب PnL: الدخول=${entry_price:.6f}, الخروج=${close_price:.6f}, "
105
- f"الحجم=${position_size:.2f}, النوع={trade_type}, "
106
- f"PnL=${pnl:.4f} ({pnl_percent:+.4f}%)")
107
 
108
  except (TypeError, ZeroDivisionError) as calc_error:
109
- print(f"⚠️ خطأ في حساب PnL: {calc_error}")
110
  pnl = 0.0
111
  pnl_percent = 0.0
112
- else:
113
- print(f"⚠️ أسعار غير صالحة لحساب PnL: الدخول={entry_price}, الخروج={close_price}")
114
 
115
  trade_to_close['pnl_usd'] = pnl
116
  trade_to_close['pnl_percent'] = pnl_percent
@@ -134,16 +117,11 @@ class TradeManager:
134
  portfolio_state["total_loss_usd"] = portfolio_state.get("total_loss_usd", 0.0) + abs(pnl)
135
 
136
  await self.r2_service.save_portfolio_state_async(portfolio_state)
137
-
138
- print(f"📈 PnL الصفقة: ${pnl:.4f} ({pnl_percent:+.4f}%). "
139
- f"رأس المال الجديد المتاح: ${new_capital:.4f}. الاستراتيجية: {strategy}")
140
 
141
  open_trades = await self.r2_service.get_open_trades_async()
142
  trades_to_keep = [t for t in open_trades if t.get('id') != trade_to_close.get('id')]
143
  await self.r2_service.save_open_trades_async(trades_to_keep)
144
 
145
- print(f"✅ تم إغلاق صفقة {trade_to_close.get('symbol')} وأرشفتها بنجاح. الاستراتيجية: {strategy}")
146
-
147
  await self.r2_service.save_system_logs_async({
148
  "trade_closed": True,
149
  "symbol": trade_to_close.get('symbol'),
@@ -164,11 +142,9 @@ class TradeManager:
164
  return True
165
 
166
  except Exception as e:
167
- print(f"❌ فشل إغلاق الصفقة: {e}")
168
  raise
169
 
170
  async def update_trade(self, trade_to_update, re_analysis_decision):
171
- """تحديث الصفقة بمعطيات جديدة من إعادة التحليل"""
172
  try:
173
  if re_analysis_decision.get('new_stop_loss'):
174
  trade_to_update['stop_loss'] = re_analysis_decision['new_stop_loss']
@@ -180,7 +156,6 @@ class TradeManager:
180
  new_expected_minutes = max(5, min(new_expected_minutes, 45))
181
  trade_to_update['expected_target_minutes'] = new_expected_minutes
182
  trade_to_update['expected_target_time'] = (datetime.now() + timedelta(minutes=new_expected_minutes)).isoformat()
183
- print(f"⏰ تم تحديث وقت الصفقة المتوقع إلى {new_expected_minutes} دقيقة.")
184
 
185
  original_strategy = trade_to_update.get('strategy')
186
  if not original_strategy or original_strategy == 'unknown':
@@ -197,7 +172,6 @@ class TradeManager:
197
  break
198
 
199
  await self.r2_service.save_open_trades_async(open_trades)
200
- print(f"✅ تم تحديث صفقة {trade_to_update.get('symbol')} بنجاح. الاستراتيجية: {original_strategy}")
201
 
202
  await self.r2_service.save_system_logs_async({
203
  "trade_updated": True,
@@ -210,11 +184,9 @@ class TradeManager:
210
  return True
211
 
212
  except Exception as e:
213
- print(f"❌ فشل تحديث الصفقة: {e}")
214
  raise
215
 
216
  async def immediate_close_trade(self, symbol, close_price, reason="المراقبة الفورية"):
217
- """إغلاق فوري لصفقة بدون إعادة تحليل كاملة"""
218
  try:
219
  open_trades = await self.r2_service.get_open_trades_async()
220
  trade_to_close = None
@@ -225,20 +197,16 @@ class TradeManager:
225
  break
226
 
227
  if not trade_to_close:
228
- print(f"❌ لم يتم العثور على صفقة مفتوحة لـ {symbol}")
229
  return False
230
 
231
  await self.close_trade(trade_to_close, close_price, reason)
232
- print(f"🚨 إغلاق فوري: {symbol} عند {close_price} - {reason}")
233
 
234
  return True
235
 
236
  except Exception as e:
237
- print(f"❌ فشل الإغلاق الفوري لصفقة {symbol}: {e}")
238
  return False
239
 
240
  async def start_trade_monitoring(self):
241
- """بدء مراقبة الصفقات المفتوحة"""
242
  self.is_running = True
243
  while self.is_running:
244
  try:
@@ -256,11 +224,9 @@ class TradeManager:
256
 
257
  await asyncio.sleep(10)
258
  except Exception as error:
259
- print(f"خطأ في مراقبة الصفقات: {error}")
260
  await asyncio.sleep(30)
261
 
262
  async def _monitor_single_trade(self, trade):
263
- """مراقبة صفقة فردية"""
264
  symbol = trade['symbol']
265
  while symbol in self.monitoring_tasks and self.is_running:
266
  try:
@@ -301,16 +267,13 @@ class TradeManager:
301
 
302
  await asyncio.sleep(15)
303
  except Exception as error:
304
- print(f"خطأ في مراقبة {symbol}: {error}")
305
  await asyncio.sleep(30)
306
 
307
  def stop_monitoring(self):
308
- """إيقاف مراقبة الصفقات"""
309
  self.is_running = False
310
  self.monitoring_tasks.clear()
311
 
312
  async def _archive_closed_trade(self, closed_trade):
313
- """أرشفة الصفقة المغلقة"""
314
  try:
315
  key = "closed_trades_history.json"
316
  try:
@@ -325,12 +288,10 @@ class TradeManager:
325
  self.r2_service.s3_client.put_object(
326
  Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
327
  )
328
- print(f"📚 تم أرشفة الصفقة. إجمالي الصفقات المؤرشفة: {len(history)}")
329
  except Exception as e:
330
- print(f"❌ فشل أرشفة الصفقة: {e}")
331
 
332
  async def _update_trade_summary(self, closed_trade):
333
- """تحديث إحصائيات التداول"""
334
  try:
335
  key = "trade_summary.json"
336
  try:
@@ -370,21 +331,16 @@ class TradeManager:
370
  self.r2_service.s3_client.put_object(
371
  Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
372
  )
373
- print(f"📊 تم تحديث ملخص التداول. معدل الربح: {summary['win_percentage']:.2f}%")
374
 
375
  except Exception as e:
376
- print(f"❌ فشل تحديث ملخص التداول: {e}")
377
 
378
  async def get_open_trades(self):
379
- """الحصول على الصفقات المفتوحة"""
380
  return await self.r2_service.get_open_trades_async()
381
 
382
  async def get_trade_by_symbol(self, symbol):
383
- """الحصول على صفقة بالرمز"""
384
  open_trades = await self.get_open_trades()
385
  for trade in open_trades:
386
  if trade['symbol'] == symbol and trade['status'] == 'OPEN':
387
  return trade
388
- return None
389
-
390
- print("✅ Trade Manager محمل - إدارة موحدة للصفقات")
 
1
  import asyncio
2
+ import json
3
  from datetime import datetime, timedelta
4
  from helpers import safe_float_conversion, _apply_patience_logic
5
 
 
12
  self.is_running = False
13
 
14
  async def open_trade(self, symbol, decision, current_price):
 
15
  try:
16
  portfolio_state = await self.r2_service.get_portfolio_state_async()
17
  available_capital = portfolio_state.get("current_capital_usd", 0)
18
 
19
  if available_capital < 1:
 
20
  return None
21
 
22
  expected_target_minutes = decision.get('expected_target_minutes', 15)
 
26
  strategy = decision.get('strategy')
27
  if not strategy or strategy == 'unknown':
28
  strategy = 'GENERIC'
 
29
 
30
  trades = await self.r2_service.get_open_trades_async()
31
  new_trade = {
 
48
  trades.append(new_trade)
49
  await self.r2_service.save_open_trades_async(trades)
50
 
 
 
 
 
 
 
51
  portfolio_state["invested_capital_usd"] = available_capital
52
  portfolio_state["current_capital_usd"] = 0.0
53
  portfolio_state["total_trades"] = portfolio_state.get("total_trades", 0) + 1
 
65
  return new_trade
66
 
67
  except Exception as e:
 
68
  raise
69
 
70
  async def close_trade(self, trade_to_close, close_price, reason="إغلاق بالنظام"):
 
71
  try:
72
  trade_to_close['status'] = 'CLOSED'
73
  trade_to_close['close_price'] = close_price
 
90
  elif trade_type == 'SHORT':
91
  pnl_percent = ((entry_price - close_price) / entry_price) * 100
92
  pnl = position_size * (pnl_percent / 100)
 
 
 
 
93
 
94
  except (TypeError, ZeroDivisionError) as calc_error:
 
95
  pnl = 0.0
96
  pnl_percent = 0.0
 
 
97
 
98
  trade_to_close['pnl_usd'] = pnl
99
  trade_to_close['pnl_percent'] = pnl_percent
 
117
  portfolio_state["total_loss_usd"] = portfolio_state.get("total_loss_usd", 0.0) + abs(pnl)
118
 
119
  await self.r2_service.save_portfolio_state_async(portfolio_state)
 
 
 
120
 
121
  open_trades = await self.r2_service.get_open_trades_async()
122
  trades_to_keep = [t for t in open_trades if t.get('id') != trade_to_close.get('id')]
123
  await self.r2_service.save_open_trades_async(trades_to_keep)
124
 
 
 
125
  await self.r2_service.save_system_logs_async({
126
  "trade_closed": True,
127
  "symbol": trade_to_close.get('symbol'),
 
142
  return True
143
 
144
  except Exception as e:
 
145
  raise
146
 
147
  async def update_trade(self, trade_to_update, re_analysis_decision):
 
148
  try:
149
  if re_analysis_decision.get('new_stop_loss'):
150
  trade_to_update['stop_loss'] = re_analysis_decision['new_stop_loss']
 
156
  new_expected_minutes = max(5, min(new_expected_minutes, 45))
157
  trade_to_update['expected_target_minutes'] = new_expected_minutes
158
  trade_to_update['expected_target_time'] = (datetime.now() + timedelta(minutes=new_expected_minutes)).isoformat()
 
159
 
160
  original_strategy = trade_to_update.get('strategy')
161
  if not original_strategy or original_strategy == 'unknown':
 
172
  break
173
 
174
  await self.r2_service.save_open_trades_async(open_trades)
 
175
 
176
  await self.r2_service.save_system_logs_async({
177
  "trade_updated": True,
 
184
  return True
185
 
186
  except Exception as e:
 
187
  raise
188
 
189
  async def immediate_close_trade(self, symbol, close_price, reason="المراقبة الفورية"):
 
190
  try:
191
  open_trades = await self.r2_service.get_open_trades_async()
192
  trade_to_close = None
 
197
  break
198
 
199
  if not trade_to_close:
 
200
  return False
201
 
202
  await self.close_trade(trade_to_close, close_price, reason)
 
203
 
204
  return True
205
 
206
  except Exception as e:
 
207
  return False
208
 
209
  async def start_trade_monitoring(self):
 
210
  self.is_running = True
211
  while self.is_running:
212
  try:
 
224
 
225
  await asyncio.sleep(10)
226
  except Exception as error:
 
227
  await asyncio.sleep(30)
228
 
229
  async def _monitor_single_trade(self, trade):
 
230
  symbol = trade['symbol']
231
  while symbol in self.monitoring_tasks and self.is_running:
232
  try:
 
267
 
268
  await asyncio.sleep(15)
269
  except Exception as error:
 
270
  await asyncio.sleep(30)
271
 
272
  def stop_monitoring(self):
 
273
  self.is_running = False
274
  self.monitoring_tasks.clear()
275
 
276
  async def _archive_closed_trade(self, closed_trade):
 
277
  try:
278
  key = "closed_trades_history.json"
279
  try:
 
288
  self.r2_service.s3_client.put_object(
289
  Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
290
  )
 
291
  except Exception as e:
292
+ pass
293
 
294
  async def _update_trade_summary(self, closed_trade):
 
295
  try:
296
  key = "trade_summary.json"
297
  try:
 
331
  self.r2_service.s3_client.put_object(
332
  Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
333
  )
 
334
 
335
  except Exception as e:
336
+ pass
337
 
338
  async def get_open_trades(self):
 
339
  return await self.r2_service.get_open_trades_async()
340
 
341
  async def get_trade_by_symbol(self, symbol):
 
342
  open_trades = await self.get_open_trades()
343
  for trade in open_trades:
344
  if trade['symbol'] == symbol and trade['status'] == 'OPEN':
345
  return trade
346
+ return None