Download fly_trader/ui/api/data.py from bryceweiner/fly-trader: direct link, hf CLI and curl.
- Browser
- Download file 6.15 kB
-
https://huggingface.co/bryceweiner/fly-trader/resolve/main/fly_trader/ui/api/data.py
- Command line
-
hf download hf://bryceweiner/fly-trader/fly_trader/ui/api/data.py
-
curl -L -o data.py https://huggingface.co/bryceweiner/fly-trader/resolve/main/fly_trader/ui/api/data.py
6.15 kB
| """Data pipelines: is each source current, and how far along are the historical builds — the Solana market feed, the | |
| pumpapi.io history archive, the training feature parts, token metadata and the Jupiter token stats. One topic, as the | |
| Streamlit page was one fragment: every panel refreshes together every 10 s — except the Jupiter coverage count (about 11 s on | |
| the live database), which has its own minute-long topic so it never holds the rest back. The feature parts are cached for a minute.""" | |
| from __future__ import annotations | |
| import glob | |
| import threading | |
| from collections import deque | |
| from datetime import datetime, timezone | |
| from ... import config | |
| from ...db.queries import q, q1 | |
| from .. import runtime | |
| from ..cache import ttl_cache | |
| from ..hub import topic | |
| from ..state import STALE_FEED_S, setting | |
| FEED_MINUTES = 180 # the market feed chart: trades and tokens per minute over the last three hours | |
| ARCHIVE_DAYS = 90 # the history archive chart: graduations per assembled day | |
| _eps: deque = deque(maxlen=120) # (status time, events/s) samples the feed reported, newest last: the Events / s sparkline | |
| _eps_lock = threading.Lock() | |
| def state_badge(alive: bool, ok: bool = True, optional: bool = False) -> dict: | |
| """running (green) / stale (orange: the worker is up but its output is old) / stopped (red; gray for an optional worker).""" | |
| return {"text": "running" if alive and ok else "stale" if alive else "stopped", | |
| "color": "green" if alive and ok else "orange" if alive else "gray" if optional else "red"} | |
| def _eps_history(at, eps: float) -> list[float]: | |
| """The feed overwrites its status row every few seconds; keep the samples this console has seen (one per status update).""" | |
| with _eps_lock: | |
| if at is not None and (not _eps or _eps[-1][0] != at): | |
| _eps.append((at, eps)) | |
| return [v for _, v in _eps] | |
| def feature_parts() -> dict: | |
| """The built feature days (one parquet part per day) and how many carry the live feature engine's current version: | |
| reading every part's schema is slow, so a minute's staleness is fine.""" | |
| from ...market.features import FEATURE_VERSION | |
| from ...train.mature import part_version | |
| files = sorted(glob.glob(str(config.CORPUS_DIR / "features_mature" / "*" / "part.parquet"))) | |
| days = [f.split("/")[-2] for f in files] | |
| return {"n": len(files), "first": days[0] if days else None, "last": days[-1] if days else None, | |
| "current": sum(1 for f in files if part_version(f) == FEATURE_VERSION)} | |
| def token_stats_coverage() -> dict: | |
| """Tokens the selector could trade in the last hour (pool above its gate) and how many have Jupiter stats from the | |
| last hour, plus when the stats history starts.""" | |
| from ...train.decisions import MIN_RESQ_SOL | |
| c = q1("""SELECT count(*) AS universe, count(*) FILTER (WHERE EXISTS (SELECT 1 FROM token_stats s WHERE s.mint = u.mint AND s.ts > now() - interval '1 hour')) AS covered | |
| FROM (SELECT DISTINCT mint FROM pump_minutes WHERE ts > now() - interval '1 hour' AND resq_sol >= %s) u""", (MIN_RESQ_SOL,)) or {} | |
| first = q1("SELECT min(ts) AS first FROM token_stats") or {} | |
| return {"universe": int(c.get("universe") or 0), "covered": int(c.get("covered") or 0), "first": first.get("first")} | |
| def pipelines(params: dict) -> dict: | |
| ws = runtime.sup().status(); now = datetime.now(timezone.utc) | |
| alive = lambda n: bool(ws.get(n, {}).get("alive")) # noqa: E731 | |
| ps, ps_at = setting("pumpstream_status"); rs, rs_at = setting("replay_status") | |
| ft = ps.get("flushed_through") | |
| age = (now - datetime.fromisoformat(ft)).total_seconds() - 60 if ft else None # since the newest complete minute closed | |
| done, total = int(rs.get("hours_done") or 0), int(rs.get("hours_total") or 0) | |
| days = q1("SELECT count(*) AS n, max(day) AS last FROM replay_days") or {} | |
| m = q1("SELECT count(*) AS n, count(creator) AS creators, count(own_dd60) AS outcomes FROM corpus_meta") or {} | |
| cr = q1("SELECT count(*) AS n FROM pump_events WHERE action = 'create'") or {} | |
| eps = float(ps.get("events_per_s") or 0) | |
| per_min = q("SELECT ts, sum(n_buys + n_sells) AS trades, count(*) AS tokens FROM pump_minutes WHERE ts > now() - make_interval(mins => %s) GROUP BY ts ORDER BY ts", | |
| (FEED_MINUTES,)) | |
| per_day = q("SELECT day, graduations, tokens_written FROM (SELECT * FROM replay_days ORDER BY day DESC LIMIT %s) d ORDER BY day", (ARCHIVE_DAYS,)) | |
| return { | |
| "feed": {"badge": state_badge(alive("pumpstream"), age is not None and age < STALE_FEED_S), "events_per_s": eps, "eps_spark": _eps_history(ps_at, eps), | |
| "age": age, "migrates": int(ps.get("migrates") or 0), "reconnects": int(ps.get("reconnects") or 0), | |
| "dropped_band": int(ps.get("dropped_band") or 0), "dropped_late": int(ps.get("dropped_late") or 0), "updated_at": ps_at, | |
| "per_minute": [[r["ts"], int(r["trades"] or 0), int(r["tokens"] or 0)] for r in per_min]}, | |
| "archive": {"badge": state_badge(alive("replay")), "hours_done": done, "hours_total": total, "progress": min(1.0, done / total) if total else None, | |
| "days": int(days.get("n") or 0), "newest_day": days.get("last"), "errors": int(rs.get("errors") or 0), | |
| "replay_start": config.REPLAY_START, "last_hour": str(rs.get("last_hour") or "—")[:13], | |
| "eta_h": float(rs["eta_h"]) if rs.get("eta_h") else None, "updated_at": rs_at, | |
| "per_day": [[r["day"], int(r["graduations"] or 0), int(r["tokens_written"] or 0)] for r in per_day]}, | |
| "features": feature_parts(), | |
| "meta": {"graduations": int(m.get("n") or 0), "creators": int(m.get("creators") or 0), "launches": int(cr.get("n") or 0)}, | |
| "stats": {"badge": state_badge(alive("discover"), optional=True)}, | |
| } | |
| def token_stats(params: dict) -> dict: | |
| """The Jupiter stats coverage on its own (a slow count, cached for a minute).""" | |
| return token_stats_coverage() | |