e5a586f903
Move business code under modules/, env template to config/, PM2 single qihuo process, and _legacy shims for old imports. Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
# Copyright (c) 2025-2026 马建军. All rights reserved.
|
|
# 专有软件 — 未经授权禁止复制、传播、转售。
|
|
# 严禁用于:带单/代客理财、向他人推荐期货品种或买卖建议、融资配资等业务。
|
|
# 详见 LICENSE.zh-CN.txt 与 docs/软件购买与使用协议.md
|
|
|
|
"""CTP tick 聚合 K 线(1 分钟为基础,再合成各周期)。"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
from modules.market.kline_chart import (
|
|
PERIOD_MINUTES,
|
|
_aggregate_bars,
|
|
_bar_datetime,
|
|
_merge_bars,
|
|
_timeshare_session,
|
|
_weekly_from_daily,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
PERIOD_AGG = {
|
|
"2m": 2,
|
|
"3m": 3,
|
|
"5m": 5,
|
|
"15m": 15,
|
|
"30m": 30,
|
|
"1h": 60,
|
|
"2h": 120,
|
|
"4h": 240,
|
|
}
|
|
|
|
|
|
def _daily_from_1m(bars_1m: list) -> list:
|
|
if not bars_1m:
|
|
return []
|
|
buckets: dict[str, list] = {}
|
|
for bar in bars_1m:
|
|
dt = _bar_datetime(bar)
|
|
if not dt:
|
|
continue
|
|
key = dt.strftime("%Y-%m-%d")
|
|
buckets.setdefault(key, []).append(bar)
|
|
out = []
|
|
for day in sorted(buckets.keys()):
|
|
chunk = buckets[day]
|
|
merged = _merge_bars(chunk)
|
|
merged["d"] = day + " 15:00:00"
|
|
out.append(merged)
|
|
return out
|
|
|
|
|
|
def compose_period_bars(bars_1m: list, period: str) -> list:
|
|
p = (period or "15m").lower()
|
|
if p == "timeshare":
|
|
return _timeshare_session(bars_1m)
|
|
if p in ("1d", "d"):
|
|
return _daily_from_1m(bars_1m)
|
|
if p == "w":
|
|
return _weekly_from_daily(_daily_from_1m(bars_1m))
|
|
if p == "1m":
|
|
return list(bars_1m)
|
|
n = PERIOD_AGG.get(p)
|
|
if n:
|
|
return _aggregate_bars(bars_1m, n)
|
|
if p in PERIOD_MINUTES:
|
|
try:
|
|
n = int(PERIOD_MINUTES[p])
|
|
return _aggregate_bars(bars_1m, n)
|
|
except (TypeError, ValueError):
|
|
pass
|
|
return list(bars_1m)
|
|
|
|
|
|
def fetch_ctp_klines(symbol: str, period: str, mode: str) -> Optional[list]:
|
|
"""CTP 已连接时由 tick 聚合 K 线;失败返回 None。"""
|
|
try:
|
|
from modules.ctp.vnpy_bridge import ctp_status, get_bridge
|
|
|
|
if not ctp_status(mode).get("connected"):
|
|
return None
|
|
bars_1m = get_bridge().get_kline_bars_1m(symbol, mode=mode)
|
|
if not bars_1m:
|
|
return None
|
|
return compose_period_bars(bars_1m, period)
|
|
except Exception as exc:
|
|
logger.debug("fetch_ctp_klines %s %s: %s", symbol, period, exc)
|
|
return None
|