Skip to content

快速开始

创建本地环境

uv venv
uv pip install --python .venv -e .[dev,docs]

运行测试

uv run --python .venv\Scripts\python.exe pytest tests

运行 CLI

uv run --python .venv\Scripts\python.exe python -m zelqor.cli --help

运行最小回测请求

可以先准备一个 request.json

{
  "schemaVersion": 2,
  "marketData": {
    "type": "clickhouse",
    "source": {
      "mode": "config_file",
      "configPath": "config.toml"
    }
  },
  "strategy": {
    "type": "python_file",
    "path": "examples/loadable_selector_strategy.py",
    "kind": "selector"
  },
  "metadata": {
    "requestId": "bt_quickstart_001",
    "caller": "quickstart"
  },
  "dateRange": {
    "startDate": "2025-03-24",
    "endDate": "2025-03-28"
  },
  "capital": {
    "initialCash": 100000
  },
  "runtime": {
    "output": {
      "includeDailyPools": true,
      "includeDailyDecisions": true,
      "includeTrades": true,
      "includePositionsByDate": true,
      "includeEquityCurve": true
    }
  },
  "params": {
    "limit": 2
  }
}

然后执行:

uv run --python .venv\Scripts\python.exe python -m zelqor.cli run-backtest --request-file request.json

如果你只想看轻量结果,可以改成:

uv run --python .venv\Scripts\python.exe python -m zelqor.cli run-backtest --request-file request.json --summary-only

如果你想把结果直接写到文件,可以改成:

uv run --python .venv\Scripts\python.exe python -m zelqor.cli run-backtest --request-file request.json --output-file result.json

如果你想直接拿统一任务 envelope,可以改成:

uv run --python .venv\Scripts\python.exe python -m zelqor.cli run-backtest --request-file request.json --task-envelope

仓库里也已经放好了两个可直接参考的请求模板:

  • examples/request_loadable_selector.json
  • examples/request_loadable_stateful_step.json

现在这条命令会真实执行:

  • 加载 ClickHouse provider
  • 加载 examples/loadable_selector_strategy.py
  • 按交易日运行 selector
  • 输出真实 BacktestResult

如果你想改成 stateful step 示例,可以把 strategy.path 改成:

  • examples/loadable_stateful_step_strategy.py

如果你想走模块路径加载,可以把 strategy 改成:

{
  "type": "python_module",
  "path": "zelqor.strategy.examples.loadable_selector_module",
  "kind": "selector"
}

当前 schema 已经统一为 strategy 字段。

marketData 现在也支持更正式的配置来源写法:

  • marketData.source.mode == "config_file"
  • marketData.source.mode == "env"

另外,宿主现在可以通过 runtime.output 控制结果保留项。

CLI 返回的 BacktestResult 现在也会稳定包含:

  • metadata
  • runtime.outputApplied
  • runtime.omittedSections

另外,直接调用:

  • run_selector_backtest(...)
  • run_stateful_step_backtest(...)

返回的 BacktestResult 现在也会保留传入的宿主 metadata

这几个 direct API 现在同样支持传入 runtime,用法和 request 模式下的 runtime.output 保持一致。

如果你在 Python 宿主里更希望得到“成功结果或错误结果”的统一返回值,而不是自己包装异常,可以使用:

  • run_backtest_safe(...)

如果你想进一步拿到固定 envelope 形状:

  • ok
  • requestId
  • result
  • error

可以使用:

  • run_backtest_task(...)

如果请求里带了 metadata.requestId,CLI 在校验失败或运行失败时也会尽量把这个 requestId 带回错误 JSON。

CLI 的失败输出现在也是结构化结果,至少包含:

  • ok
  • code
  • message
  • stage
  • requestId
  • details

CLI 的成功输出现在支持:

  • 默认完整 BacktestResult
  • --summary-only
  • --output-file
  • --task-envelope

如果你之前已经写过旧请求文件,需要同步改名:

  • selector -> strategy
  • selectorType -> strategyType
  • marketData.configPath/useEnv -> marketData.source

运行最小回测执行核心

当前仓库已经有一个最小可运行的回测执行核心,入口在:

  • zelqor.backtest.run_precomputed_pool_backtest
  • zelqor.api.run_precomputed_backtest
  • zelqor.backtest.scheduler.DayCallbackPayload
  • zelqor.backtest.create_backtest_state
  • zelqor.backtest.step_backtest_day
  • zelqor.backtest.finalize_backtest_result

这条链路当前适合:

  • 已经有交易日列表
  • 已经有每日股票池 daily_pools
  • 想先验证买入、持有、卖出和权益变化
  • 想在回测过程中逐日观察股票池、成交和权益变化

当前最小回测执行核心支持的成交时点包括:

  • open
  • next_open
  • high
  • high_limit
  • limit_up
  • average
  • avg
  • vwap
  • 默认 close

其中平均价口径为:

  • amount / volume
  • 如果 volume <= 0,则自动回退到 close

对应实现见:

  • src/zelqor/backtest/engine.py
  • src/zelqor/backtest/scheduler.py
  • tests/test_backtest_engine.py

如果你想直接体验逐日推进骨架,可以运行:

  • examples/run_step_backtest.py

这个示例会:

  • 创建 BacktestState
  • 构造 BacktestStepConfig
  • 按交易日循环调用 step_backtest_day(...)
  • 最后通过 finalize_backtest_result(...) 汇总最终结果

运行方式:

uv run --python .venv\Scripts\python.exe examples/run_step_backtest.py

运行 selector 回测最小链路

当前仓库也已经打通了一条更接近日频股票池策略的最小链路,入口在:

  • zelqor.strategy.interfaces.DailyPoolSelector
  • zelqor.strategy.interfaces.SelectorContext
  • zelqor.strategy.selector.build_daily_pools
  • zelqor.api.run_selector_backtest

这条链路当前适合:

  • selector 直接在策略脚本中实现
  • 每个交易日先生成股票池
  • 再把 daily_pools 交给最小回测执行核心

对应实现见:

  • src/zelqor/strategy/interfaces.py
  • src/zelqor/strategy/selector.py
  • src/zelqor/api.py
  • tests/test_selector_pipeline.py

运行 stateful step 策略最小链路

当前仓库已经支持更适合复杂跨日状态策略的正式接入方式,入口在:

  • zelqor.strategy.interfaces.StrategyStepContext
  • zelqor.strategy.interfaces.StrategyDayDecision
  • zelqor.strategy.interfaces.StatefulStepStrategy
  • zelqor.api.run_stateful_step_backtest

这条链路当前适合:

  • 策略需要维护观察池、待确认池或冷却期
  • 每个交易日都要推进自己的内部状态机
  • 策略负责决定今天买入池,引擎负责成交、持仓和权益

对应实现见:

  • src/zelqor/strategy/interfaces.py
  • src/zelqor/api.py
  • examples/run_stateful_step_limit_up_then_limit_up.py
  • tests/test_stateful_strategy_pipeline.py

如果你想看当前仓库内一个完整的 stateful step 示例,可以运行:

  • examples/run_stateful_step_limit_up_then_limit_up.py

这个示例当前演示的是:

  • 首次涨停先进入待入池列表
  • 下一交易日收盘后才正式进入观察池
  • 后续再次涨停触发买入
  • 每个交易日结束后实时打印状态、买卖和权益

运行方式:

uv run --python .venv\Scripts\python.exe examples/run_stateful_step_limit_up_then_limit_up.py

如果你想更详细理解这个示例内部是怎么运作的,可以继续看:

  • docs/stateful-step-example.md

使用 ClickHouse 配置

环境变量方式:

$env:CH_HOST="127.0.0.1"
$env:CH_USER="default"
$env:CH_PASSWORD="secret"
$env:CH_DATABASE="jqdata"

Python 中读取:

from zelqor.models import ClickHouseConfig

config = ClickHouseConfig.from_env()

更多配置方式见“ClickHouse 配置”页面。

使用日志

zelqor 现在内置了基于标准库 logging 的日志能力。

默认日志级别来源于:

  • ZELQOR_LOG_LEVEL

例如:

$env:ZELQOR_LOG_LEVEL="INFO"

如果你要看更细节的 SQL 和内部流程,可以改成:

$env:ZELQOR_LOG_LEVEL="DEBUG"

examples 里的常用脚本已经会自动初始化日志。

当前日志会覆盖这些关键节点:

  • ClickHouse 配置加载
  • ClickHouseProvider 初始化
  • 交易日 / universe / bars 查询
  • selector 每日执行
  • 回测开始 / 结束
  • 每个交易日的推进
  • 买入 / 卖出成交

运行配置加载示例

仓库内提供了一个最小配置示例:

  • examples/load_config.py

它会演示:

  • ClickHouseConfig.from_file(...)
  • ClickHouseConfig.from_env()

运行方式:

uv run --python .venv\Scripts\python.exe examples/load_config.py

验证远程 ClickHouse 连通性

仓库内提供了一个真实库联调测试:

  • tests/test_clickhouse_live_integration.py

推荐步骤:

  1. 复制 config.example.toml 为本地 config.toml
  2. 按你的远程 ClickHouse 信息修改配置
  3. 执行真实联调测试
uv run --python .venv\Scripts\python.exe pytest tests/test_clickhouse_live_integration.py -q

如果没有找到配置文件,测试会自动 skip,不会误报失败。

运行最小日线读取示例

仓库内提供了一个最小可运行示例:

  • examples/read_daily_bars.py

它会优先读取仓库根目录下的 config.toml,如果没有找到,则回退到环境变量。

它会在同一个文件里分别调用:

  • provider.get_daily_bars(..., as_numpy=False)
  • provider.get_daily_bars(..., as_numpy=True)

运行方式:

uv run --python .venv\Scripts\python.exe examples/read_daily_bars.py

运行交易日示例

如果你想看交易日列表和下一交易日:

  • examples/read_trading_dates.py

运行方式:

uv run --python .venv\Scripts\python.exe examples/read_trading_dates.py

运行 universe 示例

如果你想看某个交易日的股票池:

  • examples/read_universe.py

运行方式:

uv run --python .venv\Scripts\python.exe examples/read_universe.py

运行最近 N 根日线读取示例

仓库内也提供了一个窗口读取示例:

  • examples/read_recent_bars.py

它会在同一个文件里分别调用:

  • provider.get_bars(..., count=20, as_numpy=False)
  • provider.get_bars(..., count=20, as_numpy=True)

运行方式:

uv run --python .venv\Scripts\python.exe examples/read_recent_bars.py

运行兼容层示例

如果你想看旧脚本风格的 get_bars_compat(...)

  • examples/get_bars_compat.py

运行方式:

uv run --python .venv\Scripts\python.exe examples/get_bars_compat.py

运行最小回测执行核心示例

如果你想直接验证当前最小回测执行核心:

  • examples/run_precomputed_backtest.py

这个示例会:

  • 读取一小段交易日
  • 从第一天的 universe 中取前两只股票作为 daily_pools
  • 调用 run_precomputed_backtest(...)
  • 打印 summary、成交数量和最后一天权益

运行方式:

uv run --python .venv\Scripts\python.exe examples/run_precomputed_backtest.py

运行 selector 回测示例

如果你想直接验证 selector -> daily_pools -> backtest

  • examples/run_selector_backtest.py

这个示例会:

  • 读取一小段交易日
  • 在每个交易日调用 selector 生成股票池
  • 调用 run_selector_backtest(...)
  • 通过 on_day 逐日打印股票池、买卖和权益
  • 打印 summary、第一天股票池和第一笔成交

运行方式:

uv run --python .venv\Scripts\python.exe examples/run_selector_backtest.py

使用逐日回调

run_precomputed_backtest(...)run_selector_backtest(...)run_stateful_step_backtest(...) 现在都支持:

  • on_day

你可以传入一个回调函数,在每个交易日结束后获取一份摘要:

from zelqor.backtest.scheduler import DayCallbackPayload

def on_day(payload: DayCallbackPayload) -> None:
    print(payload.trade_date, payload.pool_codes, payload.buys, payload.sells, payload.equity)

当前回调对象里包含:

  • trade_date
  • pool_codes
  • buys
  • sells
  • notes
  • cash
  • market_value
  • equity
  • positions
  • warnings

运行 selector 策略骨架示例

如果你想看更接近真实策略代码的写法,仓库里还提供了两个骨架:

  • examples/selector_numpy_skeleton.py
  • examples/selector_polars_skeleton.py

这两个示例分别展示:

  • 如何使用 SelectorContext + 结构化 NumPy
  • 如何使用 SelectorContext + Polars

运行方式:

uv run --python .venv\Scripts\python.exe examples/selector_numpy_skeleton.py
uv run --python .venv\Scripts\python.exe examples/selector_polars_skeleton.py

构建文档站

uv run --python .venv\Scripts\python.exe mkdocs build

本地预览文档站

uv run --python .venv\Scripts\python.exe mkdocs serve