Files
qlib/backend/app/domain/entities/chart.py
T
Simon 995ed08548 feat(chart): M9-1 Chart DTO + Chart Service + Chart API(v3 §20)
- domain/entities/chart.py:ChartResult/OHLC/Volume/Series/EventMarker/ChartMetadata
  (adjust_mode + execution_price_basis 口径元数据)+ SelectionHit
- application/services/chart_service.py:个股 K线/量/MA 指标;显示层 qfq/hfq 折算
  (基于主口径 none 行情 × adjust_factor,绝回写研究数据);回测个股视图把实际成交
  转 fills 标记并在显示口径不同时做坐标换算(v3 §20.3/§20.5)
- by-symbol 历史查询:SignalRepository/SelectionRepository.list_by_symbol(含溯源 id)
- api/charts.py:/stocks/{symbol}/chart|signals|selections、/backtests/{id}/stocks/{symbol}/chart
  |trades|positions
- tests/test_charts.py(指标/qfq-hfq 折算断言/回测 fills/API 集成+404);全量 pytest 通过
2026-09-09 07:09:52 +08:00

89 lines
2.9 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.
"""统一量化可视化 DTO(v3 §20 Chart Service)。
原则:前端只展示本结构,不得自行重算选股/信号/成交(v3 §20.1)。
价格口径:bars 已按请求 adjust 折算(显示层);成交/信号标记与 K 线同坐标系;
metadata 记录 adjust_mode 与回测执行价 basis,杜绝图表与回测口径混用(v3 §20.5)。
"""
from __future__ import annotations
from datetime import date
from pydantic import BaseModel, Field
class OHLC(BaseModel):
time: date
open: float | None = None
high: float | None = None
low: float | None = None
close: float | None = None
class VolumePoint(BaseModel):
time: date
value: float | None = None
class SeriesPoint(BaseModel):
"""指标/分数等 (时间, 值) 序列点。"""
time: date
value: float | None = None
class EventMarker(BaseModel):
"""K 线上可点击的事件标记(选股/信号/实际成交)。"""
time: date
kind: str = Field(
description="selection | signal_buy | signal_sell | signal_watch | fill_buy | fill_sell"
)
symbol: str = ""
price: float | None = None
score: float | None = None
text: list[str] = Field(default_factory=list, description="原因/说明(tooltip)")
ref_id: str | None = Field(default=None, description="关联 selection/signal 记录 id")
class ChartMetadata(BaseModel):
symbol: str
name: str = ""
adjust_mode: str = Field(default="none", description="显示口径:none | qfq | hfq")
price_basis: str = Field(default="chart_display", description="显示价基准(显示层折算)")
execution_price_basis: str | None = Field(
default=None, description="回测执行价口径(如 none),与显示口径不同时用于解释"
)
start: date | None = None
end: date | None = None
bar_count: int = 0
indicator_windows: list[int] = Field(default_factory=list)
class ChartResult(BaseModel):
"""单只股票 / 回测个股的统一图表数据(v3 §20.2)。"""
metadata: ChartMetadata
bars: list[OHLC] = Field(default_factory=list)
volume: list[VolumePoint] = Field(default_factory=list)
indicators: dict[str, list[SeriesPoint]] = Field(default_factory=dict)
selections: list[EventMarker] = Field(default_factory=list)
signals: list[EventMarker] = Field(default_factory=list)
fills: list[EventMarker] = Field(default_factory=list)
holding_periods: list[dict] = Field(default_factory=list)
factor_values: dict[str, list[SeriesPoint]] = Field(default_factory=dict)
strategy_scores: dict[str, list[SeriesPoint]] = Field(default_factory=dict)
unimplemented: list[str] = Field(default_factory=list)
class SelectionHit(BaseModel):
"""个股在选股历史中的命中(by-symbol 查询)。"""
selection_id: str
as_of: date
method: str
symbol: str
rank: int
score: float
selection_reason: list[str] = Field(default_factory=list)