pybroker.optimize 模块
使用 Optuna 进行超参数声明和优化。
超参数为指标和执行函数声明可调节的值。每个超参数都会通过 hyperparam() 以名称全局注册,并在回测或优化时被解析为一个具体的 int 或 float。
将超参数作为关键字参数传递给 pybroker.indicator.indicator(),或将其列在 pybroker.strategy.Strategy.add_execution() 上,以便在执行函数内通过 ctx.hyperparam(name) 读取。
- class Hyperparam(name: str, default: int | float, low: int | float, high: int | float, step: int | float)[源代码]
基类:
object声明一个带有边界和步长的具名超参数。
通过
hyperparam()创建,并以name全局注册。示例
指标周期从 5 到 50,步长为 5:
period = hyperparam("period", default=14, low=5, high=50, step=5)
- class ObjectiveBundle(objective: Callable[[Trial], float], search_space: SearchSpace, score_overrides: Callable[[dict[str, Any]], float])[源代码]
基类:
objectmake_objective()的返回值。- search_space: SearchSpace
- class OptimizeMixin[源代码]
基类:
object实现超参数优化的 Mixin。
- optimize(score_fn: Callable[[TestResult], float], *, sampler: str | BaseSampler = 'grid', n_trials: int | None = None, direction: str = 'maximize', seed: int | None = None, windows: int | None = None, study: optuna.Study | None = None, pruner: optuna.pruners.BasePruner | None = None, train_size: float = 0.5, lookahead: int = 1, start_date: str | datetime | None = None, end_date: str | datetime | None = None, timeframe: str = '', between_time: tuple[str, str] | None = None, days: Any | None = None, warmup: int | None = None, parallel_indicators: bool = False, adjust: Any | None = None, calc_bootstrap: bool = False, verbose: bool = False) OptimizeResult[源代码]
在训练窗口上搜索
pybroker.optimize.hyperparam()的值,然后在保留的测试窗口上评估最佳值。由
pybroker.data.DataSource提供的数据会按照train_size指定的比例划分为训练集和测试集。每次试验都会使用一种超参数值组合在训练窗口上进行回测,并用score_fn为其打分。获胜的组合随后会在测试窗口上重放,而score_fn永远不会看到测试窗口。预训练模型(
model(..., pretrained=True))会按训练窗口加载,并在该窗口的所有试验中复用。不支持可训练模型;请在train_fn内部使用验证集划分来调优,或改用pybroker.strategy.Strategy.walkforward()。- 参数:
score_fn -- 为单次试验的训练窗口回测打分的
Callable[[TestResult], float]。默认按最大化处理;参见direction。sampler -- 候选值的选取方式。
"grid"(默认)会穷举所有组合,"tpe"使用optuna.samplers.TPESampler,"random"使用optuna.samplers.RandomSampler。也可以传入optuna.samplers.BaseSampler实例;它会按窗口进行深拷贝并重新播种,而多窗口运行会将副本分发给工作进程,因此该实例必须是可 pickle 的。网格采样器和随机采样器会在已配置的工作进程上并行评估试验。任何其他采样器 —— 即"tpe",或不是GridSampler也不是RandomSampler的实例 —— 都是自适应的,分批评估其试验会改变其提出的值,并使结果与工作进程数量绑定;因此这类采样器的试验会按顺序运行,并会有一条 info 级别的日志消息说明并行已被禁用。n_trials -- 要运行的试验数量。除
"grid"外,其他所有采样器都必须设置该参数;对于"grid",默认值为完整网格大小,设置较小的值则会随机抽取相应数量的组合。direction -- 对
score_fn进行"maximize"(默认)或"minimize"。seed -- 用于采样器和自助法指标的随机种子。默认为
None,表示不可复现。windows -- 当大于
1时,超参数会在windows个向前分析窗口中分别独立优化,各测试窗口会被拼接为一个连续的结果。默认为None,即单次训练/测试划分。study -- 用于记录试验的现有
optuna.study.Study,例如一个由持久化存储支持的 study。会使用该 study 自身的采样器和剪枝器,且其优化方向必须与direction一致。当windows大于1时不支持此参数。pruner -- 附加到所创建 study 的
optuna.pruners.BasePruner。每次试验都是一次完整的回测,没有可报告的中间值,因此剪枝实际上永远不会触发。train_size -- 每个窗口中用于训练的比例,不含
0和1。默认为0.5。lookahead -- 预测目标未来的 K 线数量。会在训练集和测试集之间保留出来,以防止训练数据跨边界泄漏,其单位是每个模型所拟合的时间框架的 K 线:通过
pybroker.model.ModelSource.intervals()绑定到某个区间的模型,会保留该区间的lookahead根 K 线,而不是基础时间框架的 K 线。默认为1。start_date -- 优化的起始日期(含)。必须在传递给
pybroker.strategy.Strategy构造函数的范围之内。end_date -- 优化的结束日期(含)。必须在传递给
pybroker.strategy.Strategy构造函数的范围之内。timeframe -- 指定数据时间框架分辨率的格式化字符串,用法与
pybroker.strategy.Strategy.walkforward()中相同。between_time -- 用于过滤数据的时间段(含边界),为
tuple[str, str],例如('9:30', '16:00')。days -- 用于过滤数据的星期(例如
"mon"、"tues")。warmup -- 运行执行函数之前需要经过的 K 线数量。设置时必须大于
0。parallel_indicators -- 如果为
True,pybroker.indicator.Indicator数据会使用多个进程并行计算。默认为False。adjust -- 对
pybroker.data.DataSource应用的复权调整类型。calc_bootstrap -- 是否为测试结果计算随机自助法评估指标。默认为
False。verbose -- 是否记录每次试验回测的日志 —— 包括指标计算、测试集划分进度条以及 Optuna 自身的试验日志。默认为
False,此时仅记录优化摘要和最终测试窗口的评估结果。
- 返回:
包含获胜超参数值、其在训练窗口获得的得分,以及其产生的测试窗口
pybroker.strategy.TestResult的OptimizeResult。当windows大于1时,best_params、best_score和study描述的是 最后一个 窗口,而result则是所有窗口拼接后的结果;各窗口的结果参见OptimizeResult.windows。- 抛出:
ValueError -- 如果未添加任何执行函数;如果任何模型源是可训练的;如果
train_size不在0和1之间(不含);如果warmup不大于0;如果windows不大于0;如果study与大于1的windows同时使用,或其优化方向存在冲突;或者如果日期超出了传递给pybroker.strategy.Strategy构造函数的范围。
- class OptimizeResult(best_params: dict[str, Any], best_score: float, result: TestResult, study: optuna.Study, windows: tuple[WindowOptimizeResult, ...] | None = None)[源代码]
基类:
objectStrategy.optimize()的结果。- result
测试窗口的
pybroker.strategy.TestResult。当设置了windows时,这是一个由每个窗口的测试数据拼接而成的单一连续结果,仓位和现金会跨窗口边界延续。- 类型:
- study
保存试验的
optuna.study.Study。当设置了windows时,为最后一个窗口的 study;其余窗口参见windows。- 类型:
optuna.Study
- windows
各窗口的调优结果;对于单次训练/测试划分则为
None。- 类型:
Optional[tuple[WindowOptimizeResult, ...]]
- class SearchSpace(hyperparams: frozenset[str], specs: Mapping[str, Hyperparam])[源代码]
基类:
object从策略中收集到的可搜索超参数。
仅包含满足
low < high且会在Strategy.optimize()期间传递给 Optuna 的超参数。- specs
超参数名称到
Hyperparam规格的映射。- 类型:
Mapping[str, pybroker.optimize.Hyperparam]
- class WindowOptimizeResult(params: dict[str, Any], study: Study, train_score: float, train_start_date: datetime | None = None, train_end_date: datetime | None = None, test_start_date: datetime | None = None, test_end_date: datetime | None = None, execution_symbols: dict[int, frozenset[str]] | None = None)[源代码]
基类:
object各窗口的向前分析优化结果。
保存某个窗口被调优到的值,本身并不是一次独立的回测:唯一的样本外
pybroker.strategy.TestResult存放在OptimizeResult.result中,由所有窗口拼接而成。- study
保存该窗口试验的
optuna.study.Study。
- train_start_date
该窗口训练数据的起始日期;当训练集划分为空时为
None。- 类型:
datetime.datetime | None
- train_end_date
该窗口训练数据的结束日期;当训练集划分为空时为
None。- 类型:
datetime.datetime | None
- test_start_date
该窗口测试数据的起始日期 —— 即其调优后的
params在拼接后的OptimizeResult.result中进行交易的区间 —— 当测试集划分为空时为None。- 类型:
datetime.datetime | None
- test_end_date
该窗口测试数据的结束日期;当测试集划分为空时为
None。- 类型:
datetime.datetime | None
- execution_symbols
当
pybroker.common.SymbolSelector为该窗口选择品种时,每个执行 id 所解析到的品种;如果没有任何执行使用选择器,则为None。
- build_run_hyperparams(specs: Mapping[str, Hyperparam], overrides: dict[str, Any] | None = None) dict[str, Any][源代码]
为单次回测或单次试验构建超参数字典。
- 参数:
specs -- 从策略可达的全部超参数。
overrides -- 要合并到默认值之上的试验值或用户提供的值。
- 返回:
specs中每个超参数的name -> value字典。
- collect_hyperparams(strategy: _ExecutionsHost) dict[str, Hyperparam][源代码]
收集从
strategy可达的全部超参数。
- collect_search_space(strategy: _ExecutionsHost) SearchSpace[源代码]
收集从
strategy可达的可搜索超参数。
- hyperparam(name: str, *, default: int | float, low: int | float, high: int | float, step: int | float) Hyperparam[源代码]
创建并注册一个
Hyperparam。- 参数:
name -- 该超参数的唯一标识符。在指标关键字参数、
add_execution(..., hyperparams=[...])以及ctx.hyperparam(name)中被引用。default -- 用于回测的值。
low -- 优化期间搜索的候选值下限(含)。
high -- 优化期间搜索的候选值上限(含)。
step -- 候选值之间的间隔。必须为正数。
- 返回:
已注册的
Hyperparam实例。
- make_objective(strategy: _OptimizeTrialHost, score_fn: Callable[[TestResult], float], *, train_rows: np.ndarray, df: pd.DataFrame, hyperparams: Mapping[str, Hyperparam], search_space: SearchSpace, invariant_indicator_data: dict[IndicatorSymbol, pd.Series], window_executions: set[Execution], master_store: Any, interval_data: Any, parallel_indicators: bool, warmup: int | None, pretrained_models: Mapping[ModelSymbol, TrainedModel], exit_dates: Mapping[str, np.datetime64], verbose: bool = False) ObjectiveBundle[源代码]
构建一个用于训练窗口打分的 Optuna 目标函数。
当
verbose为False(默认值)时,每次试验的回测都会在抑制日志的情况下运行,以避免每个搜索到的组合都重复显示逐次试验的进度条。