fix: K线新浪历史补齐与手续费页布局及CTP批量同步
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+41
-8
@@ -17,6 +17,9 @@ from kline_store import ensure_kline_tables, get_cached_entry, save_bars
|
||||
logger = logging.getLogger(__name__)
|
||||
TZ = ZoneInfo("Asia/Shanghai")
|
||||
|
||||
# CTP tick 聚合 bar 少于此数时,用新浪历史补齐走势
|
||||
MIN_CTP_KLINE_BARS = 15
|
||||
|
||||
PERIOD_MINUTES = {
|
||||
"1m": "1",
|
||||
"3m": "3",
|
||||
@@ -165,6 +168,24 @@ def _merge_bars(chunk: list) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _merge_kline_bars(history: list, live: list) -> list:
|
||||
"""新浪历史 + CTP 实时尾部(去重叠)。"""
|
||||
if not history:
|
||||
return list(live or [])
|
||||
if not live:
|
||||
return list(history)
|
||||
first_live = _bar_datetime(live[0])
|
||||
if not first_live:
|
||||
return history + live
|
||||
trimmed = []
|
||||
for bar in history:
|
||||
dt = _bar_datetime(bar)
|
||||
if dt and dt < first_live:
|
||||
trimmed.append(bar)
|
||||
merged = trimmed + list(live)
|
||||
return merged if merged else list(history)
|
||||
|
||||
|
||||
def _weekly_from_daily(daily: list) -> list:
|
||||
if not daily:
|
||||
return []
|
||||
@@ -236,6 +257,7 @@ def fetch_market_klines(
|
||||
source = "remote"
|
||||
cached_at = None
|
||||
ctp_connected = False
|
||||
ctp_bars: list = []
|
||||
|
||||
if prefer_ctp:
|
||||
try:
|
||||
@@ -253,14 +275,21 @@ def fetch_market_klines(
|
||||
mode = "simulation"
|
||||
ctp_connected = bool(ctp_status(mode).get("connected"))
|
||||
if ctp_connected:
|
||||
ctp_bars = fetch_ctp_klines(symbol, p, mode)
|
||||
if ctp_bars:
|
||||
bars = ctp_bars
|
||||
source = "ctp"
|
||||
ctp_bars = fetch_ctp_klines(symbol, p, mode) or []
|
||||
except Exception as exc:
|
||||
logger.debug("ctp kline fetch failed %s %s: %s", symbol, p, exc)
|
||||
|
||||
if not bars and db_path and chart_sym and not force_remote:
|
||||
need_sina = (
|
||||
force_remote
|
||||
or not ctp_bars
|
||||
or len(ctp_bars) < MIN_CTP_KLINE_BARS
|
||||
)
|
||||
|
||||
if ctp_bars and len(ctp_bars) >= MIN_CTP_KLINE_BARS:
|
||||
bars = ctp_bars
|
||||
source = "ctp"
|
||||
|
||||
if not bars and db_path and chart_sym and not force_remote and need_sina:
|
||||
try:
|
||||
conn = connect_db(db_path)
|
||||
cached = get_cached_entry(conn, chart_sym, p)
|
||||
@@ -272,11 +301,15 @@ def fetch_market_klines(
|
||||
except Exception as exc:
|
||||
logger.warning("kline cache read failed %s %s: %s", chart_sym, p, exc)
|
||||
|
||||
if force_remote or not bars:
|
||||
if not bars or len(ctp_bars) < MIN_CTP_KLINE_BARS:
|
||||
remote_bars = fetch_sina_klines(symbol, p)
|
||||
if remote_bars:
|
||||
bars = remote_bars
|
||||
source = "remote"
|
||||
if ctp_bars and ctp_connected:
|
||||
bars = _merge_kline_bars(remote_bars, ctp_bars)
|
||||
source = "ctp+remote"
|
||||
else:
|
||||
bars = remote_bars
|
||||
source = "remote"
|
||||
if db_path and chart_sym and not ctp_connected:
|
||||
try:
|
||||
conn = connect_db(db_path)
|
||||
|
||||
Reference in New Issue
Block a user