Riy777 commited on
Commit
a0188c4
·
verified ·
1 Parent(s): 34647e8

Delete learning_engine.py

Browse files
Files changed (1) hide show
  1. learning_engine.py +0 -548
learning_engine.py DELETED
@@ -1,548 +0,0 @@
1
- # learning_engine (37).py (محدث بالكامل مع تعلم ملف الخروج)
2
- import os, json, asyncio
3
- from datetime import datetime
4
- from helpers import normalize_weights, calculate_market_volatility, should_update_weights
5
- import numpy as np # نحتاج numpy لحساب المتوسطات
6
-
7
- class LearningEngine:
8
- def __init__(self, r2_service, data_manager):
9
- self.r2_service = r2_service
10
- self.data_manager = data_manager
11
- self.weights = {}
12
- self.performance_history = []
13
- self.strategy_effectiveness = {} # 🔴 لتعلم استراتيجيات الدخول
14
- self.exit_profile_effectiveness = {} # 🔴 جديد: لتعلم (الدخول + الخروج)
15
- self.market_patterns = {}
16
- self.risk_profiles = {}
17
- self.initialized = False
18
- self.initialization_lock = asyncio.Lock()
19
-
20
- async def initialize(self):
21
- async with self.initialization_lock:
22
- if self.initialized: return
23
- print("Initializing learning system...")
24
- try:
25
- await self.load_weights_from_r2()
26
- await self.load_performance_history()
27
- # 🔴 جديد: تحميل أداء ملفات الخروج
28
- await self.load_exit_profile_effectiveness()
29
- self.initialized = True
30
- print("Learning system ready (with Exit Profile learning)")
31
- except Exception as e:
32
- print(f"Weights loading failed: {e}")
33
- await self.initialize_default_weights()
34
- self.initialized = True
35
-
36
- async def initialize_enhanced(self):
37
- async with self.initialization_lock:
38
- if self.initialized: return
39
- print("Enhanced learning system initialization...")
40
- try:
41
- await self.load_weights_from_r2()
42
- await self.load_performance_history()
43
- # 🔴 جديد: تحميل أداء ملفات الخروج
44
- await self.load_exit_profile_effectiveness()
45
- await self.fix_weights_structure()
46
- if not self.performance_history:
47
- print("Starting learning from scratch")
48
- await self.initialize_default_weights()
49
- self.initialized = True
50
- except Exception as e:
51
- print(f"Enhanced initialization failed: {e}")
52
- await self.initialize_default_weights()
53
- self.initialized = True
54
-
55
- async def fix_weights_structure(self):
56
- try:
57
- key = "learning_engine_weights.json"
58
- response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
59
- current_data = json.loads(response['Body'].read())
60
-
61
- if 'strategy_weights' in current_data and 'last_updated' not in current_data:
62
- fixed_data = {
63
- "weights": current_data,
64
- "last_updated": datetime.now().isoformat(),
65
- "version": "2.0",
66
- "performance_metrics": await self.calculate_performance_metrics()
67
- }
68
- data_json = json.dumps(fixed_data, indent=2, ensure_ascii=False).encode('utf-8')
69
- self.r2_service.s3_client.put_object(
70
- Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
71
- )
72
- print("Weights structure fixed")
73
- except Exception as e:
74
- print(f"Weights structure fix failed: {e}")
75
-
76
- async def initialize_default_weights(self):
77
- self.weights = {
78
- "strategy_weights": {
79
- "trend_following": 0.18, "mean_reversion": 0.15, "breakout_momentum": 0.22,
80
- "volume_spike": 0.12, "whale_tracking": 0.15, "pattern_recognition": 0.10,
81
- "hybrid_ai": 0.08
82
- },
83
- "technical_weights": {
84
- "rsi": 0.15, "macd": 0.18, "ema_cross": 0.12, "bollinger_bands": 0.10,
85
- "volume_analysis": 0.15, "support_resistance": 0.12, "market_sentiment": 0.18
86
- },
87
- "risk_parameters": {
88
- "max_position_size": 0.1, "max_daily_loss": 0.02, "stop_loss_base": 0.02,
89
- "risk_reward_ratio": 2.0, "volatility_adjustment": 1.0
90
- },
91
- "market_condition_weights": {
92
- "bull_market": {"trend_following": 0.25, "breakout_momentum": 0.20, "whale_tracking": 0.15},
93
- "bear_market": {"mean_reversion": 0.25, "pattern_recognition": 0.20, "hybrid_ai": 0.15},
94
- "sideways_market": {"mean_reversion": 0.30, "volume_spike": 0.20, "pattern_recognition": 0.15}
95
- }
96
- }
97
- # 🔴 جديد: تهيئة افتراضية لملفات الخروج
98
- self.exit_profile_effectiveness = {}
99
-
100
- async def load_weights_from_r2(self):
101
- try:
102
- key = "learning_engine_weights.json"
103
- response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
104
- weights_data = json.loads(response['Body'].read())
105
-
106
- if isinstance(weights_data, dict):
107
- if 'weights' in weights_data:
108
- self.weights = weights_data['weights']
109
- else:
110
- self.weights = weights_data
111
- print(f"Weights loaded from R2")
112
- else:
113
- raise ValueError("Invalid weights structure")
114
- except Exception as e:
115
- print(f"Weights loading failed: {e}")
116
- await self.initialize_default_weights()
117
- await self.save_weights_to_r2()
118
-
119
- async def save_weights_to_r2(self):
120
- try:
121
- key = "learning_engine_weights.json"
122
- weights_data = {
123
- "weights": self.weights,
124
- "last_updated": datetime.now().isoformat(),
125
- "version": "2.0",
126
- "performance_metrics": await self.calculate_performance_metrics()
127
- }
128
- data_json = json.dumps(weights_data, indent=2, ensure_ascii=False).encode('utf-8')
129
- self.r2_service.s3_client.put_object(
130
- Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
131
- )
132
- print("Weights saved to R2")
133
- except Exception as e:
134
- print(f"Weights saving failed: {e}")
135
-
136
- # 🔴 جديد: تحميل وحفظ أداء ملف الخروج
137
- async def load_exit_profile_effectiveness(self):
138
- try:
139
- key = "learning_exit_profile_effectiveness.json"
140
- response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
141
- data = json.loads(response['Body'].read())
142
- self.exit_profile_effectiveness = data.get("effectiveness", {})
143
- print(f"Exit profile effectiveness loaded - {len(self.exit_profile_effectiveness)} combinations")
144
- except Exception as e:
145
- print(f"Exit profile effectiveness loading failed: {e}")
146
- self.exit_profile_effectiveness = {}
147
-
148
- async def save_exit_profile_effectiveness(self):
149
- try:
150
- key = "learning_exit_profile_effectiveness.json"
151
- data = {
152
- "effectiveness": self.exit_profile_effectiveness,
153
- "last_updated": datetime.now().isoformat()
154
- }
155
- data_json = json.dumps(data, indent=2, ensure_ascii=False).encode('utf-8')
156
- self.r2_service.s3_client.put_object(
157
- Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
158
- )
159
- except Exception as e:
160
- print(f"Exit profile effectiveness saving failed: {e}")
161
-
162
- async def load_performance_history(self):
163
- try:
164
- key = "learning_performance_history.json"
165
- response = self.r2_service.s3_client.get_object(Bucket="trading", Key=key)
166
- history_data = json.loads(response['Body'].read())
167
- self.performance_history = history_data.get("history", [])
168
- print(f"Performance history loaded - {len(self.performance_history)} records")
169
- except Exception as e:
170
- print(f"Performance history loading failed: {e}")
171
- self.performance_history = []
172
-
173
- async def save_performance_history(self):
174
- try:
175
- key = "learning_performance_history.json"
176
- history_data = {
177
- "history": self.performance_history[-1000:],
178
- "last_updated": datetime.now().isoformat()
179
- }
180
- data_json = json.dumps(history_data, indent=2, ensure_ascii=False).encode('utf-8')
181
- self.r2_service.s3_client.put_object(
182
- Bucket="trading", Key=key, Body=data_json, ContentType="application/json"
183
- )
184
- except Exception as e:
185
- print(f"Performance history saving failed: {e}")
186
-
187
- async def analyze_trade_outcome(self, trade_data, outcome):
188
- if not self.initialized: await self.initialize()
189
- try:
190
- strategy = trade_data.get('strategy', 'unknown')
191
- if strategy == 'unknown':
192
- decision_data = trade_data.get('decision_data', {})
193
- strategy = decision_data.get('strategy', 'unknown')
194
-
195
- # 🔴 جديد: استخراج ملف الخروج
196
- decision_data = trade_data.get('decision_data', {})
197
- exit_profile = decision_data.get('exit_profile', 'unknown')
198
-
199
- market_context = await self.get_current_market_conditions()
200
-
201
- analysis_entry = {
202
- "timestamp": datetime.now().isoformat(),
203
- "trade_data": trade_data,
204
- "outcome": outcome,
205
- "market_conditions": market_context,
206
- "strategy_used": strategy,
207
- "exit_profile_used": exit_profile, # 🔴 جديد
208
- "symbol": trade_data.get('symbol', 'unknown'),
209
- "pnl_usd": trade_data.get('pnl_usd', 0),
210
- "pnl_percent": trade_data.get('pnl_percent', 0)
211
- }
212
-
213
- self.performance_history.append(analysis_entry)
214
- await self.update_strategy_effectiveness(analysis_entry)
215
- await self.update_market_patterns(analysis_entry)
216
-
217
- if should_update_weights(len(self.performance_history)):
218
- await self.adapt_weights_based_on_performance()
219
- await self.save_weights_to_r2()
220
- await self.save_performance_history()
221
- # 🔴 جديد: حفظ أداء ملف الخروج
222
- await self.save_exit_profile_effectiveness()
223
-
224
- print(f"Trade analyzed {trade_data.get('symbol')} - Strategy: {strategy} - Exit: {exit_profile} - Outcome: {outcome}")
225
- except Exception as e:
226
- print(f"Trade outcome analysis failed: {e}")
227
-
228
- async def update_strategy_effectiveness(self, analysis_entry):
229
- strategy = analysis_entry['strategy_used']
230
- exit_profile = analysis_entry['exit_profile_used'] # 🔴 جديد
231
- combined_key = f"{strategy}_{exit_profile}" # 🔴 جديد
232
-
233
- outcome = analysis_entry['outcome']
234
- market_condition = analysis_entry['market_conditions']['current_trend']
235
- pnl_percent = analysis_entry.get('pnl_percent', 0)
236
-
237
- # --- 1. تحديث أداء استراتيجية الدخول (كما كان) ---
238
- if strategy not in self.strategy_effectiveness:
239
- self.strategy_effectiveness[strategy] = {
240
- "total_trades": 0, "successful_trades": 0, "total_profit": 0,
241
- "total_pnl_percent": 0, "market_conditions": {}
242
- }
243
-
244
- self.strategy_effectiveness[strategy]["total_trades"] += 1
245
- self.strategy_effectiveness[strategy]["total_pnl_percent"] += pnl_percent
246
-
247
- is_success = outcome in ["SUCCESS", "CLOSED_BY_REANALYSIS", "CLOSED_BY_MONITOR"] and pnl_percent > 0
248
- if is_success: self.strategy_effectiveness[strategy]["successful_trades"] += 1
249
-
250
- if market_condition not in self.strategy_effectiveness[strategy]["market_conditions"]:
251
- self.strategy_effectiveness[strategy]["market_conditions"][market_condition] = {
252
- "trades": 0, "successes": 0, "total_pnl": 0
253
- }
254
-
255
- self.strategy_effectiveness[strategy]["market_conditions"][market_condition]["trades"] += 1
256
- self.strategy_effectiveness[strategy]["market_conditions"][market_condition]["total_pnl"] += pnl_percent
257
- if is_success: self.strategy_effectiveness[strategy]["market_conditions"][market_condition]["successes"] += 1
258
-
259
- # --- 2. 🔴 جديد: تحديث أداء مزيج (الدخول + الخروج) ---
260
- if combined_key not in self.exit_profile_effectiveness:
261
- self.exit_profile_effectiveness[combined_key] = {
262
- "total_trades": 0, "successful_trades": 0,
263
- "total_pnl_percent": 0, "pnl_list": [] # لتتبع المتوسط والانحراف
264
- }
265
-
266
- self.exit_profile_effectiveness[combined_key]["total_trades"] += 1
267
- self.exit_profile_effectiveness[combined_key]["total_pnl_percent"] += pnl_percent
268
- self.exit_profile_effectiveness[combined_key]["pnl_list"].append(pnl_percent)
269
- # الحفاظ على آخر 100 نتيجة فقط
270
- if len(self.exit_profile_effectiveness[combined_key]["pnl_list"]) > 100:
271
- self.exit_profile_effectiveness[combined_key]["pnl_list"] = self.exit_profile_effectiveness[combined_key]["pnl_list"][-100:]
272
-
273
- if is_success:
274
- self.exit_profile_effectiveness[combined_key]["successful_trades"] += 1
275
-
276
-
277
- async def update_market_patterns(self, analysis_entry):
278
- # ... (هذه الدالة تبقى كما هي، لا تحتاج تعديل)
279
- market_condition = analysis_entry['market_conditions']['current_trend']
280
- symbol = analysis_entry['symbol']
281
- outcome = analysis_entry['outcome']
282
- pnl_percent = analysis_entry.get('pnl_percent', 0)
283
-
284
- if market_condition not in self.market_patterns:
285
- self.market_patterns[market_condition] = {
286
- "total_trades": 0, "successful_trades": 0, "total_pnl_percent": 0,
287
- "best_performing_strategies": {}, "best_performing_symbols": {}
288
- }
289
-
290
- self.market_patterns[market_condition]["total_trades"] += 1
291
- self.market_patterns[market_condition]["total_pnl_percent"] += pnl_percent
292
-
293
- is_success = outcome in ["SUCCESS", "CLOSED_BY_REANALYSIS", "CLOSED_BY_MONITOR"] and pnl_percent > 0
294
- if is_success: self.market_patterns[market_condition]["successful_trades"] += 1
295
-
296
- strategy = analysis_entry['strategy_used']
297
- if strategy not in self.market_patterns[market_condition]["best_performing_strategies"]:
298
- self.market_patterns[market_condition]["best_performing_strategies"][strategy] = {
299
- "count": 0, "total_pnl": 0
300
- }
301
-
302
- self.market_patterns[market_condition]["best_performing_strategies"][strategy]["count"] += 1
303
- self.market_patterns[market_condition]["best_performing_strategies"][strategy]["total_pnl"] += pnl_percent
304
-
305
- if symbol not in self.market_patterns[market_condition]["best_performing_symbols"]:
306
- self.market_patterns[market_condition]["best_performing_symbols"][symbol] = {
307
- "count": 0, "total_pnl": 0
308
- }
309
-
310
- self.market_patterns[market_condition]["best_performing_symbols"][symbol]["count"] += 1
311
- self.market_patterns[market_condition]["best_performing_symbols"][symbol]["total_pnl"] += pnl_percent
312
-
313
- async def adapt_weights_based_on_performance(self):
314
- # ... (هذه الدالة تبقى كما هي، لتعديل أوزان *الدخول* فقط)
315
- print("Updating weights based on performance...")
316
- try:
317
- if not self.strategy_effectiveness:
318
- print("Insufficient performance data, using gradual adjustment")
319
- await self.gradual_weights_adjustment()
320
- return
321
-
322
- total_performance = 0
323
- strategy_performance = {}
324
-
325
- for strategy, data in self.strategy_effectiveness.items():
326
- if data["total_trades"] > 0:
327
- success_rate = data["successful_trades"] / data["total_trades"]
328
- avg_pnl = data["total_pnl_percent"] / data["total_trades"]
329
- composite_performance = (success_rate * 0.7) + (min(avg_pnl, 10) / 10 * 0.3)
330
- strategy_performance[strategy] = composite_performance
331
- total_performance += composite_performance
332
-
333
- if total_performance > 0 and strategy_performance:
334
- for strategy, performance in strategy_performance.items():
335
- current_weight = self.weights["strategy_weights"].get(strategy, 0.1)
336
- new_weight = current_weight * 0.7 + (performance * 0.3)
337
- self.weights["strategy_weights"][strategy] = new_weight
338
-
339
- normalize_weights(self.weights["strategy_weights"])
340
- print("Weights updated based on real performance")
341
- else:
342
- await self.gradual_weights_adjustment()
343
- except Exception as e:
344
- print(f"Weights update failed: {e}")
345
- await self.gradual_weights_adjustment()
346
-
347
- async def gradual_weights_adjustment(self):
348
- # ... (هذه الدالة تبقى كما هي)
349
- print("Gradual weights adjustment...")
350
- if self.market_patterns:
351
- for market_condition, data in self.market_patterns.items():
352
- if data.get("total_trades", 0) > 0:
353
- best_strategy = max(data["best_performing_strategies"].items(),
354
- key=lambda x: x[1]["total_pnl"])[0] if data["best_performing_strategies"] else None
355
- if best_strategy:
356
- current_weight = self.weights["strategy_weights"].get(best_strategy, 0.1)
357
- self.weights["strategy_weights"][best_strategy] = min(current_weight * 1.1, 0.3)
358
-
359
- normalize_weights(self.weights["strategy_weights"])
360
- print("Gradual weights adjustment completed")
361
-
362
- # 🔴 جديد: دالة التغذية الراجعة لـ LLM
363
- async def get_best_exit_profile(self, entry_strategy: str) -> str:
364
- """
365
- يجد أفضل ملف خروج (Exit Profile) لاستراتيجية دخول معينة
366
- بناءً على متوسط الربح/الخسارة (avg_pnl_percent).
367
- """
368
- if not self.initialized or not self.exit_profile_effectiveness:
369
- return "unknown"
370
-
371
- relevant_profiles = {}
372
-
373
- for combined_key, data in self.exit_profile_effectiveness.items():
374
- if combined_key.startswith(f"{entry_strategy}_"):
375
- # يتطلب 3 صفقات على الأقل لاعتباره
376
- if data.get("total_trades", 0) >= 3:
377
- exit_profile_name = combined_key.replace(f"{entry_strategy}_", "", 1)
378
-
379
- # استخدام متوسط الربح/الخسارة كمقياس أساسي
380
- avg_pnl = data["total_pnl_percent"] / data["total_trades"]
381
-
382
- # استخدام مقياس مركب (مثل Sharpe ratio المبسط)
383
- # pnl_std_dev = np.std(data["pnl_list"]) if len(data["pnl_list"]) > 1 else 0
384
- # risk_adjusted_return = avg_pnl / (pnl_std_dev + 1e-6) # +1e-6 لمنع القسمة على صفر
385
-
386
- relevant_profiles[exit_profile_name] = avg_pnl # استخدام avg_pnl
387
-
388
- if not relevant_profiles:
389
- return "unknown" # لا توجد بيانات كافية
390
-
391
- # إرجاع اسم ملف الخروج صاحب أعلى متوسط ربح
392
- best_profile = max(relevant_profiles, key=relevant_profiles.get)
393
- print(f"🧠 Learning Feedback: Best exit for '{entry_strategy}' is '{best_profile}' (Avg PnL: {relevant_profiles[best_profile]:.2f}%)")
394
- return best_profile
395
-
396
- async def get_current_market_conditions(self):
397
- try:
398
- if not self.data_manager: raise ValueError("DataManager unavailable")
399
- market_context = await self.data_manager.get_market_context_async()
400
- if not market_context: raise ValueError("Market context fetch failed")
401
- return {
402
- "current_trend": market_context.get('market_trend', 'sideways_market'),
403
- "volatility": calculate_market_volatility(market_context),
404
- "market_sentiment": market_context.get('btc_sentiment', 'NEUTRAL'),
405
- "whale_activity": market_context.get('general_whale_activity', {}).get('sentiment', 'NEUTRAL'),
406
- "fear_greed_index": market_context.get('fear_and_greed_index', 50)
407
- }
408
- except Exception as e:
409
- print(f"Market conditions fetch failed: {e}")
410
- return {
411
- "current_trend": "sideways_market", "volatility": "medium",
412
- "market_sentiment": "neutral", "whale_activity": "low", "fear_greed_index": 50
413
- }
414
-
415
- async def calculate_performance_metrics(self):
416
- if not self.performance_history: return {"status": "No performance data yet"}
417
- recent_trades = self.performance_history[-50:]
418
- total_trades = len(recent_trades)
419
- successful_trades = sum(1 for trade in recent_trades
420
- if trade['outcome'] in ["SUCCESS", "CLOSED_BY_REANALYSIS", "CLOSED_BY_MONITOR"] and trade.get('pnl_percent', 0) > 0)
421
- success_rate = successful_trades / total_trades if total_trades > 0 else 0
422
- total_pnl = sum(trade.get('pnl_percent', 0) for trade in recent_trades)
423
- avg_pnl = total_pnl / total_trades if total_trades > 0 else 0
424
-
425
- strategy_performance = {}
426
- for strategy, data in self.strategy_effectiveness.items():
427
- if data["total_trades"] > 0:
428
- strategy_success_rate = data["successful_trades"] / data["total_trades"]
429
- strategy_avg_pnl = data["total_pnl_percent"] / data["total_trades"]
430
- strategy_performance[strategy] = {
431
- "success_rate": strategy_success_rate, "avg_pnl_percent": strategy_avg_pnl,
432
- "total_trades": data["total_trades"], "successful_trades": data["successful_trades"]
433
- }
434
-
435
- # 🔴 جديد: إضافة إحصائيات أداء ملف الخروج
436
- exit_profile_performance = {}
437
- for combined_key, data in self.exit_profile_effectiveness.items():
438
- if data["total_trades"] > 0:
439
- profile_success_rate = data["successful_trades"] / data["total_trades"]
440
- profile_avg_pnl = data["total_pnl_percent"] / data["total_trades"]
441
- exit_profile_performance[combined_key] = {
442
- "success_rate": profile_success_rate, "avg_pnl_percent": profile_avg_pnl,
443
- "total_trades": data["total_trades"]
444
- }
445
-
446
- market_performance = {}
447
- for condition, data in self.market_patterns.items():
448
- if data["total_trades"] > 0:
449
- market_success_rate = data["successful_trades"] / data["total_trades"]
450
- market_avg_pnl = data["total_pnl_percent"] / data["total_trades"]
451
- market_performance[condition] = {
452
- "success_rate": market_success_rate, "avg_pnl_percent": market_avg_pnl,
453
- "total_trades": data["total_trades"]
454
- }
455
-
456
- return {
457
- "overall_success_rate": success_rate, "overall_avg_pnl_percent": avg_pnl,
458
- "total_analyzed_trades": len(self.performance_history), "recent_trades_analyzed": total_trades,
459
- "strategy_performance": strategy_performance,
460
- "exit_profile_performance": exit_profile_performance, # 🔴 جديد
461
- "market_performance": market_performance,
462
- "last_updated": datetime.now().isoformat()
463
- }
464
-
465
- async def get_optimized_strategy_weights(self, market_condition):
466
- try:
467
- if not self.initialized: return await self.get_default_strategy_weights()
468
- if (not self.weights or "strategy_weights" not in self.weights or not self.weights["strategy_weights"]):
469
- return await self.get_default_strategy_weights()
470
- base_weights = self.weights["strategy_weights"].copy()
471
- if not any(weight > 0 for weight in base_weights.values()):
472
- return await self.get_default_strategy_weights()
473
- print(f"Using learned weights: {base_weights}")
474
- return base_weights
475
- except Exception as e:
476
- print(f"Optimized weights calculation failed: {e}")
477
- return await self.get_default_strategy_weights()
478
-
479
- async def get_default_strategy_weights(self):
480
- return {
481
- "trend_following": 0.18, "mean_reversion": 0.15, "breakout_momentum": 0.22,
482
- "volume_spike": 0.12, "whale_tracking": 0.15, "pattern_recognition": 0.10,
483
- "hybrid_ai": 0.08
484
- }
485
-
486
- async def get_risk_parameters(self, symbol_volatility):
487
- if not self.weights or "risk_parameters" not in self.weights: await self.initialize_default_weights()
488
- risk_params = self.weights.get("risk_parameters", {}).copy()
489
- if symbol_volatility == "HIGH":
490
- risk_params["stop_loss_base"] *= 1.5
491
- risk_params["max_position_size"] *= 0.7
492
- risk_params["risk_reward_ratio"] = 1.5
493
- elif symbol_volatility == "LOW":
494
- risk_params["stop_loss_base"] *= 0.7
495
- risk_params["max_position_size"] *= 1.2
496
- risk_params["risk_reward_ratio"] = 2.5
497
- return risk_params
498
-
499
- async def suggest_improvements(self):
500
- improvements = []
501
- if not self.performance_history:
502
- improvements.append("Start collecting performance data from first trades")
503
- return improvements
504
-
505
- # ... (التحليل الأساسي يبقى كما هو)
506
- for strategy, data in self.strategy_effectiveness.items():
507
- if data["total_trades"] >= 3:
508
- success_rate = data["successful_trades"] / data["total_trades"]
509
- avg_pnl = data["total_pnl_percent"] / data["total_trades"]
510
- if success_rate < 0.3 and avg_pnl < 0:
511
- improvements.append(f"Strategy {strategy} poor performance ({success_rate:.1%} success, {avg_pnl:+.1f}% average) - suggest reducing usage")
512
- elif success_rate > 0.6 and avg_pnl > 2:
513
- improvements.append(f"Strategy {strategy} excellent performance ({success_rate:.1%} success, {avg_pnl:+.1f}% average) - suggest increasing usage")
514
-
515
- # 🔴 جديد: اقتراح تحسينات بناءً على ملفات الخروج
516
- for combined_key, data in self.exit_profile_effectiveness.items():
517
- if data["total_trades"] >= 5: # يتطلب 5 صفقات للمزيج
518
- success_rate = data["successful_trades"] / data["total_trades"]
519
- avg_pnl = data["total_pnl_percent"] / data["total_trades"]
520
- if success_rate < 0.3 and avg_pnl < -0.5:
521
- improvements.append(f"Exit Combo '{combined_key}' is failing ({success_rate:.1%} success, {avg_pnl:+.1f}% avg). AVOID.")
522
- elif success_rate > 0.7 and avg_pnl > 1.5:
523
- improvements.append(f"Exit Combo '{combined_key}' is performing well ({success_rate:.1%} success, {avg_pnl:+.1f}% avg). PRIORITIZE.")
524
-
525
- for market_condition, data in self.market_patterns.items():
526
- # ... (التحليل الأساسي يبقى كما هو)
527
- if data["total_trades"] >= 5:
528
- success_rate = data["successful_trades"] / data["total_trades"]
529
- if success_rate < 0.4:
530
- improvements.append(f"Poor performance in {market_condition} market ({success_rate:.1%} success) - needs strategy review")
531
-
532
- if not improvements: improvements.append("No suggested improvements currently - continue data collection")
533
- return improvements
534
-
535
- async def force_strategy_learning(self):
536
- print("Forcing strategy update from current data...")
537
- if not self.performance_history:
538
- print("No performance data to learn from")
539
- return
540
- for entry in self.performance_history:
541
- await self.update_strategy_effectiveness(entry) # 🔴 هذا سيحدث الآن كلا القاموسين
542
- await self.update_market_patterns(entry)
543
- await self.adapt_weights_based_on_performance()
544
- await self.save_weights_to_r2()
545
- await self.save_exit_profile_effectiveness() # 🔴 جديد
546
- print("Strategy update forced successfully (including exit profiles)")
547
-
548
- print("Enhanced self-learning system loaded - V2 (with Exit Profile Learning)")