Files
trade/engine/common/models.py
T
Rekey edc50e8809 feat: 新增2h/6h时间框架支持,策略重构为增量指标计算
- 数据层: build_aggregates_sql 新增 2h/6h 聚合视图,默认起始时间调整为 2017-05
- 模型层: KlineInterval 类型扩展 2h/6h,DataService 新增对应表名和毫秒映射
- 指标层: 新增 incremental.py 增量指标模块 (EmaInc/AtrInc/RsiInc/BbInc),O(1) per bar
- 策略重构: long_short.py 和 regime_all.py 从批量 ema/atr 迁移至增量指标,避免每 bar 重复全量计算
- regime 探测器: RegimeDetector3 改为增量 EMA200,detect() 接口简化
- 回测扩展: regime_timeframe_comparison 从 4h/1d 扩展至 2h/4h/6h/1d
- 新增示例: multi_strategy_report, vol_break_compare/periods, intraday_explore, top3_trades 等分析脚本
2026-06-13 19:30:25 +08:00

179 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
数据模型定义 — 与 TS data/types/base.ts 对齐的 Pydantic 模型
Ticker / Trade / OrderBook / Kline 是系统中流通的核心行情数据结构,
字段语义与 Binance/OKX/Bybit 通用概念对齐,时间戳统一使用 Unix 毫秒。
"""
from typing import Literal
from pydantic import BaseModel, Field, field_validator
# ============================================================
# K 线周期类型
# ============================================================
KlineInterval = Literal["1m", "5m", "15m", "30m", "1h", "2h", "4h", "6h", "1d", "1w"]
# ============================================================
# 行情数据模型
# ============================================================
class Ticker(BaseModel):
"""24 小时滚动行情统计
每笔成交触发推送,包含最近 24 小时的 OHLC、成交量、买卖盘口等统计信息。
"""
exchange: str
"""交易所标识(如 binance"""
symbol: str
"""交易对符号(大写,如 BTCUSDT"""
# 24h 价格统计
last_price: float = Field(alias="lastPrice")
"""最新成交价"""
open_price: float = Field(alias="openPrice")
"""24h 开盘价"""
high_price: float = Field(alias="highPrice")
"""24h 最高价"""
low_price: float = Field(alias="lowPrice")
"""24h 最低价"""
# 24h 成交量统计
volume: float
"""24h 成交量(base 币种)"""
quote_volume: float = Field(alias="quoteVolume")
"""24h 成交额(quote 币种)"""
# 价格变化
price_change: float = Field(alias="priceChange")
"""24h 价格变化"""
price_change_percent: float = Field(alias="priceChangePercent")
"""24h 价格变化百分比(0.05 = 5%"""
# 最优买卖盘口
bid_price: float = Field(alias="bidPrice")
"""买一价"""
bid_qty: float = Field(alias="bidQty")
"""买一量"""
ask_price: float = Field(alias="askPrice")
"""卖一价"""
ask_qty: float = Field(alias="askQty")
"""卖一量"""
# 时间戳
event_time: float = Field(alias="eventTime")
"""事件发生时间(Unix 毫秒)"""
close_time: float = Field(alias="closeTime")
"""交易所收盘时间(Unix 毫秒,用于判断 K 线是否闭合)"""
class Trade(BaseModel):
"""逐笔成交记录"""
exchange: str
"""交易所标识"""
symbol: str
"""交易对符号"""
price: float
"""成交价"""
amount: float
"""成交数量(base 币种)"""
quote_amount: float = Field(alias="quoteAmount")
"""成交额(quote 币种 = price × amount"""
timestamp: float
"""成交时间(Unix 毫秒)"""
is_buyer_maker: bool = Field(alias="isBuyerMaker")
"""买方是否为挂单方(true = 主动卖出 / taker sell"""
trade_id: str = Field(alias="tradeId")
"""交易所成交 ID"""
class OrderBook(BaseModel):
"""订单簿深度快照"""
exchange: str
"""交易所标识"""
symbol: str
"""交易对符号"""
bids: list[tuple[float, float]]
"""买单列表 [[price, qty], ...],按价格降序(买一在前)"""
asks: list[tuple[float, float]]
"""卖单列表 [[price, qty], ...],按价格升序(卖一在前)"""
last_update_id: int = Field(alias="lastUpdateId")
"""上次更新 ID"""
event_time: float = Field(alias="eventTime")
"""事件发生时间(Unix 毫秒)"""
class Kline(BaseModel):
"""标准化 K 线(OHLCV
K 线是最主要的行情输入,策略通过 on_kline() 接收此数据。
open/high/low/close/volume 字段在 TS 侧为字符串以保持精度,
模型在初始化时自动转换为 float。
"""
exchange: str
"""交易所标识"""
symbol: str
"""交易对符号"""
interval: KlineInterval
"""K 线周期"""
# 时间
open_time: float = Field(alias="openTime")
"""开盘时间(Unix 毫秒)"""
close_time: float = Field(alias="closeTime")
"""收盘时间(Unix 毫秒)"""
# OHLCV
open: float
"""开盘价"""
high: float
"""最高价"""
low: float
"""最低价"""
close: float
"""收盘价"""
volume: float
"""成交量(base 币种)"""
# 扩展字段
quote_volume: float = Field(default=0.0, alias="quoteVolume")
"""成交额(quote 币种)"""
taker_buy_base_vol: float = Field(default=0.0, alias="takerBuyBaseVol")
"""主动买入成交量(base 币种)"""
taker_buy_quote_vol: float = Field(default=0.0, alias="takerBuyQuoteVol")
"""主动买入成交额(quote 币种)"""
trade_count: int = Field(default=0, alias="tradeCount")
"""成交笔数"""
is_closed: bool = Field(alias="isClosed")
"""该 K 线是否已关闭(不再更新)"""
# ── 字段校验:处理 TS 侧字符串 → float 转换 ──
@field_validator(
"open", "high", "low", "close", "volume",
"quote_volume", "taker_buy_base_vol", "taker_buy_quote_vol",
mode="before",
)
@classmethod
def _coerce_float(cls, v: object) -> float:
"""将字符串类型数值转为 float,兼容 TS 侧 MessagePack 序列化格式"""
if isinstance(v, str):
return float(v)
return float(v)
@field_validator("trade_count", mode="before")
@classmethod
def _coerce_int(cls, v: object) -> int:
"""将字符串类型数值转为 int"""
if isinstance(v, str):
return int(v)
return int(v)