""" Live test for indicators.py. Fetches 5-min candles from Tradernet (via /root/grid-bot/api.py TradernetAPI), runs compute_sma_atr(), prints results. """ import sys import time sys.path.insert(0, '/root/grid-bot') from indicators import compute_sma, compute_atr, compute_sma_atr from api import TradernetAPI from config import ( TRADERNET_PUBLIC_KEY, TRADERNET_PRIVATE_KEY, SYMBOL, TRADERNET_BASE_URL, TRADERNET_LOGIN, TRADERNET_PASSWORD, ) api = TradernetAPI( public_key=TRADERNET_PUBLIC_KEY, private_key=TRADERNET_PRIVATE_KEY, login=TRADERNET_LOGIN, password=TRADERNET_PASSWORD, base_url=TRADERNET_BASE_URL, ) # Fetch 5-min candles for last 7 days from datetime import datetime, timedelta, timezone dt_to = datetime.now(tz=timezone.utc) dt_from = dt_to - timedelta(days=2) # 2 days = 576 candles (5-min) — plenty for SMA(20)+ATR(14) date_from = dt_from.strftime("%d.%m.%Y %H:%M") date_to = dt_to.strftime("%d.%m.%Y %H:%M") print(f"Fetching {SYMBOL} 5-min candles {date_from} → {date_to}...") t0 = time.time() raw = api.get_hloc_sync(SYMBOL, 5, date_from, date_to, 0) print(f" done in {time.time()-t0:.2f}s") if not raw: print("ERROR: getHloc returned empty. Check API keys/network.") sys.exit(1) # Same normaliser as main.py:fetch_candles hloc_list = raw.get("hloc", {}).get(SYMBOL, []) ts_list = raw.get("xSeries", {}).get(SYMBOL, []) vol_list = raw.get("vl", {}).get(SYMBOL, []) candles = [] for i, ohlc in enumerate(hloc_list): if not isinstance(ohlc, (list, tuple)) or len(ohlc) < 4: continue t = ts_list[i] if i < len(ts_list) else 0 v = vol_list[i] if i < len(vol_list) else 0 candles.append({ "t": int(t), "o": float(ohlc[0]), "h": float(ohlc[1]), "l": float(ohlc[2]), "c": float(ohlc[3]), "v": float(v) if v is not None else 0.0, }) print(f"Got {len(candles)} candles") if not candles: sys.exit(1) print(f"First: {datetime.fromtimestamp(candles[0]['t'], tz=timezone.utc).isoformat()} " f"c=${candles[0]['c']:,.2f}") print(f"Last: {datetime.fromtimestamp(candles[-1]['t'], tz=timezone.utc).isoformat()} " f"c=${candles[-1]['c']:,.2f}") # Compute indicators at multiple timeframes for sma_p, atr_p in [(20, 14), (50, 14), (20, 20)]: res = compute_sma_atr(candles, sma_period=sma_p, atr_period=atr_p) print(f"\nSMA({sma_p}) / ATR({atr_p}):") print(f" sma = ${res['sma']:,.2f}") print(f" atr = ${res['atr']:,.2f}") print(f" range_h = ${res['range_h']:,.2f}") print(f" range_l = ${res['range_l']:,.2f}") if res['sma'] is not None and res['last_close'] is not None: dev_pct = (res['last_close'] - res['sma']) / res['sma'] * 100 in_range = res['range_l'] <= res['last_close'] <= res['range_h'] print(f" last_close deviation from SMA = {dev_pct:+.2f}%") print(f" last_close IN range = {in_range}") if res['atr'] is not None and res['atr'] > 0: dev_atr = abs(res['last_close'] - res['sma']) / res['atr'] print(f" |last_close - SMA| / ATR = {dev_atr:.2f}× ATR") print(f" → Would LOCK at {1.5}× ATR? {dev_atr > 1.5}") # Decision: which params to use print("\n=== Recommended for grid-bot ===") res = compute_sma_atr(candles, sma_period=20, atr_period=14) print(f" SMA(20) = ${res['sma']:,.2f}") print(f" ATR(14) = ${res['atr']:,.2f}") print(f" Grid range = ${res['range_l']:,.2f} — ${res['range_h']:,.2f}") print(f" Step per level (1 ATR) = ${res['atr']:,.2f}") print(f" Step % = {res['atr']/res['sma']*100:.3f}%")