feat: 行情K线优先CTP tick聚合,修复手续费同步主力列表解析

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-24 13:18:43 +08:00
parent 09f4649d79
commit 3fe4add8e1
8 changed files with 390 additions and 24 deletions
+49 -6
View File
@@ -428,13 +428,30 @@ def build_market_quote_payload(
if codes:
market_code = codes.get("market_code", "") or market_code
sina_code = codes.get("sina_code", "") or sina_code
price = fetch_price(symbol, market_code, sina_code)
quote_source = "sina"
price = None
prev_close = None
try:
from vnpy_bridge import ctp_status, ctp_get_tick_detail
from trading_context import get_trading_mode
mode = get_trading_mode(get_setting)
if ctp_status(mode).get("connected"):
detail = ctp_get_tick_detail(mode, symbol)
if detail.get("price"):
price = detail["price"]
quote_source = "ctp"
if detail.get("pre_close") is not None:
prev_close = detail["pre_close"]
except Exception:
pass
if price is None:
price = fetch_price(symbol, market_code, sina_code)
name = symbol
codes = ths_to_codes(symbol)
if codes:
name = codes.get("name", symbol)
prev_close = None
if sina_code:
if prev_close is None and sina_code:
from market import fetch_raw_for_volume
raw = fetch_raw_for_volume(sina_code)
if raw and raw.get("prev_close") is not None:
@@ -444,6 +461,7 @@ def build_market_quote_payload(
"name": name,
"price": price,
"prev_close": prev_close,
"quote_source": quote_source,
}
@@ -643,9 +661,15 @@ def background_task():
def start_background_threads():
from trading_context import get_trading_mode
threading.Thread(target=background_task, daemon=True).start()
threading.Thread(
target=lambda: kline_hub.worker_loop(DB_PATH, build_market_quote_payload),
target=lambda: kline_hub.worker_loop(
DB_PATH,
build_market_quote_payload,
get_mode_fn=lambda: get_trading_mode(get_setting),
),
daemon=True,
).start()
threading.Thread(target=refresh_main_index, daemon=True).start()
@@ -1397,11 +1421,21 @@ def market_page():
valid = {p["key"] for p in MARKET_PERIODS}
if period not in valid:
period = "15m"
ctp_st = {}
try:
from vnpy_bridge import ctp_status
from trading_context import get_trading_mode
ctp_st = ctp_status(get_trading_mode(get_setting))
except Exception:
pass
return render_template(
"market.html",
symbol=symbol,
period=period,
market_periods=MARKET_PERIODS,
quote_label=get_quote_source_label(ctp_connected=bool(ctp_st.get("connected"))),
ctp_connected=bool(ctp_st.get("connected")),
)
@@ -1413,7 +1447,11 @@ def api_kline():
if not symbol:
return jsonify({"error": "请提供合约代码"}), 400
try:
data = fetch_market_klines(symbol, period, DB_PATH)
from trading_context import get_trading_mode
data = fetch_market_klines(
symbol, period, DB_PATH, trading_mode=get_trading_mode(get_setting),
)
except Exception as exc:
app.logger.warning("kline api failed: %s", exc)
return jsonify({"error": str(exc)}), 500
@@ -1437,9 +1475,14 @@ def api_kline_stream():
return jsonify({"error": "请提供合约代码"}), 400
def generate():
from trading_context import get_trading_mode
mode = get_trading_mode(get_setting)
sub = kline_hub.subscribe(symbol, period, market_code, sina_code)
try:
kline_data = fetch_market_klines(symbol, period, DB_PATH)
kline_data = fetch_market_klines(
symbol, period, DB_PATH, trading_mode=mode,
)
if kline_data.get("bars"):
yield sse_format("kline", kline_data)
yield sse_format(