feat: 5-coin fleet (DOGE/SOL/ETH/XRP/BTC), enriched context (multi-TF trend, orderbook depth, BTC corr, WR history, regime), memory system (learned patterns), self-adapting overrides, fleet dashboard with per-coin RSI/mom

This commit is contained in:
drjones
2026-08-02 19:25:58 -07:00
parent a4def4f72e
commit 8e860361ec
14 changed files with 153 additions and 6 deletions

View File

@@ -201,7 +201,7 @@ h1{font-size:1rem;letter-spacing:3px}.dim{color:#0a5f2e}
<div class="fleet" id="cards"></div>
<div id="statusbar"></div>
<script>
const C={DOGE:"#c2a633",SOL:"#9945FF",ETH:"#627EEA"};
const C={DOGE:"#c2a633",SOL:"#9945FF",ETH:"#627EEA",XRP:"#00AAE4",BTC:"#f7931a"};
function fmt(c){return c<0?`<span class="dn">-${Math.abs(c)}¢</span>`:c>0?`<span class="up">+${c}¢</span>`:`<span class="skip">${c}¢</span>`}
function ago(ts){const d=Date.now()/1000-ts;return d<60?Math.floor(d)+'s':d<3600?Math.floor(d/60)+'m':Math.floor(d/3600)+'h'}
async function load(){
@@ -335,7 +335,7 @@ def toggle_dry():
@app.route("/api/fleet")
def fleet_api():
"""All active coins in one call — reads each coin's own DB."""
COINS = {"🐶DOGE": "#c2a633", "🔮SOL": "#9945FF", "💎ETH": "#627EEA"}
COINS = {"🐶DOGE": "#c2a633", "🔮SOL": "#9945FF", "💎ETH": "#627EEA", "🌊XRP": "#00AAE4", "₿BTC": "#f7931a"}
result = {}
for label, color in COINS.items():
coin = label[1:] # strip leading emoji
@@ -350,16 +350,34 @@ def fleet_api():
now = time.time()
ticks = [r[0] for r in conn.execute("SELECT price FROM ticks WHERE ts > ? ORDER BY ts", (now-1800,)).fetchall()]
last_price = ticks[-1] if ticks else None
# enriched per-coin data
# enriched per-coin data — compute RSI + momentum directly (no cross-import)
decs = [dict(r) for r in conn.execute("SELECT * FROM decisions ORDER BY id DESC LIMIT 3")]
ords = [dict(r) for r in conn.execute("SELECT * FROM orders ORDER BY id DESC LIMIT 5")]
live_bets = conn.execute("SELECT COUNT(*) FROM orders WHERE status IN ('placed','posted') AND dry=0").fetchone()[0]
total_bets = conn.execute("SELECT COUNT(*) FROM orders WHERE dry=0").fetchone()[0]
pnl = conn.execute("SELECT COALESCE(SUM(pnl_cents),0) FROM orders WHERE dry=0").fetchone()[0]
won = conn.execute("SELECT COUNT(*) FROM orders WHERE status='won' AND dry=0").fetchone()[0]
import sys; sys.path.insert(0, str(HOME))
from bot import rsi as _rsi, momentum as _mom
c_rsi = _rsi(conn); c_mom, c_score = _mom(conn)
# RSI
rows14 = conn.execute("SELECT price FROM ticks WHERE ts > ? ORDER BY ts DESC LIMIT 15", (now-900,)).fetchall()
c_rsi = None
if len(rows14) >= 15:
px = [r[0] for r in rows14]
gains = [max(0, b-a) for a, b in zip(px[:-1], px[1:])]
losses = [max(0, a-b) for a, b in zip(px[:-1], px[1:])]
ag = sum(gains)/14 if gains else 0; al = sum(losses)/14 if losses else 1e-9
c_rsi = 100 - 100/(1 + ag/al) if al else (100 if ag > 0 else 50)
# Momentum
rows_t = conn.execute("SELECT ts, price FROM ticks WHERE ts > ? ORDER BY ts", (now-1800,)).fetchall()
c_mom, c_score = "FLAT", 0.0
if len(rows_t) >= 4:
now_p = rows_t[-1][1]
ref5 = min(rows_t, key=lambda r: abs(r[0]-(now-300)))[1]
ref15 = min(rows_t, key=lambda r: abs(r[0]-(now-900)))[1]
r5 = (now_p-ref5)/ref5*100 if ref5 else 0; r15 = (now_p-ref15)/ref15*100 if ref15 else 0
sc = r5*0.6 + r15*0.4
if sc > 0.008: c_mom, c_score = "UP", abs(sc)
elif sc < -0.008: c_mom, c_score = "DOWN", abs(sc)
else: c_mom, c_score = "FLAT", abs(sc)
chg24 = c.get("chg24_cache", 0)
result[coin] = {"label": label, "color": color, "series": c["series"],
"price": last_price, "mode": c["mode"],