跳转到正文

参数优化 API ​

从 localquant.optimize 导入公共接口。优化器将参数网格拆成独立回测,收集指标、排序并按需保存检查点;它不定义买卖逻辑,也不自动证明某组参数有效。先跑通固定参数回测,再使用本页接口。

seeddata 回测回调 ​

先跑通固定参数策略。将下面的函数放在可导入的 optimize_runner.py 中:shared 提供已验证的 config、策略文件绝对路径 strategy_file 和覆盖全部组合的 bundle。策略从 context 读取参数;若参数参与信号预处理,应在回调中先重算信号,再把产物交给策略。

python
from copy import deepcopy

from localquant import run_file
from localquant.mod.localquant_mod_seeddata_source import register_bundle, discard_bundle
from localquant.optimize import RunOutcome

def run_once(params, shared):
    config = deepcopy(shared["config"])
    config.setdefault("extra", {}).setdefault("context_vars", {}).update(params)
    config["mod"].setdefault("sys_analyser", {}).update(enabled=True, record=True, output_file=None)
    key = register_bundle(shared["bundle"])
    try:
        config["mod"]["seeddata_source"]["bundle_key"] = key
        analyser = run_file(shared["strategy_file"], config=config)["sys_analyser"]
    finally:
        discard_bundle(key)
    return RunOutcome(metrics={
        name: float(analyser["summary"][name])
        for name in ("total_returns", "annualized_returns", "max_drawdown", "sharpe")
    })

每轮从相同初始账户开始;策略模块的全局状态须重置。

常规任务只保留指标,避免每组写入同一 output_file;需要保留单组报告时,为该组指定独立目录。每次回测领取一次注册键;共享的是行情 bundle,而不是已经消费的 key。

网格搜索 ​

python
from localquant.optimize import run_grid_search
from optimize_runner import run_once

# config、bundle 来自已跑通的固定参数回测;文件属于使用者自己的策略。
# 策略在 init 中保留 context.target_weight,按该参数提交目标权重。
shared = {"config": config, "bundle": bundle, "strategy_file": "/绝对路径/strategy.py"}
frame = run_grid_search(
    run_once, {"target_weight": [0.2, 0.4, 0.6]},
    shared=shared, max_workers=2, sort_by="sharpe", ascending=False,
)

参数网格取笛卡尔积,值须有限且可 JSON 序列化。constraint(params) 可过滤组合;全部过滤时报错。sort_by 和 ascending 可为多字段配置;排序字段不存在时报错,已存在但非有限的指标排在后面,同分按参数 JSON 字典序决胜。

返回 DataFrame 包含参数列、回调提供的指标及 duration。引擎不自动重跑赢家或生成报告;调用方按研究目标选出有效参数,再运行完整回测。任务异常直接抛出,不返回伪造的失败指标。

并行与续跑 ​

max_workers=1 串行;大于 1 使用 Linux fork。回调须可 pickle,并定义于可导入模块,不能是入口脚本中的 __main__ 函数、闭包或 lambda。大数据通过 shared 共享,任务中不修改共享行情;建池前不启动后台线程。入口放在 if __name__ == "__main__": 中。

优化配置不使用 extra.log_file;多轮运行会累积日志输出,改用控制台日志或由入口管理日志。worker 数由数据规模和内存决定,不用线程并发调用回测。

checkpoint_dir 保存成功任务,复用还需相同参数及 run_fingerprint。提供能区分有效配置、策略和数据的身份,不能只复用默认空字符串。公共辅助接口:

  • run_fingerprint(source_paths, configuration, datasets, salt=""):source_paths 传使用者自己的策略文件,另传有效配置和具名 DataFrame 输入;不需要提供框架源文件。配置包含已安装的框架版本和研究口径,salt 可追加身份。
  • write_run_manifest(directory, fingerprint, configuration):记录目录身份,已有不同身份时拒绝复用。

检查点不保存失败任务,报错后已写入检查点的成功任务保留。赢家报告及 CSV 的保存由调用方负责。

curve_metrics(values, initial_cash, trading_days_a_year=252, risk_free_rate=0) 可从无外部出入金的每日资产计算首日计入初始资金的收益、年化、夏普和正幅度回撤;有出入金时直接使用分析器 summary,不向该函数传入包含资金流的总权益。已有分析结果时,直接使用 summary;确需由资产序列重算时,将该结果的 backtest_settings["trading_days_a_year"] 显式传给 trading_days_a_year,避免使用独立函数默认值改变口径。不从不同起点的净值自行拼接绩效。

公共调用参数 ​

text
run_grid_search(
    run_once, param_grid, *, shared=None,
    sort_by="sharpe", ascending=False, constraint=None,
    max_workers=1, checkpoint_dir=None, run_fingerprint="",
)

run_once(params, shared) 返回 RunOutcome(metrics=指标字典);优化表只收集 metrics,不自动保存 RunOutcome 中的 analyser 或曲线。结果 duration 单位为秒。参数名与指标名应分别表达参数和绩效,避免重名覆盖。

expand_grid(param_grid, constraint=None) 可只展开合法组合。make_run_once 不负责为 seeddata 每轮注册新 bundle,不能把含固定 bundle_key 的配置直接用于它;本数据链路使用上面的显式回调。

localquant documentation