feat: save factors to signal_indicators + show FR/Liq on signals page
- DB: added factors JSONB column to signal_indicators - Backend: save_indicator now includes factors JSON - API: /api/signals/latest returns factors field - Frontend: signals page shows FR and 清算 score bars
This commit is contained in:
parent
a571a221e5
commit
01b1992643
@ -427,7 +427,7 @@ async def get_signal_latest(user: dict = Depends(get_current_user)):
|
|||||||
for sym in SYMBOLS:
|
for sym in SYMBOLS:
|
||||||
row = await async_fetchrow(
|
row = await async_fetchrow(
|
||||||
"SELECT ts, cvd_fast, cvd_mid, cvd_day, cvd_fast_slope, atr_5m, atr_percentile, "
|
"SELECT ts, cvd_fast, cvd_mid, cvd_day, cvd_fast_slope, atr_5m, atr_percentile, "
|
||||||
"vwap_30m, price, p95_qty, p99_qty, score, signal "
|
"vwap_30m, price, p95_qty, p99_qty, score, signal, factors "
|
||||||
"FROM signal_indicators WHERE symbol = $1 ORDER BY ts DESC LIMIT 1",
|
"FROM signal_indicators WHERE symbol = $1 ORDER BY ts DESC LIMIT 1",
|
||||||
sym
|
sym
|
||||||
)
|
)
|
||||||
|
|||||||
@ -638,13 +638,15 @@ def fetch_new_trades(symbol: str, last_id: int) -> list:
|
|||||||
def save_indicator(ts: int, symbol: str, result: dict):
|
def save_indicator(ts: int, symbol: str, result: dict):
|
||||||
with get_sync_conn() as conn:
|
with get_sync_conn() as conn:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
|
import json as _json3
|
||||||
|
factors_json = _json3.dumps(result.get("factors")) if result.get("factors") else None
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"INSERT INTO signal_indicators "
|
"INSERT INTO signal_indicators "
|
||||||
"(ts,symbol,cvd_fast,cvd_mid,cvd_day,cvd_fast_slope,atr_5m,atr_percentile,vwap_30m,price,p95_qty,p99_qty,score,signal) "
|
"(ts,symbol,cvd_fast,cvd_mid,cvd_day,cvd_fast_slope,atr_5m,atr_percentile,vwap_30m,price,p95_qty,p99_qty,score,signal,factors) "
|
||||||
"VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
|
"VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
|
||||||
(ts, symbol, result["cvd_fast"], result["cvd_mid"], result["cvd_day"], result["cvd_fast_slope"],
|
(ts, symbol, result["cvd_fast"], result["cvd_mid"], result["cvd_day"], result["cvd_fast_slope"],
|
||||||
result["atr"], result["atr_pct"], result["vwap"], result["price"],
|
result["atr"], result["atr_pct"], result["vwap"], result["price"],
|
||||||
result["p95"], result["p99"], result["score"], result.get("signal"))
|
result["p95"], result["p99"], result["score"], result.get("signal"), factors_json)
|
||||||
)
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,8 @@ interface LatestIndicator {
|
|||||||
environment?: { score?: number };
|
environment?: { score?: number };
|
||||||
confirmation?: { score?: number };
|
confirmation?: { score?: number };
|
||||||
auxiliary?: { score?: number };
|
auxiliary?: { score?: number };
|
||||||
|
funding_rate?: { score?: number; value?: number };
|
||||||
|
liquidation?: { score?: number; long_usd?: number; short_usd?: number };
|
||||||
} | null;
|
} | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,6 +432,8 @@ function IndicatorCards({ symbol }: { symbol: Symbol }) {
|
|||||||
<LayerScore label="环境" score={data.factors?.environment?.score ?? Math.min(Math.round(data.score * 0.15), 15)} max={15} colorClass="bg-emerald-600" />
|
<LayerScore label="环境" score={data.factors?.environment?.score ?? Math.min(Math.round(data.score * 0.15), 15)} max={15} colorClass="bg-emerald-600" />
|
||||||
<LayerScore label="确认" score={data.factors?.confirmation?.score ?? Math.min(Math.round(data.score * 0.15), 15)} max={15} colorClass="bg-amber-500" />
|
<LayerScore label="确认" score={data.factors?.confirmation?.score ?? Math.min(Math.round(data.score * 0.15), 15)} max={15} colorClass="bg-amber-500" />
|
||||||
<LayerScore label="辅助" score={data.factors?.auxiliary?.score ?? Math.min(Math.round(data.score * 0.05), 5)} max={5} colorClass="bg-slate-500" />
|
<LayerScore label="辅助" score={data.factors?.auxiliary?.score ?? Math.min(Math.round(data.score * 0.05), 5)} max={5} colorClass="bg-slate-500" />
|
||||||
|
<LayerScore label="FR" score={data.factors?.funding_rate?.score ?? 0} max={5} colorClass="bg-cyan-600" />
|
||||||
|
<LayerScore label="清算" score={data.factors?.liquidation?.score ?? 0} max={5} colorClass="bg-orange-500" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -40,3 +40,37 @@
|
|||||||
2026-03-01 23:34:08,664 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=87 price=83.5
|
2026-03-01 23:34:08,664 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=87 price=83.5
|
||||||
2026-03-01 23:34:08,664 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=87 price=83.5
|
2026-03-01 23:34:08,664 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=87 price=83.5
|
||||||
2026-03-01 23:34:08,686 [INFO] signal-engine: [SOLUSDT] 📝 模拟开仓: LONG @ 83.54 score=87 tier=heavy strategy=v52_8signals TP1=84.10 TP2=84.80 SL=82.70
|
2026-03-01 23:34:08,686 [INFO] signal-engine: [SOLUSDT] 📝 模拟开仓: LONG @ 83.54 score=87 tier=heavy strategy=v52_8signals TP1=84.10 TP2=84.80 SL=82.70
|
||||||
|
2026-03-01 23:35:46,904 [INFO] signal-engine: 已加载策略配置: v51_baseline, v52_8signals
|
||||||
|
2026-03-01 23:35:50,048 [INFO] signal-engine: [BTCUSDT] 冷启动完成: 加载459,950条历史数据 (窗口=4h)
|
||||||
|
2026-03-01 23:35:53,307 [INFO] signal-engine: [ETHUSDT] 冷启动完成: 加载486,670条历史数据 (窗口=4h)
|
||||||
|
2026-03-01 23:35:53,760 [INFO] signal-engine: [XRPUSDT] 冷启动完成: 加载64,640条历史数据 (窗口=4h)
|
||||||
|
2026-03-01 23:35:54,229 [INFO] signal-engine: [SOLUSDT] 冷启动完成: 加载71,505条历史数据 (窗口=4h)
|
||||||
|
2026-03-01 23:35:54,229 [INFO] signal-engine: === Signal Engine (PG) 启动完成 ===
|
||||||
|
2026-03-01 23:35:54,463 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v51_baseline]: LONG score=95 price=65794.8
|
||||||
|
2026-03-01 23:35:54,464 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v52_8signals]: LONG score=95 price=65794.8
|
||||||
|
2026-03-01 23:35:54,823 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v51_baseline]: SHORT score=92 price=1.4
|
||||||
|
2026-03-01 23:35:54,823 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v52_8signals]: SHORT score=92 price=1.4
|
||||||
|
2026-03-01 23:35:54,901 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=92 price=83.6
|
||||||
|
2026-03-01 23:35:54,901 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=92 price=83.6
|
||||||
|
2026-03-01 23:36:26,291 [INFO] signal-engine: 冷启动保护期结束,模拟盘开仓已启用
|
||||||
|
2026-03-01 23:45:20,597 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v51_baseline]: SHORT score=85 price=1937.2
|
||||||
|
2026-03-01 23:45:20,598 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v52_8signals]: SHORT score=90 price=1937.2
|
||||||
|
2026-03-01 23:45:20,621 [INFO] signal-engine: [ETHUSDT] 📝 模拟开仓: SHORT @ 1937.23 score=90 tier=heavy strategy=v52_8signals TP1=1923.04 TP2=1905.29 SL=1958.53
|
||||||
|
2026-03-01 23:46:07,484 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v51_baseline]: LONG score=85 price=65708.5
|
||||||
|
2026-03-01 23:46:07,484 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v52_8signals]: LONG score=85 price=65708.5
|
||||||
|
2026-03-01 23:46:07,850 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v51_baseline]: SHORT score=82 price=1.3
|
||||||
|
2026-03-01 23:46:07,850 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v52_8signals]: SHORT score=82 price=1.3
|
||||||
|
2026-03-01 23:46:07,939 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=87 price=83.5
|
||||||
|
2026-03-01 23:46:07,939 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=87 price=83.5
|
||||||
|
2026-03-01 23:51:22,298 [INFO] signal-engine: [BTCUSDT] 状态: CVD_fast=417.5 CVD_mid=3139.9 ATR=262.21 (11%) VWAP=65702.8
|
||||||
|
2026-03-01 23:51:22,298 [INFO] signal-engine: [ETHUSDT] 状态: CVD_fast=-892.3 CVD_mid=-33690.7 ATR=8.38 (11%) VWAP=1937.7
|
||||||
|
2026-03-01 23:51:22,298 [INFO] signal-engine: [XRPUSDT] 状态: CVD_fast=-517373.6 CVD_mid=-3295080.7 ATR=0.01 (11%) VWAP=1.4
|
||||||
|
2026-03-01 23:51:22,298 [INFO] signal-engine: [SOLUSDT] 状态: CVD_fast=829.6 CVD_mid=204333.9 ATR=0.39 (11%) VWAP=83.6
|
||||||
|
2026-03-01 23:55:33,622 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v51_baseline]: SHORT score=80 price=1937.9
|
||||||
|
2026-03-01 23:55:33,622 [INFO] signal-engine: [ETHUSDT] 🚨 信号[v52_8signals]: SHORT score=80 price=1937.9
|
||||||
|
2026-03-01 23:56:20,475 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v51_baseline]: LONG score=85 price=65700.6
|
||||||
|
2026-03-01 23:56:20,475 [INFO] signal-engine: [BTCUSDT] 🚨 信号[v52_8signals]: LONG score=85 price=65700.6
|
||||||
|
2026-03-01 23:56:20,867 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v51_baseline]: SHORT score=82 price=1.4
|
||||||
|
2026-03-01 23:56:20,867 [INFO] signal-engine: [XRPUSDT] 🚨 信号[v52_8signals]: SHORT score=82 price=1.4
|
||||||
|
2026-03-01 23:56:20,955 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v51_baseline]: LONG score=87 price=83.6
|
||||||
|
2026-03-01 23:56:20,955 [INFO] signal-engine: [SOLUSDT] 🚨 信号[v52_8signals]: LONG score=87 price=83.6
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user