Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""Test SMA/ATR at multiple timeframes."""
|
||||
import sys
|
||||
sys.path.insert(0, '/root/grid-bot')
|
||||
|
||||
from indicators import compute_sma_atr
|
||||
from api import TradernetAPI
|
||||
from config import (
|
||||
TRADERNET_PUBLIC_KEY, TRADERNET_PRIVATE_KEY, SYMBOL,
|
||||
TRADERNET_BASE_URL, TRADERNET_LOGIN, TRADERNET_PASSWORD,
|
||||
)
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
api = TradernetAPI(
|
||||
TRADERNET_PUBLIC_KEY, TRADERNET_PRIVATE_KEY,
|
||||
TRADERNET_LOGIN, TRADERNET_PASSWORD, TRADERNET_BASE_URL,
|
||||
)
|
||||
|
||||
configs = [
|
||||
# (tf_min, sma_p, atr_p, mult, label)
|
||||
(5, 20, 14, 2.0, "5m SMA20"),
|
||||
(15, 12, 14, 2.0, "15m SMA12"),
|
||||
(60, 24, 14, 2.0, "1h SMA24"),
|
||||
(60, 48, 14, 2.0, "1h SMA48"),
|
||||
(240, 14, 14, 2.0, "4h SMA14"),
|
||||
]
|
||||
|
||||
now_str = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
||||
print(f"BTC-USDT.IMEX timeframe analysis @ {now_str}\n")
|
||||
|
||||
rows = []
|
||||
for tf, sma_p, atr_p, mult, label in configs:
|
||||
days = 7 if tf <= 60 else 30
|
||||
dt_to = datetime.now(tz=timezone.utc)
|
||||
dt_from = dt_to - timedelta(days=days)
|
||||
raw = api.get_hloc_sync(
|
||||
SYMBOL, tf,
|
||||
dt_from.strftime("%d.%m.%Y %H:%M"),
|
||||
dt_to.strftime("%d.%m.%Y %H:%M"),
|
||||
0,
|
||||
)
|
||||
hloc = raw.get("hloc", {}).get(SYMBOL, [])
|
||||
ts_list = raw.get("xSeries", {}).get(SYMBOL, [])
|
||||
candles = [
|
||||
{"o": float(h[0]), "h": float(h[1]), "l": float(h[2]), "c": float(h[3])}
|
||||
for i, h in enumerate(hloc[:len(ts_list)])
|
||||
]
|
||||
min_needed = atr_p + 1
|
||||
if len(candles) < min_needed:
|
||||
print(f"[{label}] only {len(candles)} candles (need {min_needed}) — SKIP")
|
||||
continue
|
||||
|
||||
res = compute_sma_atr(candles, sma_period=sma_p, atr_period=atr_p, width_atr_mult=mult)
|
||||
if res["sma"] is None:
|
||||
print(f"[{label}] insufficient data — SKIP")
|
||||
continue
|
||||
|
||||
lock_thr = 1.5 * res["atr"]
|
||||
dev = abs(res["last_close"] - res["sma"])
|
||||
dev_atr = dev / res["atr"] if res["atr"] else 0
|
||||
step_dlr = res["sma"] * 0.005 # current 0.5% step
|
||||
step_atr = step_dlr / res["atr"] if res["atr"] else 0
|
||||
range_d = mult * 2 * res["atr"] # ±mult*ATR total
|
||||
levels = range_d / step_dlr if step_dlr else 0
|
||||
would_lock = dev_atr > 1.5
|
||||
|
||||
print(f"[{label}] SMA=${res['sma']:,.0f} ATR=${res['atr']:,.0f} last=${res['last_close']:,.0f}")
|
||||
print(f" |dev|={dev:.0f} ({dev_atr:.1f}×ATR) lock_thr={lock_thr:.0f} range=±{range_d/2:.0f}$")
|
||||
print(f" step(0.5%)=${step_dlr:.0f} = {step_atr:.0f}×ATR levels_in_range={levels:.1f}")
|
||||
print(f" → LOCK {'⚠️ YES ⚠️' if would_lock else 'no'}")
|
||||
print()
|
||||
rows.append((label, res, dev_atr, would_lock, levels, step_atr, lock_thr))
|
||||
|
||||
print("=== RECOMMENDATION ===")
|
||||
print("Want: dev < 1.5×ATR (stable, no false lock) + levels >= 2 (grid has room)\n")
|
||||
for label, res, dev_atr, would_lock, levels, step_atr, lock_thr in rows:
|
||||
ok = not would_lock and levels >= 2
|
||||
mark = "✅" if ok else "⚠️ "
|
||||
lock = "🔒" if would_lock else " "
|
||||
print(f"{mark}{lock} [{label}] dev={dev_atr:.1f}× levels={levels:.1f} step={step_atr:.0f}×ATR lock_thr=${lock_thr:.0f}")
|
||||
Reference in New Issue
Block a user