news 2026/9/7 10:08:56

freqtrade list-hyperoptloss 命令实战:发现并选择超参优化损失函数的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
freqtrade list-hyperoptloss 命令实战:发现并选择超参优化损失函数的完整指南

freqtrade list-hyperoptloss 命令实战:发现并选择超参优化损失函数的完整指南

【免费下载链接】freqtradeFree, open source crypto trading bot项目地址: https://gitcode.com/GitHub_Trending/fr/freqtrade

list-hyperoptloss是 Freqtrade 用于列出所有可用超参优化(Hyperopt)损失函数的命令。本篇基于 list-hyperoptloss 命令参考,完整讲解该命令的用法与全部参数,并结合仓库源码说明其背后的类发现机制(HyperOptLossResolver)、内置损失函数清单及其各自优化目标,以及如何在hyperopt中通过--hyperopt-loss指定这些损失函数。读完本文,你可以快速确认当前环境中有哪些损失函数可用、自定义损失函数放在哪里才会被发现,并为优化任务选择更合适的优化目标。

命令概览与完整参数

list-hyperoptloss的输出即命令的 help 信息,完整用法如下(源自 docs/commands/list-hyperoptloss.md):

usage: freqtrade list-hyperoptloss [-h] [-v] [--no-color] [--logfile FILE] [-V] [-c PATH] [-d PATH] [--userdir PATH] [--hyperopt-path PATH] [-1] options: -h, --help show this help message and exit --hyperopt-path PATH Specify additional lookup path for Hyperopt Loss functions. -1, --one-column Print output in one column. Common arguments: -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). --no-color Disable colorization of hyperopt results. May be useful if you are redirecting output to a file. --logfile, --log-file FILE Log to the file specified. Special values are: 'syslog', 'journald'. See the documentation for more details. -V, --version show program's version number and exit -c, --config PATH Specify configuration file (default: `userdir/config.json` or `config.json` whichever exists). Multiple --config options may be used. Can be set to `-` to read config from stdin. -d, --datadir, --data-dir PATH Path to the base directory of the exchange with historical backtesting data. To see futures data, use trading-mode additionally. --userdir, --user-data-dir PATH Path to userdata directory.

该命令属于 Freqtrade 的一组 "list" 类只读工具命令,命令注册位于 freqtrade/commands/arguments.py:

list_hyperopt_loss_cmd = subparsers.add_parser( "list-hyperoptloss", help="Print available hyperopt loss functions.", parents=[_common_parser], ) list_hyperopt_loss_cmd.set_defaults(func=start_list_hyperopt_loss_functions) self._build_args(optionlist=ARGS_LIST_HYPEROPTS, parser=list_hyperopt_loss_cmd)

参数逐项说明:

参数作用
--hyperopt-path PATH指定 Hyperopt Loss 函数的额外查找路径。默认情况下命令只会扫描user_data/hyperopts/与内置目录;如果你把自定义损失函数放在其他目录,需要用它把该目录加入搜索范围
-1/--one-column以单列纯文本输出(每行一个类名),便于脚本处理或重定向到文件
-c/--config PATH指定配置文件;可重复使用以合并多份配置,也可设为-从 stdin 读取
-d/--datadir PATH历史数据目录(对纯列表命令影响有限,但与hyperopt共用同一套公共参数)
--userdir/--user-data-dir PATH指定 userdata 目录。损失函数搜索路径中的user_data/hyperopts/正是相对此目录解析的
-v/--verbose开启详细日志,-vv-vvv逐级增加
--no-color关闭彩色输出,输出重定向到文件时很有用
--logfile FILE写日志到文件,支持syslogjournald特殊值
-V/--version输出版本号后退出

由于该命令运行在RunMode.UTIL_NO_EXCHANGE模式下(见下文源码分析),它不需要连接交易所,是一个纯粹的本地扫描工具,可以放心在 CI 或脚本中频繁调用。

源码实现:命令如何发现损失函数

命令入口函数start_list_hyperopt_loss_functions位于 freqtrade/commands/list_commands.py:

def start_list_hyperopt_loss_functions(args: dict[str, Any]) -> None: """ Print files with FreqAI models custom classes available in the directory """ from freqtrade.configuration import setup_utils_configuration from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) model_objs = HyperOptLossResolver.search_all_objects(config, not args["print_one_column"]) # Sort alphabetically model_objs = sorted(model_objs, key=lambda x: x["name"]) if args["print_one_column"]: print("\n".join([s["name"] for s in model_objs])) else: _print_objs_tabular(model_objs, config.get("print_colorized", False))

从源码结构看,其执行链路为:

  1. setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)构建工具类配置(不初始化交易所连接);
  2. 调用HyperOptLossResolver.search_all_objects(...)扫描所有候选目录,收集继承自IHyperOptLoss的类;
  3. 结果按类名字母排序后输出:--one-column时打印纯文本列表,否则通过_print_objs_tabular()渲染为 Rich 表格,表中还会标注每个类的location(来源文件相对路径)与加载状态(OK / LOAD FAILED / DUPLICATE NAME,状态列逻辑见 freqtrade/commands/list_commands.py)。

搜索路径的构成

真正决定"能列出哪些损失函数"的是HyperOptLossResolver的类属性,位于 freqtrade/resolvers/hyperopt_resolver.py:

class HyperOptLossResolver(IResolver): """ This class contains all the logic to load custom hyperopt loss class """ object_type = IHyperOptLoss object_type_str = "HyperoptLoss" user_subdir = USERPATH_HYPEROPTS # 即 "hyperopts" initial_search_path = Path(__file__).parent.parent.joinpath("optimize/hyperopt_loss").resolve()

结合基类IResolver.build_search_paths()的实现(见 freqtrade/resolvers/iresolver.py),最终搜索顺序为(越靠前优先级越高):

  1. --hyperopt-path指定的额外目录(extra_dirs插入到最前);
  2. <user_data_dir>/hyperopts/USERPATH_HYPEROPTS = "hyperopts",定义于 freqtrade/constants.py);
  3. 内置目录freqtrade/optimize/hyperopt_loss/

也就是说:自定义损失函数放进user_data/hyperopts/即可被发现,无需--hyperopt-path;放在仓库之外时才需要显式传入。扫描时基类会用importlib逐个加载.py文件,只收集本模块中定义(obj.__module__ == module_name)且继承自IHyperOptLoss的非接口类;导入失败的模块会被跳过并记录 warning(若开启enum_failed则会显示为 LOAD FAILED)。

损失函数接口:IHyperOptLoss

所有被列出的对象都必须实现IHyperOptLoss抽象接口,定义于 freqtrade/optimize/hyperopt_loss/hyperopt_loss_interface.py:

class IHyperOptLoss(ABC): """ Interface for freqtrade hyperopt Loss functions. Defines the custom loss function (`hyperopt_loss_function()` which is evaluated every epoch.) """ timeframe: str @staticmethod @abstractmethod def hyperopt_loss_function( *, results: DataFrame, trade_count: int, min_date: datetime, max_date: datetime, config: Config, processed: dict[str, DataFrame], backtest_stats: dict[str, Any], starting_balance: float, **kwargs, ) -> float: """ Objective function, returns smaller number for better results """

要点:

  • hyperopt_loss_function必须是@staticmethod,每个 epoch 都会被调用一次;
  • 返回值是越小越好的目标值——Hyperopt 的整个搜索过程就是在最小化这个数;
  • 函数签名提供了回测结果 DataFrame(results)、交易数量(trade_count)、时间范围、完整配置、按对处理的 DataFrame(processed)与回测统计(backtest_stats),足以计算任意基于回测结果的指标;
  • 加载时 resolver 会把配置中的timeframe赋值给损失函数类(hyperoptloss.__class__.timeframe = str(config["timeframe"]),见 freqtrade/resolvers/hyperopt_resolver.py),供损失函数感知当前优化粒度。

仓库自带的 freqtrade/templates/sample_hyperopt_loss.py 是一个可直接复制到user_data/hyperopts/改造的示例实现(包含TARGET_TRADESEXPECTED_MAX_PROFITMAX_ACCEPTED_TRADE_DURATION等可调常量)。

内置的 12 种损失函数

内置损失函数集中定义在 freqtrade/optimize/hyperopt_loss/ 目录下,其名称清单在 freqtrade/constants.py 中以HYPEROPT_LOSS_BUILTIN维护:

HYPEROPT_LOSS_BUILTIN = [ "ShortTradeDurHyperOptLoss", "OnlyProfitHyperOptLoss", "SharpeHyperOptLoss", "SharpeHyperOptLossDaily", "SortinoHyperOptLoss", "SortinoHyperOptLossDaily", "CalmarHyperOptLoss", "MaxDrawDownHyperOptLoss", "MaxDrawDownRelativeHyperOptLoss", "MaxDrawDownPerPairHyperOptLoss", "ProfitDrawDownHyperOptLoss", "MultiMetricHyperOptLoss", ]

list-hyperoptloss默认输出中就会包含上述全部 12 个内置类。它们在 超参优化文档 中的定义与优化目标如下:

类名对应文件优化目标
ShortTradeDurHyperOptLosshyperopt_loss_short_trade_dur.py传统(legacy)默认损失函数:侧重缩短平均交易时长并规避亏损
OnlyProfitHyperOptLosshyperopt_loss_onlyprofit.py只考虑盈利额(profit only)
SharpeHyperOptLosshyperopt_loss_sharpe.py优化基于逐笔交易收益与其标准差计算的 Sharpe 比率
SharpeHyperOptLossDailyhyperopt_loss_sharpe_daily.py优化基于每日收益的 Sharpe 比率
SortinoHyperOptLosshyperopt_loss_sortino.py优化基于逐笔收益与下行标准差的 Sortino 比率
SortinoHyperOptLossDailyhyperopt_loss_sortino_daily.py优化基于每日收益与下行标准差的 Sortino 比率
CalmarHyperOptLosshyperopt_loss_calmar.py优化交易收益相对最大回撤的 Calmar 比率
MaxDrawDownHyperOptLosshyperopt_loss_max_drawdown.py优化最大绝对回撤
MaxDrawDownRelativeHyperOptLosshyperopt_loss_max_drawdown_relative.py同时优化最大绝对回撤,并按最大相对回撤调整
MaxDrawDownPerPairHyperOptLosshyperopt_loss_max_drawdown_per_pair.py按交易对计算收益/回撤比,以最差的一对为目标值,防止个别交易对的好结果"拉高"整体指标
ProfitDrawDownHyperOptLosshyperopt_loss_profit_drawdown.py以最大收益 + 最小回撤为联合目标;文件内DRAWDOWN_MULT常量可调松/调紧对回撤的惩罚
MultiMetricHyperOptLosshyperopt_loss_multi_metric.py综合收益、回撤、Profit Factor、Expectancy、胜率等多指标;并对交易数量过少的 epoch 施加惩罚,鼓励足够的交易频率

选择损失函数的经验(对应 docs/hyperopt.md 的 "Loss-functions" 一节):

  • 追求资金曲线稳健性:优先考虑SharpeHyperOptLossDaily/SortinoHyperOptLossDaily(按日归一,减少交易次数差异带来的偏差);
  • 控制回撤风险MaxDrawDownHyperOptLoss及其 Relative/PerPair 变体;PerPair变体特别适合多交易对组合,避免"一星带多尘";
  • 平衡收益与回撤ProfitDrawDownHyperOptLossMultiMetricHyperOptLoss
  • ShortTradeDurHyperOptLoss是历史默认值,适合快速复现早期结果,但对现代组合目标通常不如比率型损失函数精细。

在 hyperopt 中使用损失函数

list-hyperoptloss列出的类名,正是运行超参优化时--hyperopt-loss参数的取值。该参数定义于 freqtrade/commands/cli_options.py,help 文本本身就提示了全部内置函数:

"hyperopt_loss": Arg( "--hyperopt-loss", "--hyperoptloss", help="Specify the class name of the hyperopt loss function class (IHyperOptLoss). " "Different functions can generate completely different results, " "since the target for optimization is different. Built-in Hyperopt-loss-functions are: " f"{', '.join(HYPEROPT_LOSS_BUILTIN)}", metavar="NAME", ),

典型工作流是"先列后用":

# 1. 确认当前可用的损失函数(含 user_data/hyperopts/ 下的自定义类) freqtrade list-hyperoptloss # 2. 用单列格式写入脚本变量,方便程序化处理 freqtrade list-hyperoptloss --one-column > available_losses.txt # 3. 运行超参优化并指定损失函数 freqtrade hyperopt --config config.json --hyperopt-loss SharpeHyperOptLossDaily \ --strategy MyWorkingStrategy --spaces roi stoploss trailing -e 1000

除命令行外,也可以在配置文件的"hyperopt_loss"键中指定(配置 schema 的校验同样引用HYPEROPT_LOSS_BUILTIN名单,见 freqtrade/config_schema/config_schema.py)。若在运行时两者都未指定,resolver 会抛出异常并列出全部内置函数名作为提示:

No Hyperopt loss set. Please use `--hyperopt-loss` to specify the Hyperopt-Loss class to use. Built-in Hyperopt-loss-functions are: ShortTradeDurHyperOptLoss, OnlyProfitHyperOptLoss, ...

(见 freqtrade/resolvers/hyperopt_resolver.py。)

自定义损失函数:让新类出现在列表中

要让自定义损失函数出现在list-hyperoptloss的输出里,需要满足三个条件,均与上文源码证据对应:

  1. 位置正确:文件放在<user_data>/hyperopts/下(默认即被扫描),或使用--hyperopt-path /path/to/dir加入额外查找路径;
  2. 类定义在本文件且直接继承IHyperOptLoss(resolver 要求obj.__module__ == module_name,从其他模块 import 进来再转述的类不会被收录);
  3. 实现静态方法hyperopt_loss_function(...),返回"越小越好"的 float。

骨架示例(基于仓库模板 freqtrade/templates/sample_hyperopt_loss.py):

from datetime import datetime from pandas import DataFrame from freqtrade.constants import Config from freqtrade.optimize.hyperopt_loss import IHyperOptLoss class MyCustomLoss(IHyperOptLoss): @staticmethod def hyperopt_loss_function( *, results: DataFrame, trade_count: int, min_date: datetime, max_date: datetime, config: Config, processed: dict[str, DataFrame], backtest_stats: dict[str, Any], starting_balance: float, **kwargs, ) -> float: # 基于 results / backtest_stats 计算你自己的目标值,越小越好 return 0.0

保存后执行freqtrade list-hyperoptloss,应能看到MyCustomLoss及其来源位置;之后即可用freqtrade hyperopt --hyperopt-loss MyCustomLoss ...运行。若加载失败(语法错误、缺依赖等),该条会显示为LOAD FAILED并打印失败原因,便于快速定位。更多自定义损失函数的完整写法参见 Advanced Hyperopt 文档。

常见问题小结

  • 输出为空或找不到我的自定义类?检查--userdir指向的目录下是否存在hyperopts/子目录,以及类是否直接定义在该目录的.py文件中而非被 import 转述;非默认位置请用--hyperopt-path
  • 输出重定向到文件乱码/带颜色码?--no-color;需要机器可读格式时用--one-column
  • 为什么list-hyperoptloss不要求--config该命令运行于UTIL_NO_EXCHANGE模式,只依赖本地文件系统;传入-c主要是为了让user_data等路径解析符合你的项目布局。
  • 内置函数会随版本变化吗?以 freqtrade/constants.py 中HYPEROPT_LOSS_BUILTIN的当前内容为准;命令 help 与--hyperopt-loss的帮助文本都直接引用该清单,二者始终一致。

小结

list-hyperoptloss虽是一条轻量的只读命令,却揭示了 Freqtrade 超参优化体系中"目标函数可插拔"的设计:HyperOptLossResolver按"额外路径 →user_data/hyperopts/→ 内置目录"的顺序扫描所有实现IHyperOptLoss的类,list-hyperoptloss负责把它们全部展示出来,hyperopt --hyperopt-loss则负责在优化时按名字加载。理解了这条链路,你就能自如地在 12 个内置损失函数与自研目标函数之间切换,为不同策略挑选最匹配的优化方向。

【免费下载链接】freqtradeFree, open source crypto trading bot项目地址: https://gitcode.com/GitHub_Trending/fr/freqtrade

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 10:08:27

从零实现DFT:MATLAB频谱分析工具箱的原理与工程实践

简介&#xff1a;DFTtoolbox 是一套以 Python 模块形式提供的开源 DFT 工具箱源代码&#xff0c;面向凝聚态物理与材料科学研究者&#xff0c;目标是让密度泛函理论&#xff08;DFT&#xff09;计算中的输入构建、批量分析与可视化更简单。它基于 numpy 与 matplotlib&#xff…

作者头像 李华
网站建设 2026/9/7 10:07:17

AI生成内容检测:隐形提示陷阱与学术诚信保护方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 10:01:24

CATIA V5与AI智能体结合:实现全自动三维建模的关键技术与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华