fix: signal_engine now reads real market_indicators (JSONB parsing + OI change rate)

This commit is contained in:
root 2026-02-28 11:03:44 +00:00
parent 271658c725
commit 317031ab57

View File

@ -52,7 +52,8 @@ COOLDOWN_MS = 10 * 60 * 1000
def fetch_market_indicators(symbol: str) -> dict: def fetch_market_indicators(symbol: str) -> dict:
"""从PG读取最新的market_indicators数据""" """从PG读取最新的market_indicators数据解析JSONB提取关键数值"""
import json as _json
with get_sync_conn() as conn: with get_sync_conn() as conn:
with conn.cursor() as cur: with conn.cursor() as cur:
indicators = {} indicators = {}
@ -62,7 +63,26 @@ def fetch_market_indicators(symbol: str) -> dict:
(symbol, ind_type), (symbol, ind_type),
) )
row = cur.fetchone() row = cur.fetchone()
indicators[ind_type] = row[0] if row else None if not row or row[0] is None:
indicators[ind_type] = None
continue
# value可能是JSON字符串或已解析的dict
val = row[0]
if isinstance(val, str):
try:
val = _json.loads(val)
except Exception:
indicators[ind_type] = None
continue
# 提取关键数值
if ind_type == "long_short_ratio":
indicators[ind_type] = float(val.get("longShortRatio", 1.0))
elif ind_type == "top_trader_position":
indicators[ind_type] = float(val.get("longAccount", 0.5))
elif ind_type == "open_interest_hist":
indicators[ind_type] = float(val.get("sumOpenInterestValue", 0))
elif ind_type == "coinbase_premium":
indicators[ind_type] = float(val.get("premium_pct", 0))
return indicators return indicators
@ -177,6 +197,7 @@ class SymbolState:
self.warmup = True self.warmup = True
self.prev_cvd_fast = 0.0 self.prev_cvd_fast = 0.0
self.prev_cvd_fast_slope = 0.0 self.prev_cvd_fast_slope = 0.0
self.prev_oi_value = 0.0
self.market_indicators = fetch_market_indicators(symbol) self.market_indicators = fetch_market_indicators(symbol)
self.last_signal_ts = 0 self.last_signal_ts = 0
self.last_signal_dir = "" self.last_signal_dir = ""
@ -306,16 +327,21 @@ class SymbolState:
top_trader_score = 5 top_trader_score = 5
crowding_score = ls_score + top_trader_score crowding_score = ls_score + top_trader_score
# 3) 环境层15分 # 3) 环境层15分— OI变化率
oi_change = to_float(self.market_indicators.get("open_interest_hist")) oi_value = to_float(self.market_indicators.get("open_interest_hist"))
if oi_change is None: if oi_value is None or self.prev_oi_value == 0:
environment_score = 10 environment_score = 10
elif oi_change >= 0.03: oi_change = 0.0
else:
oi_change = (oi_value - self.prev_oi_value) / self.prev_oi_value if self.prev_oi_value > 0 else 0
if oi_change >= 0.03:
environment_score = 15 environment_score = 15
elif oi_change > 0: elif oi_change > 0:
environment_score = 10 environment_score = 10
else: else:
environment_score = 5 environment_score = 5
if oi_value is not None and oi_value > 0:
self.prev_oi_value = oi_value
# 4) 确认层15分 # 4) 确认层15分
confirmation_score = 15 if ((direction == "LONG" and cvd_fast > 0 and cvd_mid > 0) or (direction == "SHORT" and cvd_fast < 0 and cvd_mid < 0)) else 0 confirmation_score = 15 if ((direction == "LONG" and cvd_fast > 0 and cvd_mid > 0) or (direction == "SHORT" and cvd_fast < 0 and cvd_mid < 0)) else 0