Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""Analyze price deviation from SMA(24) on 1h candles — to calibrate lock threshold."""
|
||||
import sys
|
||||
sys.path.insert(0, '/root/grid-bot')
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
# Fetch 7 days of 1h candles
|
||||
dt_to = datetime.now(tz=timezone.utc)
|
||||
dt_from = dt_to - timedelta(days=7)
|
||||
raw = api.get_hloc_sync(
|
||||
SYMBOL, 60,
|
||||
dt_from.strftime("%d.%m.%Y %H:%M"),
|
||||
dt_to.strftime("%d.%m.%Y %H:%M"),
|
||||
0,
|
||||
)
|
||||
hloc = raw.get("hloc", {}).get(SYMBOL, [])
|
||||
ts_lst = raw.get("xSeries", {}).get(SYMBOL, [])
|
||||
|
||||
candles = [
|
||||
{"t": int(ts_lst[i]), "c": float(h[3])}
|
||||
for i, h in enumerate(hloc[:len(ts_lst)])
|
||||
]
|
||||
closes = [c["c"] for c in candles]
|
||||
print(f"Got {len(closes)} hourly closes: {closes[0]:.0f} → {closes[-1]:.0f}\n")
|
||||
|
||||
# Compute rolling SMA(24) and deviation in %
|
||||
sma_p = 24
|
||||
devs = [] # (timestamp, price, sma, dev_pct, atr_1h)
|
||||
atr_p = 14
|
||||
|
||||
# ATR first
|
||||
atr_candles = [{"h": float(h[1]), "l": float(h[2]), "c": float(h[3])} for h in hloc[:len(ts_lst)]]
|
||||
trs = []
|
||||
for i in range(1, len(atr_candles)):
|
||||
h, l, pc = atr_candles[i]["h"], atr_candles[i]["l"], atr_candles[i-1]["c"]
|
||||
tr = max(h-l, abs(h-pc), abs(l-pc))
|
||||
trs.append(tr)
|
||||
atr_14 = sum(trs[-atr_p:]) / atr_p if len(trs) >= atr_p else None
|
||||
atr_dollar = atr_14
|
||||
print(f"ATR(14) on 1h = ${atr_dollar:.2f}\n")
|
||||
|
||||
for i in range(sma_p, len(closes)):
|
||||
sma = sum(closes[i-sma_p:i]) / sma_p
|
||||
price = closes[i]
|
||||
ts = candles[i]["t"]
|
||||
dev_pct = (price - sma) / sma * 100
|
||||
devs.append((ts, price, sma, dev_pct))
|
||||
|
||||
print(f"{'Time (UTC)':<22} {'Price':>10} {'SMA(24)':>10} {'Dev%':>7} {'Dev$':>8} ATR-based")
|
||||
print("-" * 75)
|
||||
for ts, price, sma, dev_pct in devs[-48:]: # last 48h
|
||||
dt = datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%d %H:%M")
|
||||
dev_dollar = price - sma
|
||||
dev_atr = abs(dev_dollar) / atr_dollar if atr_dollar else 0
|
||||
lock_1p5 = "🔒" if abs(dev_pct) > 1.5 else " "
|
||||
lock_2p0 = "🔒" if abs(dev_pct) > 2.0 else " "
|
||||
lock_3p0 = "🔒" if abs(dev_pct) > 3.0 else " "
|
||||
print(f"{dt:<22} {price:>10,.0f} {sma:>10,.0f} {dev_pct:>+6.2f}% {dev_dollar:>+8,.0f} "
|
||||
f"@1.5%{lock_1p5} @2.0%{lock_2p0} @3.0%{lock_3p0}")
|
||||
|
||||
print("\n=== Deviation distribution ===")
|
||||
pcts = [d[3] for d in devs]
|
||||
abs_pcts = [abs(p) for p in pcts]
|
||||
import statistics
|
||||
print(f" Mean abs dev: {statistics.mean(abs_pcts):.2f}%")
|
||||
print(f" Median abs dev: {statistics.median(abs_pcts):.2f}%")
|
||||
print(f" Max abs dev: {max(abs_pcts):.2f}%")
|
||||
print(f" % time |dev| < 1%: {sum(1 for p in abs_pcts if p < 1.0)/len(abs_pcts)*100:.1f}%")
|
||||
print(f" % time |dev| < 2%: {sum(1 for p in abs_pcts if p < 2.0)/len(abs_pcts)*100:.1f}%")
|
||||
print(f" % time |dev| < 3%: {sum(1 for p in abs_pcts if p < 3.0)/len(abs_pcts)*100:.1f}%")
|
||||
print(f" % time |dev| > 3%: {sum(1 for p in abs_pcts if p > 3.0)/len(abs_pcts)*100:.1f}%")
|
||||
Reference in New Issue
Block a user