Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets

This commit is contained in:
Kolp
2026-09-24 13:22:23 +07:00
commit 642cc11a9f
18968 changed files with 5683248 additions and 0 deletions
+96
View File
@@ -0,0 +1,96 @@
"""
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}%")