CoolFace
Apppublic

tomiris-executor/Final_last_bablo

sourceHugging Facemitupdated 3mo agoView on Hugging Face
0likes
app.py405 linesDownload Raw Back to root
1# ============================================2# АВТО-УСТАНОВКА ПАКЕТОВ3# ============================================4import subprocess, sys, importlib5 6REQUIRED_PACKAGES = {7    'numpy': 'numpy',8    'httpx': 'httpx',9    'fastapi': 'fastapi',10    'uvicorn': 'uvicorn',11    'requests': 'requests'12}13 14for module_name, pip_name in REQUIRED_PACKAGES.items():15    try:16        importlib.import_module(module_name)17    except ImportError:18        print(f"📦 Устанавливаю {pip_name}...")19        subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name])20        print(f"✅ {pip_name} установлен!")21 22# ============================================23# 👑 TOMIRIS SPACE 24 v3.1 — ECOSYSTEM AGGREGATOR PRO24# ============================================25import os, time, json, logging, asyncio26from typing import Dict, Any, List, Optional27from datetime import datetime, timezone28from collections import deque29import numpy as np30import httpx31from fastapi import FastAPI, Query32 33logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")34logger = logging.getLogger("Space24_Ecosystem")35 36# ================= КОНФИГУРАЦИЯ =================37SPACE_ID = 2438SPACE_NAME = "Ecosystem Aggregator"39SYMBOLS = ["XAU/USD", "ETH/USD", "SOL/USD"]40 41HUB_URL = "https://TOMI-HUB-HUB-FINAL.hf.space"42HUB_SECRET = os.getenv("HUB_SECRET", "TomyrisUltraSecret2026!")43 44STARTUP_SLEEP = int(os.getenv("STARTUP_SLEEP", "120"))  # 2 минуты45AUTO_SEND_INTERVAL = int(os.getenv("AUTO_SEND_INTERVAL", "300"))  # 5 минут46 47logger.info(f"🔗 Хаб: {HUB_URL} | Старт: {STARTUP_SLEEP}с | Интервал: {AUTO_SEND_INTERVAL}с")48 49# ================= HTTP КЛИЕНТ =================50http_client = httpx.AsyncClient(timeout=15.0)51 52def hub_headers():53    return {"X-Hub-Secret": HUB_SECRET, "Content-Type": "application/json"}54 55# ================= ЛОГГЕР В ХАБ =================56async def log_to_hub(event_type: str, message: str, details: dict = None):57    try:58        await http_client.post(59            f"{HUB_URL}/log",60            json={61                "space_id": str(SPACE_ID),62                "event_type": event_type,63                "message": message,64                "details": details or {}65            },66            headers=hub_headers(),67            timeout=568        )69    except: pass70 71# ================= ECOSYSTEM SPACES (по space_id) =================72ECOSYSTEM_SPACES = {73    "19": {74        "weight": 0.25,75        "symbols": ["SOL/USD"],76        "description": "SOL Master",77        "cache_ttl": 30078    },79    "20": {80        "weight": 0.25,81        "symbols": ["ETH/USD"],82        "description": "L2 & DeFi Pulse",83        "cache_ttl": 30084    },85    "21": {86        "weight": 0.25,87        "symbols": ["XAU/USD"],88        "description": "Gold Macro & Flow",89        "cache_ttl": 60090    },91    "22": {92        "weight": 0.15,93        "symbols": ["XAU/USD", "ETH/USD", "SOL/USD"],94        "description": "Cross-Asset Sentiment",95        "cache_ttl": 30096    },97    "23": {98        "weight": 0.10,99        "symbols": ["ETH/USD", "SOL/USD"],100        "description": "On-Chain Anomaly",101        "cache_ttl": 60102    }103}104 105# ================= ГЛОБАЛЬНЫЙ КЭШ =================106cache_store = {}107cache_times = {}108 109# ================= ПОЛУЧЕНИЕ СИГНАЛОВ ЧЕРЕЗ ХАБ =================110async def fetch_space_signal_from_hub(space_id: str, config: Dict, symbol: str) -> Optional[Dict]:111    """Получает последний сигнал Space'а через Хаб (по space_id)"""112    cache_key = f"space_{space_id}_{symbol}"113    ttl = config.get("cache_ttl", 300)114    now = time.time()115    116    if cache_key in cache_store and (now - cache_times.get(cache_key, 0)) < ttl:117        return cache_store[cache_key]118 119    try:120        r = await http_client.get(121            f"{HUB_URL}/signals",122            params={"symbol": symbol, "limit": 100},123            timeout=10,124            headers=hub_headers()125        )126        if r.status_code == 200:127            signals = r.json()128            # Ищем последний сигнал от нужного space_id129            for s in reversed(signals):130                sid = str(s.get("space_id", ""))131                if sid == space_id:132                    direction = s.get("direction", s.get("signal", "WAIT"))133                    # Нормализуем134                    if direction in ("LONG", "BUY"):135                        direction = "BUY"136                    elif direction in ("SHORT", "SELL"):137                        direction = "SELL"138                    else:139                        direction = "WAIT"140                    141                    data = {142                        "signal": {143                            "direction": direction,144                            "confidence": float(s.get("confidence", 0))145                        }146                    }147                    cache_store[cache_key] = data148                    cache_times[cache_key] = time.time()149                    return data150        151        # Не нашли — WAIT152        data = {"signal": {"direction": "WAIT", "confidence": 0.0}}153        cache_store[cache_key] = data154        cache_times[cache_key] = time.time()155        return data156    except Exception as e:157        logger.warning(f"Hub fetch space {space_id}: {e}")158    return {"signal": {"direction": "WAIT", "confidence": 0.0}}159 160# ================= ДИНАМИЧЕСКИЕ ВЕСА =================161async def fetch_dynamic_weights() -> Dict[str, float]:162    try:163        r = await http_client.get(f"{HUB_URL}/weights", timeout=8, headers=hub_headers())164        if r.status_code == 200:165            data = r.json()166            weights = data.get("weights", {})167            if weights:168                return {k: v for k, v in weights.items() if k in ECOSYSTEM_SPACES}169    except:170        pass171    return {space_id: cfg["weight"] for space_id, cfg in ECOSYSTEM_SPACES.items()}172 173# ================= АГРЕГАЦИЯ =================174async def aggregate_ecosystem(symbol: str) -> Dict[str, Any]:175    dynamic_weights = await fetch_dynamic_weights()176    177    tasks = []178    space_ids = []179    for space_id, cfg in ECOSYSTEM_SPACES.items():180        if symbol in cfg["symbols"]:181            tasks.append(fetch_space_signal_from_hub(space_id, cfg, symbol))182            space_ids.append(space_id)183 184    results = await asyncio.gather(*tasks)185 186    signals = {}187    errors = []188    for space_id, res in zip(space_ids, results):189        if res and isinstance(res, dict):190            signals[space_id] = res191        else:192            errors.append(space_id)193 194    total_weight = 0.0195    buy_votes = 0.0196    sell_votes = 0.0197    wait_votes = 0.0198    details = {}199 200    for space_id, data in signals.items():201        weight = dynamic_weights.get(space_id, ECOSYSTEM_SPACES[space_id]["weight"])202        sig = data.get("signal", {})203        direction = sig.get("direction", "WAIT")204        confidence = sig.get("confidence", 0)205 206        if direction == "BUY":207            buy_votes += weight * confidence208        elif direction == "SELL":209            sell_votes += weight * confidence210        else:211            wait_votes += weight * confidence212        213        total_weight += weight214        details[space_id] = {215            "direction": direction,216            "confidence": confidence,217            "weight": weight,218            "status": "active",219            "description": ECOSYSTEM_SPACES[space_id]["description"]220        }221 222    for space_id in errors:223        weight = dynamic_weights.get(space_id, ECOSYSTEM_SPACES[space_id]["weight"])224        details[space_id] = {225            "direction": "ERROR",226            "confidence": 0,227            "weight": weight,228            "status": "error",229            "description": ECOSYSTEM_SPACES[space_id]["description"]230        }231 232    if total_weight == 0:233        return {234            "ecosystem_score": 50.0,235            "direction": "WAIT",236            "confidence": 0.0,237            "active_spaces": 0,238            "error_spaces": len(errors),239            "signals_detail": details240        }241 242    bias = (buy_votes - sell_votes) / total_weight243    ecosystem_score = 50.0 + bias * 50.0244    ecosystem_score = max(0, min(100, ecosystem_score))245 246    wait_ratio = wait_votes / total_weight247    248    if wait_ratio > 0.6:249        direction = "WAIT"250        confidence = wait_ratio251    elif buy_votes > sell_votes * 1.3:252        direction = "BUY"253        confidence = min(0.9, buy_votes / total_weight)254    elif sell_votes > buy_votes * 1.3:255        direction = "SELL"256        confidence = min(0.9, sell_votes / total_weight)257    else:258        direction = "WAIT"259        confidence = max(buy_votes, sell_votes) / total_weight260 261    active_ratio = len(signals) / len(space_ids) if space_ids else 0262    confidence *= 0.5 + 0.5 * active_ratio263 264    return {265        "ecosystem_score": round(ecosystem_score, 2),266        "direction": direction,267        "confidence": round(confidence, 4),268        "active_spaces": len(signals),269        "error_spaces": len(errors),270        "signals_detail": details,271        "votes": {272            "BUY": round(buy_votes, 4),273            "SELL": round(sell_votes, 4),274            "WAIT": round(wait_votes, 4)275        }276    }277 278# ================= ОТПРАВКА В HUB =================279async def send_signal_to_hub(symbol: str, signal: str, confidence: float, features: Dict = None):280    if features is None:281        features = {}282    283    payload = {284        "space_id": SPACE_ID,285        "space_name": SPACE_NAME,286        "symbol": symbol,287        "signal": signal,288        "confidence": round(confidence, 4),289        "features": features,290        "metadata": {"version": "3.1"},291        "timestamp": datetime.now(timezone.utc).isoformat()292    }293    294    for attempt in range(3):295        try:296            r = await http_client.post(f"{HUB_URL}/signals", json=payload, timeout=15, headers=hub_headers())297            if r.status_code == 200:298                logger.info(f"📤 {symbol}: {signal} conf={confidence:.3f}")299                return True300            await asyncio.sleep(2)301        except Exception as e:302            logger.warning(f"Попытка {attempt+1}: {e}")303            await asyncio.sleep(2)304    305    logger.error(f"❌ Не удалось отправить {symbol}")306    return False307 308# ================= ГЛАВНЫЙ СИГНАЛ =================309async def get_ecosystem_aggregate(symbol: str = "XAU/USD") -> Dict[str, Any]:310    start = time.time()311    agg = await aggregate_ecosystem(symbol)312    latency = int((time.time() - start) * 1000)313 314    signal = agg['direction']315    confidence = agg['confidence']316    317    features = {318        "ecosystem_score": agg['ecosystem_score'],319        "active_spaces": agg['active_spaces'],320        "votes": agg['votes']321    }322    323    await send_signal_to_hub(symbol, signal, confidence, features)324 325    logger.info(f"🌐 Ecosystem {symbol}: {signal} conf={confidence:.3f} score={agg['ecosystem_score']} | {latency}ms")326    327    return {328        "space_id": SPACE_ID,329        "timestamp": int(time.time()),330        "symbol": symbol,331        "signal": signal,332        "confidence": confidence,333        "ecosystem_analysis": agg,334        "latency_ms": latency335    }336 337# ================= АВТО-ОТПРАВКА =================338async def auto_send_loop():339    logger.info(f"⏳ Стартовый сон {STARTUP_SLEEP}с...")340    await log_to_hub("STARTUP", f"Ecosystem Aggregator v3.1 запущен, жду {STARTUP_SLEEP}с")341    await asyncio.sleep(STARTUP_SLEEP)342    logger.info(f"🔄 Авто-отправка (интервал {AUTO_SEND_INTERVAL}с)")343    344    while True:345        try:346            for symbol in SYMBOLS:347                await get_ecosystem_aggregate(symbol)348                await asyncio.sleep(2)349            logger.info("✅ Ecosystem цикл завершён")350        except Exception as e:351            logger.error(f"Ошибка: {e}")352            await log_to_hub("ERROR", f"Ошибка: {str(e)[:200]}")353        await asyncio.sleep(AUTO_SEND_INTERVAL)354 355# ================= FASTAPI =================356app = FastAPI(title="Tomiris Space 24 v3.1 — Ecosystem Aggregator Pro")357 358@app.on_event("startup")359async def startup():360    asyncio.create_task(auto_send_loop())361    logger.info(f"🚀 Space 24 v3.1 запущен | Hub: {HUB_URL}")362 363@app.on_event("shutdown")364async def shutdown():365    await http_client.aclose()366 367@app.get("/health")368async def health():369    return {"space_id": SPACE_ID, "status": "operational", "version": "3.1", "ecosystem_spaces": len(ECOSYSTEM_SPACES)}370 371@app.get("/consilium")372async def consilium(symbol: str = Query("XAU/USD")):373    if symbol not in SYMBOLS:374        return {"error": "Invalid symbol"}375    return await get_ecosystem_aggregate(symbol)376 377@app.get("/breakdown/{symbol}")378async def breakdown(symbol: str):379    agg = await aggregate_ecosystem(symbol)380    return {"symbol": symbol, "aggregate": agg}381 382@app.get("/all")383async def all_signals():384    results = {}385    for sym in SYMBOLS:386        results[sym] = await aggregate_ecosystem(sym)387    return results388 389@app.get("/send_now")390async def send_now():391    results = {}392    for symbol in SYMBOLS:393        sig = await get_ecosystem_aggregate(symbol)394        results[symbol] = sig.get("signal", "WAIT")395    return {"status": "sent", "results": results}396 397@app.get("/")398async def root():399    return {"name": "Ecosystem Aggregator v3.1", "space_id": SPACE_ID, "hub": HUB_URL}400 401if __name__ == "__main__":402    import uvicorn403    uvicorn.run(app, host="0.0.0.0", port=7860)404 405print("🚀 SPACE 24 v3.1 — ECOSYSTEM AGGREGATOR PRO ЗАПУЩЕН!")