tomirisai80 commited on
Commit
63895c6
·
verified ·
1 Parent(s): e638379

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -29
app.py CHANGED
@@ -1,11 +1,11 @@
1
  # ============================================
2
- # 👑 TOMIRIS SPACE 19 v8.1 — SOL/USD MASTER (Hub-Connected)
3
  # ============================================
4
  import os, time, threading, warnings, json, asyncio
5
  from typing import Dict, Any, Optional, List, Tuple
6
  import numpy as np, pandas as pd
7
  import requests
8
- from datetime import datetime
9
  from collections import deque
10
  from fastapi import FastAPI, Query
11
  warnings.filterwarnings('ignore')
@@ -49,7 +49,6 @@ if HAS_FIREBASE:
49
  SPACE_URLS: Dict[str, str] = {
50
  "space_17_hub": os.getenv("SPACE17_URL", "https://tomiris-ai-name5-5.hf.space"),
51
  "space_18_arbiter": os.getenv("SPACE18_URL", "https://tomiris-ai-name6-6.hf.space"),
52
- "space_31_perf": "https://nuxotetotmailsvoboden-tomiris-perf.hf.space"
53
  }
54
 
55
  HUB_URL = SPACE_URLS["space_17_hub"]
@@ -64,6 +63,8 @@ TWELVE_KEYS: List[str] = [
64
  SYMBOL: str = "SOL/USD"
65
  MT5_SYMBOL: str = "SOLUSD"
66
  TIMEFRAMES: List[str] = ["15min", "1h", "4h"]
 
 
67
 
68
  try:
69
  with open("best_config.json", "r") as f:
@@ -111,7 +112,7 @@ COMPONENT_PERF: Dict[str, Dict[str, float]] = {
111
  YAHOO_INTERVAL_MAP: Dict[str, str] = {"15min": "15m", "1h": "60m", "4h": "4h"}
112
 
113
  # ================= ЗАГРУЗКА МОДЕЛЕЙ =================
114
- print(f"🔥 SPACE 19 v8.1: Загрузка моделей для {SYMBOL}...")
115
  MODELS: Dict[str, Optional[Any]] = {"xgb_daily": None, "xgb_4h": None, "lgb": None}
116
 
117
  if HAS_JOBLIB:
@@ -143,7 +144,7 @@ def get_next_twelve_key() -> str:
143
  return key
144
 
145
  session = requests.Session()
146
- session.headers.update({"User-Agent": "Tomiris-Space19-v8.1"})
147
 
148
  def safe_float(value: Any, default: float = 0.0) -> float:
149
  try:
@@ -203,6 +204,20 @@ def hurst_exponent(series: pd.Series, lags: int = 20) -> float:
203
  def fetch_google_trends_index(keyword: str) -> float:
204
  return 50.0
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  # ================= DATA HUB =================
207
  def get_mt5_price_from_hub() -> Dict[str, Any]:
208
  global HUB_CACHE
@@ -405,20 +420,6 @@ def fetch_space_signal(name: str, url: str, endpoint: str = "/consilium") -> Dic
405
  breaker_fail(name)
406
  return {"active": False, "reason": str(e)[:50]}
407
 
408
- # ================= ОТПРАВКА В HUB =================
409
- def send_signal_to_hub(symbol: str, direction: str, confidence: float):
410
- try:
411
- session.post(f"{HUB_URL}/signal", json={
412
- "space": "space_19_sol_master",
413
- "symbol": symbol,
414
- "direction": direction,
415
- "confidence": confidence,
416
- "raw": json.dumps({"source": "space_19_sol_master"})
417
- }, timeout=5)
418
- print(f"📤 {symbol}: {direction} conf={confidence:.3f} отправлен в Hub")
419
- except Exception as e:
420
- print(f"Ошибка отправки в Hub: {e}")
421
-
422
  # ================= ПОСТРОЕНИЕ ПРИЗНАКОВ =================
423
  def build_features_from_mt5(mt5_features: Dict[str, Any]) -> Dict[str, Any]:
424
  features: Dict[str, Any] = {}
@@ -628,7 +629,7 @@ def get_sol_signal() -> Optional[Dict[str, Any]]:
628
  "signal": {"direction": "WAIT", "confidence": 0.0},
629
  "reason": "stress_test_black_swan"
630
  }
631
- send_signal_to_hub(SYMBOL, "WAIT", 0.0)
632
  return result
633
 
634
  regime = detect_market_regime(model_features)
@@ -799,17 +800,80 @@ def get_sol_signal() -> Optional[Dict[str, Any]]:
799
  "risk": {"sl": sl, "tp": tp, "rr": round(tp_dist/(sl_dist+1e-10), 2) if direction != "WAIT" else 0},
800
  "meta": {
801
  "latency_ms": latency,
802
- "model_version": "v8.1_hub_connected",
803
  "features_used": len(model_features) if model_features else 0,
804
  "dynamic_weights": comp_weights
805
  }
806
  }
807
 
808
- # Отправка в Hub вместо Arbiter
809
- send_signal_to_hub(SYMBOL, result["signal"]["direction"], result["signal"]["confidence"])
810
  print(f"🥉 SOL/USD: {direction} | conf={confidence:.3f} | ensemble={xgb_prob:.3f} | models={models_used} | regime={regime} | latency={latency}ms")
811
  return result
812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  # ================= KEEP-ALIVE =================
814
  def keep_alive():
815
  while True:
@@ -818,21 +882,24 @@ def keep_alive():
818
  requests.get("http://localhost:7860/health", timeout=5)
819
  except:
820
  pass
 
821
  threading.Thread(target=keep_alive, daemon=True).start()
 
 
822
 
823
  # ================= FASTAPI =================
824
- app = FastAPI(title="TOMIRIS SOL/USD MASTER v8.1 Hub-Connected")
825
 
826
  @app.get("/health")
827
  async def health():
828
  models_loaded = sum(1 for m in ["xgb_daily","xgb_4h","lgb"] if MODELS.get(m) is not None)
829
  return {
830
- "space": "Space 19 v8.1 Hub-Connected",
831
  "status": "operational",
832
  "symbol": SYMBOL,
833
  "models_loaded": models_loaded,
834
- "dynamic_weights": True,
835
- "hub_connected": True
836
  }
837
 
838
  @app.get("/consilium")
@@ -889,6 +956,6 @@ async def explain():
889
  }
890
  return {"error": "No prediction yet"}
891
 
892
- print("🚀 SPACE 19 v8.1 — SOL/USD MASTER (Hub-Connected) ЗАПУЩЕН!")
893
- print("🥉 Ансамбль daily+4h + Meta SOL Score + Dynamic Weights + Hub Integration")
894
  print("✅ Готов к бою!")
 
1
  # ============================================
2
+ # 👑 TOMIRIS SPACE 19 v9.0 — SOL/USD MASTER (HubConnected + Auto‑Retrain)
3
  # ============================================
4
  import os, time, threading, warnings, json, asyncio
5
  from typing import Dict, Any, Optional, List, Tuple
6
  import numpy as np, pandas as pd
7
  import requests
8
+ from datetime import datetime, timedelta
9
  from collections import deque
10
  from fastapi import FastAPI, Query
11
  warnings.filterwarnings('ignore')
 
49
  SPACE_URLS: Dict[str, str] = {
50
  "space_17_hub": os.getenv("SPACE17_URL", "https://tomiris-ai-name5-5.hf.space"),
51
  "space_18_arbiter": os.getenv("SPACE18_URL", "https://tomiris-ai-name6-6.hf.space"),
 
52
  }
53
 
54
  HUB_URL = SPACE_URLS["space_17_hub"]
 
63
  SYMBOL: str = "SOL/USD"
64
  MT5_SYMBOL: str = "SOLUSD"
65
  TIMEFRAMES: List[str] = ["15min", "1h", "4h"]
66
+ AUTO_REPORT_INTERVAL = 300 # секунд между авто‑отправками
67
+ RETRAIN_INTERVAL = 30 * 86400 # 30 дней
68
 
69
  try:
70
  with open("best_config.json", "r") as f:
 
112
  YAHOO_INTERVAL_MAP: Dict[str, str] = {"15min": "15m", "1h": "60m", "4h": "4h"}
113
 
114
  # ================= ЗАГРУЗКА МОДЕЛЕЙ =================
115
+ print(f"🔥 SPACE 19 v9.0: Загрузка моделей для {SYMBOL}...")
116
  MODELS: Dict[str, Optional[Any]] = {"xgb_daily": None, "xgb_4h": None, "lgb": None}
117
 
118
  if HAS_JOBLIB:
 
144
  return key
145
 
146
  session = requests.Session()
147
+ session.headers.update({"User-Agent": "Tomiris-Space19-v9.0"})
148
 
149
  def safe_float(value: Any, default: float = 0.0) -> float:
150
  try:
 
204
  def fetch_google_trends_index(keyword: str) -> float:
205
  return 50.0
206
 
207
+ # ================= ОТПРАВКА В HUB =================
208
+ def send_signal_to_hub(direction, confidence):
209
+ try:
210
+ session.post(f"{HUB_URL}/signal", json={
211
+ "space": "space_19_sol_master",
212
+ "symbol": SYMBOL,
213
+ "direction": direction,
214
+ "confidence": confidence,
215
+ "raw": json.dumps({"source": "space_19_sol_master"})
216
+ }, timeout=5)
217
+ print(f"📤 {SYMBOL}: {direction} conf={confidence:.3f} отправлен в Hub")
218
+ except Exception as e:
219
+ print(f"Ошибка отправки в Hub: {e}")
220
+
221
  # ================= DATA HUB =================
222
  def get_mt5_price_from_hub() -> Dict[str, Any]:
223
  global HUB_CACHE
 
420
  breaker_fail(name)
421
  return {"active": False, "reason": str(e)[:50]}
422
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  # ================= ПОСТРОЕНИЕ ПРИЗНАКОВ =================
424
  def build_features_from_mt5(mt5_features: Dict[str, Any]) -> Dict[str, Any]:
425
  features: Dict[str, Any] = {}
 
629
  "signal": {"direction": "WAIT", "confidence": 0.0},
630
  "reason": "stress_test_black_swan"
631
  }
632
+ send_signal_to_hub("WAIT", 0.0)
633
  return result
634
 
635
  regime = detect_market_regime(model_features)
 
800
  "risk": {"sl": sl, "tp": tp, "rr": round(tp_dist/(sl_dist+1e-10), 2) if direction != "WAIT" else 0},
801
  "meta": {
802
  "latency_ms": latency,
803
+ "model_version": "v9.0_auto_retrain",
804
  "features_used": len(model_features) if model_features else 0,
805
  "dynamic_weights": comp_weights
806
  }
807
  }
808
 
809
+ send_signal_to_hub(result["signal"]["direction"], result["signal"]["confidence"])
 
810
  print(f"🥉 SOL/USD: {direction} | conf={confidence:.3f} | ensemble={xgb_prob:.3f} | models={models_used} | regime={regime} | latency={latency}ms")
811
  return result
812
 
813
+ # ================= АВТО-ОТПРАВКА =================
814
+ def auto_report():
815
+ while True:
816
+ time.sleep(AUTO_REPORT_INTERVAL)
817
+ try:
818
+ get_sol_signal()
819
+ except Exception as e:
820
+ print(f"Ошибка авто-отправки: {e}")
821
+
822
+ # ================= АВТО-ДООБУЧЕНИЕ =================
823
+ def retrain_models():
824
+ print("🔄 Запуск дообучения моделей SOL...")
825
+ try:
826
+ # Используем дневные данные за последний год через Yahoo (или Hub)
827
+ df = None
828
+ if HAS_YFINANCE:
829
+ yf_data = yf.download("SOL-USD", period="1y", interval="1d", progress=False)
830
+ if not yf_data.empty:
831
+ df = pd.DataFrame({
832
+ 'close': yf_data['Close'].values.flatten(),
833
+ 'high': yf_data['High'].values.flatten(),
834
+ 'low': yf_data['Low'].values.flatten(),
835
+ 'open': yf_data['Open'].values.flatten(),
836
+ 'volume': yf_data['Volume'].values.flatten()
837
+ }).dropna()
838
+ if df is None or len(df) < 200:
839
+ print("Недостаточно данных для дообучения")
840
+ return
841
+
842
+ features_list = []
843
+ targets = []
844
+ for i in range(100, len(df)-24):
845
+ sub_df = df.iloc[:i+1]
846
+ feats = build_sol_features(sub_df)
847
+ if not feats:
848
+ continue
849
+ features_list.append(feats)
850
+ target = 1 if df["close"].iloc[i+24] > df["close"].iloc[i] else 0
851
+ targets.append(target)
852
+
853
+ if not features_list:
854
+ return
855
+ # Приводим к единому размеру (pad до 200)
856
+ X = np.array([list(f.values())[:200] + [0.0]*(200 - len(f)) for f in features_list])
857
+ y = np.array(targets)
858
+
859
+ for model_name in ["xgb_daily", "xgb_4h"]:
860
+ model = MODELS.get(model_name)
861
+ if model and hasattr(model, 'fit'):
862
+ model.fit(X, y)
863
+ joblib.dump(model, f"{model_name}_retrained.joblib")
864
+ print(f"✅ {model_name} дообучена")
865
+ if MODELS.get("lgb") and hasattr(MODELS["lgb"], 'fit'):
866
+ MODELS["lgb"].fit(X, y)
867
+ joblib.dump(MODELS["lgb"], "lgb_retrained.joblib")
868
+ print("✅ LightGBM дообучена")
869
+ except Exception as e:
870
+ print(f"Ошибка дообучения: {e}")
871
+
872
+ def auto_retrain():
873
+ while True:
874
+ time.sleep(RETRAIN_INTERVAL)
875
+ retrain_models()
876
+
877
  # ================= KEEP-ALIVE =================
878
  def keep_alive():
879
  while True:
 
882
  requests.get("http://localhost:7860/health", timeout=5)
883
  except:
884
  pass
885
+
886
  threading.Thread(target=keep_alive, daemon=True).start()
887
+ threading.Thread(target=auto_report, daemon=True).start()
888
+ threading.Thread(target=auto_retrain, daemon=True).start()
889
 
890
  # ================= FASTAPI =================
891
+ app = FastAPI(title="TOMIRIS SOL/USD MASTER v9.0 Auto-Retrain")
892
 
893
  @app.get("/health")
894
  async def health():
895
  models_loaded = sum(1 for m in ["xgb_daily","xgb_4h","lgb"] if MODELS.get(m) is not None)
896
  return {
897
+ "space": "Space 19 v9.0 Auto-Retrain",
898
  "status": "operational",
899
  "symbol": SYMBOL,
900
  "models_loaded": models_loaded,
901
+ "hub_connected": True,
902
+ "auto_retrain": True
903
  }
904
 
905
  @app.get("/consilium")
 
956
  }
957
  return {"error": "No prediction yet"}
958
 
959
+ print("🚀 SPACE 19 v9.0 — SOL/USD MASTER (Hub-Connected + Auto-Retrain) ЗАПУЩЕН!")
960
+ print("🥉 Ансамбль daily+4h + Meta SOL Score + Dynamic Weights + Auto-Retrain")
961
  print("✅ Готов к бою!")