Spaces:
Running
Running
Thang6822
Update Kronos Platform: New UI, enhanced backend stability and restored Dockerfile
85d632d | import sys | |
| import os | |
| # RECOVERY SCRIPT FOR KRONOS BACKEND v6.0 | |
| # Restores the missing functions and fixes the structure | |
| def get_part1(): # Imports to SYMBOLS | |
| # We can read this from current file as it's likely safe (lines 1-1220) | |
| with open('backend/main.py', 'r', encoding='utf-8', errors='replace') as f: | |
| lines = f.readlines() | |
| return lines[:1220] | |
| def get_correct_fetchers(): | |
| return [ | |
| "def _get_source_priority(symbol: str) -> List[str]:\n", | |
| " cfg = SYMBOLS[symbol]\n", | |
| " priority = CATEGORY_SOURCE_PRIORITY.get(cfg.category, DEFAULT_SOURCE_PRIORITY)\n", | |
| " return [s for s in priority if s in cfg.mappings]\n", | |
| "\n", | |
| "\n", | |
| "async def fetch_historical(\n", | |
| " symbol: str, interval: str, limit: int\n", | |
| ") -> Tuple[List[Dict[str, Any]], str]:\n", | |
| " prefix = _cache_prefix(symbol, interval)\n", | |
| " key = f'hist_{prefix}'\n", | |
| " cached = historical_cache.get(key)\n", | |
| " if cached is not None:\n", | |
| " return cached[-limit:], 'cache'\n", | |
| " priority = _get_source_priority(symbol)\n", | |
| " errors: List[str] = []\n", | |
| " fetch_limit = max(limit, 1000)\n", | |
| " for source in priority:\n", | |
| " try:\n", | |
| " if source == 'binance': data = await fetch_binance(symbol, interval, fetch_limit)\n", | |
| " elif source == 'bybit': data = await fetch_bybit(symbol, interval, fetch_limit)\n", | |
| " elif source == 'coingecko': data = await fetch_coingecko(symbol, interval, fetch_limit)\n", | |
| " elif source == 'twelvedata': data = await fetch_twelvedata(symbol, interval, fetch_limit)\n", | |
| " elif source == 'finnhub': data = await fetch_finnhub(symbol, interval, fetch_limit)\n", | |
| " elif source == 'yfinance': data = await fetch_yfinance(symbol, interval, fetch_limit)\n", | |
| " else: continue\n", | |
| " if len(data) >= 20:\n", | |
| " historical_cache.set(key, data, ttl_seconds=interval_ttl(interval))\n", | |
| " return data[-limit:], source\n", | |
| " except Exception as ex: errors.append(f'{source}: {ex}')\n", | |
| " raise HTTPException(status_code=502, detail={'message': 'All sources failed', 'errors': errors})\n" | |
| ] | |
| # Indicators part (Vectorized) | |
| def get_vectorized_indicators(): | |
| return [ | |
| "def _ema(arr: np.ndarray, period: int) -> np.ndarray:\n", | |
| " if len(arr) == 0: return np.array([], dtype=float)\n", | |
| " return pd.Series(arr).ewm(alpha=2.0/(period+1), adjust=False).mean().values\n", | |
| "\n", | |
| "def _rsi(close: np.ndarray, period: int = 14) -> np.ndarray:\n", | |
| " delta = np.diff(close)\n", | |
| " gain = np.where(delta > 0, delta, 0.0)\n", | |
| " loss = np.where(delta < 0, -delta, 0.0)\n", | |
| " avg_gain = pd.Series(gain).ewm(alpha=1.0/period, adjust=False).mean()\n", | |
| " avg_loss = pd.Series(loss).ewm(alpha=1.0/period, adjust=False).mean()\n", | |
| " rs = avg_gain / avg_loss.replace(0, np.inf)\n", | |
| " rsi = 100 - (100 / (1 + rs))\n", | |
| " return np.concatenate([[np.nan], rsi.values])\n", | |
| "\n", | |
| "def _bollinger(close: np.ndarray, period=20, k=2.0):\n", | |
| " s = pd.Series(close)\n", | |
| " mid = s.rolling(window=period).mean()\n", | |
| " std = s.rolling(window=period).std()\n", | |
| " return (mid + k*std).values, mid.values, (mid - k*std).values\n", | |
| "\n", | |
| "def _macd(close, fast=12, slow=26, signal=9):\n", | |
| " f, s = _ema(close, fast), _ema(close, slow)\n", | |
| " line = f - s\n", | |
| " sig = _ema(np.where(np.isnan(line), 0, line), signal)\n", | |
| " return line, sig, line - sig\n", | |
| "\n", | |
| "def _atr(high, low, close, period=14):\n", | |
| " tr = np.maximum(high[1:]-low[1:], np.maximum(np.abs(high[1:]-close[:-1]), np.abs(low[1:]-close[:-1])))\n", | |
| " tr = np.concatenate([[np.nan], tr])\n", | |
| " return pd.Series(tr).ewm(alpha=1.0/period, adjust=False).mean().values\n", | |
| "\n", | |
| "def _stoch_rsi(close, rsi_p=14, stoch_p=14, k_p=3, d_p=3):\n", | |
| " rsi = pd.Series(_rsi(close, rsi_p))\n", | |
| " mn, mx = rsi.rolling(stoch_p).min(), rsi.rolling(stoch_p).max()\n", | |
| " k = 100 * (rsi - mn) / (mx - mn).replace(0, np.inf)\n", | |
| " ks = k.rolling(k_p).mean()\n", | |
| " return ks.values, ks.rolling(d_p).mean().values\n", | |
| "\n", | |
| "def _sma(arr, p): return pd.Series(arr).rolling(p).mean().values if len(arr) else arr\n", | |
| "\n", | |
| "def _cci(h, l, c, p=20):\n", | |
| " tp = (h+l+c)/3.0; s = pd.Series(tp)\n", | |
| " sma = s.rolling(p).mean()\n", | |
| " mad = s.rolling(p).apply(lambda x: np.abs(x-x.mean()).mean(), raw=False)\n", | |
| " return (s - sma) / (0.015 * mad.replace(0, np.inf))\n", | |
| "\n", | |
| "def _adx(h, l, c, p=14):\n", | |
| " up = h[1:]-h[:-1]; dn = l[:-1]-l[1:]\n", | |
| " p_dm = np.concatenate([[0], np.where((up>dn)&(up>0), up, 0)])\n", | |
| " m_dm = np.concatenate([[0], np.where((dn>up)&(dn>0), dn, 0)])\n", | |
| " tr = _atr(h, l, c, p) # simplified TR for vectorization\n", | |
| " tr_s = pd.Series(tr).rolling(p).sum().replace(0, np.inf)\n", | |
| " p_di = 100 * pd.Series(p_dm).rolling(p).sum() / tr_s\n", | |
| " m_di = 100 * pd.Series(m_dm).rolling(p).sum() / tr_s\n", | |
| " dx = 100 * np.abs(p_di - m_di) / (p_di + m_di).replace(0, np.inf)\n", | |
| " return dx.rolling(p).mean().values, p_di.values, m_di.values\n", | |
| "\n", | |
| "def _awesome_oscillator(h, l): return _sma((h+l)/2, 5) - _sma((h+l)/2, 34)\n", | |
| "def _momentum(c, p): return np.concatenate([np.full(p, np.nan), c[p:] - c[:-p]])\n", | |
| "def _williams_r(h, l, c, p=14):\n", | |
| " hh, ll = pd.Series(h).rolling(p).max(), pd.Series(l).rolling(p).min()\n", | |
| " return -100 * (hh - c) / (hh - ll).replace(0, np.inf)\n", | |
| "def _bull_bear_power(h, l, c, p=13): ema = _ema(c, p); return (h - ema) + (l - ema)\n", | |
| "def _ultimate_oscillator(h, l, c, p1=7, p2=14, p3=28):\n", | |
| " cp = pd.Series(c).shift(1); tr = np.maximum(h, cp) - np.minimum(l, cp); bp = pd.Series(c) - np.minimum(l, cp)\n", | |
| " a1, a2, a3 = bp.rolling(p1).sum()/tr.rolling(p1).sum().replace(0,np.inf), bp.rolling(p2).sum()/tr.rolling(p2).sum().replace(0,np.inf), bp.rolling(p3).sum()/tr.rolling(p3).sum().replace(0,np.inf)\n", | |
| " return 100 * (4*a1 + 2*a2 + a3) / 7.0\n", | |
| "def _vwma(c, v, p=20): return (pd.Series(c*v).rolling(p).sum() / pd.Series(v).rolling(p).sum().replace(0, np.inf)).values\n", | |
| "def _hull_ma(c, p=9):\n", | |
| " h, s = max(p//2, 1), int(p**0.5)\n", | |
| " d = 2*_sma(c, h) - _sma(c, p)\n", | |
| " return _sma(np.where(np.isnan(d), c, d), s)\n" | |
| ] | |
| # Add analytical engine back | |
| # (Omitted here for brevity in script creation, will insert in actual write) | |
| # ... Reconstruct and write ... | |
| print("Recovery logic ready (truncated here for brevity)") | |