Spaces:
Paused
Paused
Update periodic_tuner.py
Browse files- periodic_tuner.py +16 -9
periodic_tuner.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# ============================================================
|
| 2 |
-
# 🗓️ periodic_tuner.py (V4.
|
| 3 |
# ============================================================
|
| 4 |
|
| 5 |
import asyncio
|
|
@@ -164,7 +164,7 @@ class AutoTunerScheduler:
|
|
| 164 |
self.trade_manager = trade_manager
|
| 165 |
self.state_file = "scheduler_state.json"
|
| 166 |
|
| 167 |
-
# التوقيتات
|
| 168 |
self.last_weekly_run = None
|
| 169 |
self.last_monthly_run = None
|
| 170 |
|
|
@@ -176,7 +176,7 @@ class AutoTunerScheduler:
|
|
| 176 |
logger.info("🕰️ [Scheduler] Auto-Tuner Armed & Ready.")
|
| 177 |
|
| 178 |
async def start_loop(self):
|
| 179 |
-
await self._load_state()
|
| 180 |
while True:
|
| 181 |
try:
|
| 182 |
await asyncio.sleep(3600)
|
|
@@ -204,11 +204,15 @@ class AutoTunerScheduler:
|
|
| 204 |
if state.get('last_monthly'):
|
| 205 |
self.last_monthly_run = datetime.fromisoformat(state['last_monthly'])
|
| 206 |
|
| 207 |
-
# استرجاع العدادات
|
| 208 |
self.weekly_count = state.get('weekly_count', 0)
|
| 209 |
self.monthly_count = state.get('monthly_count', 0)
|
| 210 |
-
|
| 211 |
logger.info(f" 🕰️ [Scheduler] State Restored (W:{self.weekly_count} | M:{self.monthly_count}).")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
except Exception: pass
|
| 213 |
|
| 214 |
async def _save_state(self):
|
|
@@ -221,7 +225,6 @@ class AutoTunerScheduler:
|
|
| 221 |
}
|
| 222 |
if self.trade_manager.r2:
|
| 223 |
await self.trade_manager.r2.upload_json_async(state, self.state_file)
|
| 224 |
-
logger.info(" 💾 [Scheduler] State Saved.")
|
| 225 |
except Exception: pass
|
| 226 |
|
| 227 |
def _needs_run(self, period_type):
|
|
@@ -266,7 +269,7 @@ class AutoTunerScheduler:
|
|
| 266 |
finally:
|
| 267 |
self.is_running = False
|
| 268 |
|
| 269 |
-
# ✅ دالة جلب المقاييس للواجهة
|
| 270 |
def get_status_metrics(self):
|
| 271 |
def _fmt_time(last_dt):
|
| 272 |
if not last_dt: return "Pending"
|
|
@@ -275,10 +278,14 @@ class AutoTunerScheduler:
|
|
| 275 |
h = diff.seconds // 3600
|
| 276 |
return f"{d}d {h}h"
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
return {
|
| 279 |
-
"weekly_timer":
|
| 280 |
"weekly_count": self.weekly_count,
|
| 281 |
-
"monthly_timer":
|
| 282 |
"monthly_count": self.monthly_count,
|
| 283 |
"is_running": self.is_running
|
| 284 |
}
|
|
|
|
| 1 |
# ============================================================
|
| 2 |
+
# 🗓️ periodic_tuner.py (V4.3 - GEM-Architect: Timer Persistence)
|
| 3 |
# ============================================================
|
| 4 |
|
| 5 |
import asyncio
|
|
|
|
| 164 |
self.trade_manager = trade_manager
|
| 165 |
self.state_file = "scheduler_state.json"
|
| 166 |
|
| 167 |
+
# التوقيتات (ستيم تحميلها من R2)
|
| 168 |
self.last_weekly_run = None
|
| 169 |
self.last_monthly_run = None
|
| 170 |
|
|
|
|
| 176 |
logger.info("🕰️ [Scheduler] Auto-Tuner Armed & Ready.")
|
| 177 |
|
| 178 |
async def start_loop(self):
|
| 179 |
+
await self._load_state() # Force Load on Start
|
| 180 |
while True:
|
| 181 |
try:
|
| 182 |
await asyncio.sleep(3600)
|
|
|
|
| 204 |
if state.get('last_monthly'):
|
| 205 |
self.last_monthly_run = datetime.fromisoformat(state['last_monthly'])
|
| 206 |
|
|
|
|
| 207 |
self.weekly_count = state.get('weekly_count', 0)
|
| 208 |
self.monthly_count = state.get('monthly_count', 0)
|
|
|
|
| 209 |
logger.info(f" 🕰️ [Scheduler] State Restored (W:{self.weekly_count} | M:{self.monthly_count}).")
|
| 210 |
+
else:
|
| 211 |
+
# ✅ FIX: إذا كان الملف جديداً، نبدأ التوقيت من "الآن" بدلاً من الانتظار
|
| 212 |
+
logger.info(" 🕰️ [Scheduler] New Instance. Initializing Clocks...")
|
| 213 |
+
self.last_weekly_run = datetime.now()
|
| 214 |
+
self.last_monthly_run = datetime.now()
|
| 215 |
+
await self._save_state()
|
| 216 |
except Exception: pass
|
| 217 |
|
| 218 |
async def _save_state(self):
|
|
|
|
| 225 |
}
|
| 226 |
if self.trade_manager.r2:
|
| 227 |
await self.trade_manager.r2.upload_json_async(state, self.state_file)
|
|
|
|
| 228 |
except Exception: pass
|
| 229 |
|
| 230 |
def _needs_run(self, period_type):
|
|
|
|
| 269 |
finally:
|
| 270 |
self.is_running = False
|
| 271 |
|
| 272 |
+
# ✅ دالة جلب المقاييس للواجهة (محسنة)
|
| 273 |
def get_status_metrics(self):
|
| 274 |
def _fmt_time(last_dt):
|
| 275 |
if not last_dt: return "Pending"
|
|
|
|
| 278 |
h = diff.seconds // 3600
|
| 279 |
return f"{d}d {h}h"
|
| 280 |
|
| 281 |
+
# إذا كانت None (لم يتم التحميل بعد)، نعيد Init
|
| 282 |
+
w_time = _fmt_time(self.last_weekly_run) if self.last_weekly_run else "Init..."
|
| 283 |
+
m_time = _fmt_time(self.last_monthly_run) if self.last_monthly_run else "Init..."
|
| 284 |
+
|
| 285 |
return {
|
| 286 |
+
"weekly_timer": w_time,
|
| 287 |
"weekly_count": self.weekly_count,
|
| 288 |
+
"monthly_timer": m_time,
|
| 289 |
"monthly_count": self.monthly_count,
|
| 290 |
"is_running": self.is_running
|
| 291 |
}
|