freqtrade hyperopt 命令深度参考:参数空间、损失函数与并行优化实践
freqtrade 的 hyperopt 命令是基于 optuna 的超参数优化入口:它反复执行回测,在策略定义的参数空间(buy/sell/enter/exit/roi/stoploss/trailing/protection 等)中寻找使损失函数最小的参数组合。本文完整解析 hyperopt 命令参考 中的全部命令行参数,结合源码中的默认值常量与调度实现,帮助你把优化任务配置到可直接复制运行的程度,并掌握 hyperopt-list、hyperopt-show 等结果后处理命令的配合方式。
一、前置条件:依赖安装与数据准备
hyperopt 依赖较重(optuna、scikit-learn 等),并非随基础包默认安装。当前仓库中 requirements-hyperopt.txt 锁定的版本为:
-r requirements.txt
# Required for hyperopt
scikit-learn==1.9.0
filelock==3.32.4
optuna==4.9.0
cmaes==0.13.1
手动安装方式(或执行仓库中的 setup.sh 后手动补齐):
source .venv/bin/activate
pip install -r requirements-hyperopt.txt
使用 Docker 镜像的用户无需额外安装,镜像内已包含 hyperopt 依赖。注意两点来自 docs/hyperopt.md 的官方提示:
- hyperopt 需要与回测相同的历史数据,先通过
download-data命令准备好 K 线数据; - hyperopt 会占满所有 CPU 核心且耗时较长,在单核机器(如树莓派)上可能出现崩溃或不推荐运行的情况。
二、命令总览
usage: freqtrade hyperopt [-h] [-v] [--no-color] [--logfile FILE] [-V]
[-c PATH] [-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [--recursive-strategy-search]
[--freqaimodel NAME] [--freqaimodel-path PATH]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,feather,parquet}]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
[-p PAIRS [PAIRS ...]] [--hyperopt-path PATH]
[--eps] [--enable-protections]
[--dry-run-wallet DRY_RUN_WALLET]
[--timeframe-detail TIMEFRAME_DETAIL] [-e INT]
[--spaces SPACES [SPACES ...]] [--print-all]
[--print-json] [-j JOBS] [--random-state INT]
[--min-trades INT] [--hyperopt-loss NAME]
[--disable-param-export] [--ignore-missing-spaces]
[--analyze-per-epoch] [--early-stop INT]
一次典型的最小化运行:
freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily \
--spaces roi stoploss trailing \
--strategy MyWorkingStrategy --config config.json -e 100
下面按功能分组完整覆盖 命令参考 中的所有选项。
三、核心优化参数
3.1 -e, --epochs:优化轮数
指定评估的参数组合数量,默认 100。该默认值由 freqtrade/constants.py 中的 HYPEROPT_EPOCH = 100 定义,CLI 侧在 freqtrade/commands/cli_options.py 中以 default=constants.HYPEROPT_EPOCH 读取。轮数越多越容易收敛,但耗时线性增长;可配合 --early-stop 提前终止。
3.2 --spaces:选择要优化的参数空间
指定哪些参数参与优化,空格分隔。内置取值在 freqtrade/constants.py 中定义:
HYPEROPT_BUILTIN_SPACES = [
"buy", "sell", "enter", "exit",
"roi", "stoploss", "trailing", "protection", "trades",
]
HYPEROPT_BUILTIN_SPACE_OPTIONS = ["default", "all"] + HYPEROPT_BUILTIN_SPACES
default(缺省):包含除trailing、protection、trades之外的所有空间;all:全部空间;- 也可以传策略中自定义命名的空间(如
space='my_custom_space'),自定义空间不会出现在--help的内置列表里。
策略侧的对应关系(见 docs/hyperopt.md):参数通过 IntParameter/DecimalParameter/RealParameter/CategoricalParameter/BooleanParameter 声明,并依靠命名前缀(buy_*、enter_* 等)或显式 space= 归属空间。若某个请求的空间内没有任何参数,hyperopt 会报错,可用 --ignore-missing-spaces(别名 --ignore-unparameterized-spaces)抑制该错误。
3.3 --hyperopt-loss:损失函数
优化目标由损失函数决定,不同函数会得出完全不同的结果。--hyperopt-loss(别名 --hyperoptloss)接收 IHyperOptLoss 子类名。CLI 帮助文本中的内置函数列表来自 freqtrade/constants.py 的 HYPEROPT_LOSS_BUILTIN,与 freqtrade/optimize/hyperopt_loss/ 目录下的实现一一对应:
| 类名 | 优化倾向 |
|---|---|
ShortTradeDurHyperOptLoss |
偏好短平均持仓时间 |
OnlyProfitHyperOptLoss |
只看利润 |
SharpeHyperOptLoss / SharpeHyperOptLossDaily |
夏普比率(总量/按日) |
SortinoHyperOptLoss / SortinoHyperOptLossDaily |
Sortino 比率(总量/按日) |
CalmarHyperOptLoss |
Calmar 比率 |
MaxDrawDownHyperOptLoss / MaxDrawDownRelativeHyperOptLoss / MaxDrawDownPerPairHyperOptLoss |
最大回撤(绝对/相对/按币种) |
ProfitDrawDownHyperOptLoss |
利润与回撤的综合 |
MultiMetricHyperOptLoss |
多指标加权组合 |
自定义损失函数放在用户目录并通过 --hyperopt-path PATH 追加查找路径(cli_options.py 第 279-283 行)。运行 freqtrade list-hyperoptloss 可列出当前环境中可用的损失函数(参考 docs/commands/list-hyperoptloss.md)。
3.4 -j, --job-workers:并行工作进程数
控制 hyperopt 的并行回测进程数:-1(默认)使用全部 CPU,-2 为全部减一,1 则完全禁用并行代码(cli_options.py 第 340-350 行)。并行调度实现位于 freqtrade/optimize/hyperopt/hyperopt.py:进程池把剩余轮数均分到各 worker(evals = ceil((self.total_epochs - start) / jobs)),最后剩余不足一批时按余数截断。官方文档明确警告单核 CPU 上 hyperopt 可能崩溃(Issue #1133),遇到此类问题可将 -j 1 作为排查手段。
3.5 --random-state:可复现性
设置为正整数后,随机种子固定,相同数据与参数下的优化路径可复现。源码中 hyperopt.py 第 141-142 行 显示:未指定时会自动随机生成 random.randint(1, 2**16 - 1) 并在日志中打印 Using optimizer random state: ...,因此复现实验时应以日志中打印的种子为准传入本参数。
3.6 --early-stop:早停
--early-stop INT:若连续 INT 个 epoch 没有改进则提前停止,默认 0(禁用)。CLI 定义见 cli_options.py 第 292-298 行;调度循环中在 hyperopt.py 第 283-286 行 检查 self.hyperopter.es_epochs > 0 后触发 Early stopping after ... epochs。长任务中可显著节省 CPU。
3.7 --analyze-per-epoch:逐轮重算指标
默认情况下,hyperopt 先把数据载入内存、每对交易对只执行一次 populate_indicators(),随后各 epoch 仅重跑 populate_entry_trend()、populate_exit_trend() 与回测。--analyze-per-epoch 会把 populate_indicators() 移入每个 epoch 进程内逐轮计算,代价是 CPU 增加,但可以避免 .range 方式预生成大量指标列导致的内存(OOM)问题——hyperopt.py 第 48 行 读取该配置并在 epoch 循环中分支处理(if self.analyze_per_epoch:)。官方建议:当优化参数被用于指标计算、或 .range 展开列过多时改用该选项。
3.8 结果输出控制
| 参数 | 作用 |
|---|---|
--print-all |
打印所有 epoch 的结果而不仅是最优(默认 False,见 cli_options.py 第 314-319 行) |
--print-json |
以 JSON 格式输出结果 |
--min-trades INT |
参与评估的最少交易数,默认 1(cli_options.py 第 357-364 行),过滤掉交易过少的“伪最优”组合 |
--disable-param-export |
禁用优化结束后自动把最优参数导出到策略/JSON 文件 |
--no-color |
关闭结果着色,重定向输出到文件时常用 |
四、与回测一致的场景参数
这些参数保证优化时的模拟环境与你后续回测/实盘一致,逐项继承自 命令参考:
| 参数 | 说明 |
|---|---|
-i, --timeframe |
主时间周期(1m、5m、30m、1h、1d 等),覆盖配置中的 timeframe |
--timerange |
限定数据时间范围,格式 yyyymmdd 或 yyyymmddThhmm,如 20240101-20240201T1200 |
--data-format-ohlcv {json,jsongz,feather,parquet} |
K 线存储格式,默认 feather |
-p, --pairs |
空格分隔的币种列表,限定优化范围 |
--max-open-trades INT |
覆盖配置中的 max_open_trades |
--stake-amount |
覆盖配置中的 stake_amount |
--fee FLOAT |
手续费比率,会在开仓和平仓各应用一次 |
--eps, --enable-position-stacking |
允许同一币种多次开仓(仓位叠加),仅适用于回测/hyperopt,结果无法在 dry/live 中复现 |
--enable-protections(别名 --enableprotections) |
回测中启用 protections,速度明显下降但结果更贴近实盘 |
--dry-run-wallet, --starting-balance |
回测/hyperopt 使用的起始余额 |
--timeframe-detail |
细粒度回测时间周期,用于在粗时间周期上模拟更精确的成交价 |
五、通用参数与策略查找参数
通用参数(Common arguments):
| 参数 | 说明 |
|---|---|
-v, --verbose |
详细模式,-vv、-vvv 逐级更详细 |
--no-color |
禁用着色(重定向到文件时有用) |
--logfile, --log-file FILE |
日志写文件;特殊值 syslog、journald |
-V, --version |
打印版本号后退出 |
-c, --config PATH |
配置文件路径,默认 userdir/config.json 或 config.json(取先存在者);可多次使用;设为 - 表示从 stdin 读取 |
-d, --datadir, --data-dir PATH |
历史数据根目录;查看合约(futures)数据需同时指定 trading-mode |
--userdir, --user-data-dir PATH |
用户数据目录 |
策略参数(Strategy arguments):
| 参数 | 说明 |
|---|---|
-s, --strategy NAME |
策略类名 |
--strategy-path PATH |
追加策略查找路径 |
--recursive-strategy-search |
在 strategies 目录中递归查找策略 |
--freqaimodel NAME |
指定 FreqAI 模型 |
--freqaimodel-path PATH |
追加 FreqAI 模型查找路径 |
六、执行流程:命令背后发生了什么
结合 docs/hyperopt.md 的“Hyperopt execution logic”与 freqtrade/optimize/hyperopt/hyperopt.py 的实现,一次 freqtrade hyperopt 的完整流程为:
- 加载历史数据到内存,按交易对各执行一次
populate_indicators()(除非指定--analyze-per-epoch); - 启动
--job-workers指定的进程池,基于 optuna 采样器(当前为 NSGAIII 多目标采样)生成参数组合; - 每组参数依次执行
populate_entry_trend()→populate_exit_trend()→ 完整回测模拟; - 回测结果送入
--hyperopt-loss指定的损失函数打分,采样器据此决定下一组参数; - 结束(或
--early-stop触发)后打印最优 epoch 详情,并把最优参数自动导出(可用--disable-param-export关闭)。优化结果以 pickle 文件保存于user_data/hyperopt_results/。
--spaces 与策略声明的映射关系同样在此处生效:从源码结构看,未找到任何参数对应空间时会直接报错,这正对应 --ignore-missing-spaces 需要抑制的错误路径。
七、结果后处理:hyperopt-list 与 hyperopt-show
优化跑完后,两个配套命令用于回顾历史结果(实现入口在 freqtrade/commands/hyperopt_commands.py):
hyperopt-list:列出已评估的 epochs,支持--best、--profitable、--min-trades、--min-avg-profit、--min-objective等过滤条件,--export-csv FILE导出 CSV(会禁用表格打印)。start_hyperopt_list内部按loss排序后自动展示最优 epoch 的详情(见 hyperopt_commands.py 第 50-53 行)。详见 docs/commands/hyperopt-list.md。hyperopt-show:按-n(1 起始的 epoch 序号,支持负数倒数索引)查看某个 epoch 的完整回测报表,--best/--profitable可先过滤,--breakdown {day,week,month,year,weekday}输出分时段拆解;该命令同样会触发参数导出逻辑(HyperoptTools.try_export_params),可用--disable-param-export关闭。详见 docs/commands/hyperopt-show.md。
两个命令都通过 get_latest_hyperopt_file 在 user_data/hyperopt_results/ 下定位结果文件(hyperopt_commands.py 第 29-31 行),并支持 --hyperopt-filename 指定具体文件、--print-json 输出 JSON。
八、实战速查
| 目标 | 推荐命令要点 |
|---|---|
| 不改动策略、只优化 ROI/止损/移动止损 | freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi stoploss trailing -s MyStrategy --config config.json -e 100 |
| 优化买卖信号并抑制无参数空间报错 | --spaces enter exit --ignore-missing-spaces |
| 内存吃紧时避免 OOM | 改用 --analyze-per-epoch,或缩小 .range 的取值范围 |
| 固定随机种子以便复现 | 查看日志中的 Using optimizer random state,再以 --random-state <N> 重跑 |
| 长任务省 CPU | --early-stop 50(连续 50 epoch 无改进即停) |
| 复盘某次运行的第 3 个好结果 | freqtrade hyperopt-show -n 3 --best --breakdown week |
适用前提与限制:以上参数行为对应当前仓库版本;--eps 产生的结果无法在 dry/live 交易复现;--enable-protections 会显著拖慢回测;单核 CPU 环境运行 hyperopt 存在已知崩溃风险。完整教程(参数类型、.range 技巧、Guards/Triggers 设计、自定义空间覆盖)请继续阅读 docs/hyperopt.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00