Upload app.py
Browse files
app.py
CHANGED
|
@@ -14,12 +14,20 @@ RECEIVER_URL = os.getenv("RECEIVER_URL", "").rstrip("/")
|
|
| 14 |
MOVE, OFFSET, HORIZONS = .0008, .0004, (5, 15, 30)
|
| 15 |
MODELS = None
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
def get_candles():
|
| 18 |
"""Incrementally backfill Delta candles from the newest stored timestamp."""
|
| 19 |
now = int(time.time())
|
| 20 |
old = pd.read_parquet(LIVE_DATA) if LIVE_DATA.exists() else pd.DataFrame()
|
|
|
|
|
|
|
| 21 |
if len(old):
|
| 22 |
-
start =
|
| 23 |
else:
|
| 24 |
base = pd.read_parquet(DATA, columns=["timestamp"])
|
| 25 |
start = int(pd.to_datetime(base.timestamp, utc=True).astype("int64").max() // 10**9) + 60
|
|
@@ -31,10 +39,11 @@ def get_candles():
|
|
| 31 |
batch=r.json().get("result", [])
|
| 32 |
if not batch: break
|
| 33 |
rows.extend(batch)
|
| 34 |
-
latest=max(
|
| 35 |
if latest < start: break
|
| 36 |
start=max(end, latest+60)
|
| 37 |
fresh=pd.DataFrame(rows).rename(columns={"time":"epoch"})
|
|
|
|
| 38 |
live=pd.concat([old,fresh],ignore_index=True) if len(old) or len(fresh) else pd.DataFrame()
|
| 39 |
if len(live):
|
| 40 |
live=live.drop_duplicates("epoch",keep="last").sort_values("epoch").reset_index(drop=True)
|
|
@@ -89,7 +98,7 @@ def tick():
|
|
| 89 |
for si in range(2):
|
| 90 |
for hi,horizon in enumerate(HORIZONS): probs[si,hi]=MODELS[si,horizon].predict_proba(x[i:i+1])[0,1]
|
| 91 |
score=3/(1/(probs+1e-6)).sum(axis=1); si=int(np.argmax(score)); side="LONG" if si==0 else "SHORT"
|
| 92 |
-
row=d.iloc[i]; event={"event":"tick","symbol":SYMBOL,"candle":{"time":datetime.fromtimestamp(
|
| 93 |
if np.isfinite(x[i]).all(): event["signal"]={"side":side,"price":float(row.close),"score":float(score[si]),"offset":OFFSET,"target":MOVE}
|
| 94 |
event["data_last_updated"] = event["candle"]["time"]
|
| 95 |
event["live_cache_rows"] = int(len(live))
|
|
|
|
| 14 |
MOVE, OFFSET, HORIZONS = .0008, .0004, (5, 15, 30)
|
| 15 |
MODELS = None
|
| 16 |
|
| 17 |
+
def epoch_seconds(value):
|
| 18 |
+
value = float(value)
|
| 19 |
+
if value > 1e14: return int(value / 1e6)
|
| 20 |
+
if value > 1e11: return int(value / 1e3)
|
| 21 |
+
return int(value)
|
| 22 |
+
|
| 23 |
def get_candles():
|
| 24 |
"""Incrementally backfill Delta candles from the newest stored timestamp."""
|
| 25 |
now = int(time.time())
|
| 26 |
old = pd.read_parquet(LIVE_DATA) if LIVE_DATA.exists() else pd.DataFrame()
|
| 27 |
+
if len(old) and epoch_seconds(old.epoch.max()) < 1577836800:
|
| 28 |
+
old = pd.DataFrame()
|
| 29 |
if len(old):
|
| 30 |
+
start = epoch_seconds(old.epoch.max()) + 60
|
| 31 |
else:
|
| 32 |
base = pd.read_parquet(DATA, columns=["timestamp"])
|
| 33 |
start = int(pd.to_datetime(base.timestamp, utc=True).astype("int64").max() // 10**9) + 60
|
|
|
|
| 39 |
batch=r.json().get("result", [])
|
| 40 |
if not batch: break
|
| 41 |
rows.extend(batch)
|
| 42 |
+
latest=max(epoch_seconds(q["time"]) for q in batch)
|
| 43 |
if latest < start: break
|
| 44 |
start=max(end, latest+60)
|
| 45 |
fresh=pd.DataFrame(rows).rename(columns={"time":"epoch"})
|
| 46 |
+
if len(fresh): fresh["epoch"] = fresh["epoch"].map(epoch_seconds)
|
| 47 |
live=pd.concat([old,fresh],ignore_index=True) if len(old) or len(fresh) else pd.DataFrame()
|
| 48 |
if len(live):
|
| 49 |
live=live.drop_duplicates("epoch",keep="last").sort_values("epoch").reset_index(drop=True)
|
|
|
|
| 98 |
for si in range(2):
|
| 99 |
for hi,horizon in enumerate(HORIZONS): probs[si,hi]=MODELS[si,horizon].predict_proba(x[i:i+1])[0,1]
|
| 100 |
score=3/(1/(probs+1e-6)).sum(axis=1); si=int(np.argmax(score)); side="LONG" if si==0 else "SHORT"
|
| 101 |
+
row=d.iloc[i]; candle_epoch=epoch_seconds(row.epoch); event={"event":"tick","symbol":SYMBOL,"candle":{"time":datetime.fromtimestamp(candle_epoch,timezone.utc).isoformat(),"epoch":candle_epoch,"open":float(row.open),"high":float(row.high),"low":float(row.low),"close":float(row.close)},"signal":None,"probs":probs.tolist(),"score":float(score[si]),"source":"exact-hybrid-multihorizon"}
|
| 102 |
if np.isfinite(x[i]).all(): event["signal"]={"side":side,"price":float(row.close),"score":float(score[si]),"offset":OFFSET,"target":MOVE}
|
| 103 |
event["data_last_updated"] = event["candle"]["time"]
|
| 104 |
event["live_cache_rows"] = int(len(live))
|