fix: signal_engine now reads real market_indicators (JSONB parsing + OI change rate)
This commit is contained in:
parent
271658c725
commit
317031ab57
@ -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
|
|
||||||
elif oi_change >= 0.03:
|
|
||||||
environment_score = 15
|
|
||||||
elif oi_change > 0:
|
|
||||||
environment_score = 10
|
environment_score = 10
|
||||||
|
oi_change = 0.0
|
||||||
else:
|
else:
|
||||||
environment_score = 5
|
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
|
||||||
|
elif oi_change > 0:
|
||||||
|
environment_score = 10
|
||||||
|
else:
|
||||||
|
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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user