freqtrade list-timeframes:查询交易所支持的 K 线周期(Timeframe)并理解其底层校验机制
list-timeframes 是 freqtrade 提供的命令行工具,用于打印指定交易所当前支持的全部 K 线周期(timeframe),是编写策略、下载数据前确认 timeframe 取值是否合法的直接手段。本篇完整收录该命令的用法与参数说明,并结合 list_commands.py 与 exchange.py 的源码实现,讲清楚 spot / futures 两种交易模式下周期列表的差异来源,以及配置中 timeframe 不合法时 freqtrade 如何报错,帮助你把「查询 → 选型 → 校验」这条链路走通。
命令总览与完整用法
list-timeframes 的官方帮助输出如下(来自 docs/commands/list-timeframes.md,该文件由 create_command_partials.py 从命令实际帮助信息生成):
usage: freqtrade list-timeframes [-h] [-v] [--no-color] [--logfile FILE] [-V]
[-c PATH] [-d PATH] [--userdir PATH]
[--exchange EXCHANGE] [-1]
[--trading-mode {spot,margin,futures}]
options:
-h, --help show this help message and exit
--exchange EXCHANGE Exchange name. Only valid if no config is provided.
-1, --one-column Print output in one column.
--trading-mode, --tradingmode {spot,margin,futures}
Select Trading mode
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.
要点归纳:
- 子命令参数只有三个:
--exchange(交易所名称)、-1/--one-column(单列输出,便于脚本解析)、--trading-mode(选择 spot / margin / futures 交易模式); - 命令在 arguments.py 的
NO_CONF_REQURIED白名单中(见 arguments.py#L281-L302),即不强制要求提供配置文件——可以通过--exchange直接指定交易所运行; - 该子命令注册的选项集为
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column", "trading_mode"](见 arguments.py#L114),与帮助输出一致; --trading-mode的可选值来自constants.TRADING_MODES,即spot、margin、futures三者(定义见 cli_options.py#L441-L446),--tradingmode是它的别名。
基本用法示例
参考 docs/utils.md#L207-L224 中的示例,典型用法有两种:
示例 1:基于配置文件查询(exchange 取自配置)
$ freqtrade list-timeframes -c config_binance.json
...
Timeframes available for the exchange `binance`: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
示例 2:不依赖配置文件,直接指定交易所
$ freqtrade list-timeframes --exchange binance
示例 3:批量枚举所有可用交易所的周期(结合 list-exchanges -1 的单列输出做循环):
$ for i in `freqtrade list-exchanges -1`; do freqtrade list-timeframes --exchange $i; done
示例 4:单列输出,方便管道处理
$ freqtrade list-timeframes --exchange binance --one-column
1m
3m
5m
...
注意 --exchange 与配置文件的关系:帮助文本明确写着 "Only valid if no config is provided"。当未提供 -c/--config 时,--exchange 是必填项,否则命令会抛出 This command requires a configured exchange 的 OperationalException——这一点在 tests/commands/test_commands.py#L229-L237 中有对应的测试断言。
源码实现:周期列表从哪里来
命令的入口函数是 start_list_timeframes,位于 list_commands.py#L222-L242:
def start_list_timeframes(args: dict[str, Any]) -> None:
"""
Print timeframes available on Exchange
"""
from freqtrade.configuration import setup_utils_configuration
from freqtrade.resolvers import ExchangeResolver
config = setup_utils_configuration(args, RunMode.UTIL_EXCHANGE)
# Do not use timeframe set in the config
config["timeframe"] = None
# Init exchange
exchange = ExchangeResolver.load_exchange(config, validate=False)
if args["print_one_column"]:
print("\n".join(exchange.timeframes))
else:
print(
f"Timeframes available for the exchange `{exchange.name}`: "
f"{', '.join(exchange.timeframes)}"
)
从这段实现可以确认三个行为:
- 以
RunMode.UTIL_EXCHANGE模式初始化配置,只加载交易所定义所需的最小配置,不启动交易逻辑; - 显式把
config["timeframe"]置为None(注释写明 "Do not use timeframe set in the config")。也就是说,即使配置文件里写了timeframe,它既不会被校验、也不会影响输出——本命令只关心"交易所支持什么",而不关心"你的配置写了什么"; - 以
validate=False加载交易所,跳过对配置合法性的整体校验,然后统一通过Exchange类的timeframes属性取数。
timeframes 属性是 exchange.py#L456-L465 中的一个 property,它的取值逻辑解释了 --trading-mode 参数的意义:
@property
def timeframes(self) -> list[str]:
market_type = (
"spot"
if self.trading_mode != TradingMode.FUTURES
else self._ft_has["ccxt_futures_name"]
)
timeframes = self._api.options.get("timeframes", {}).get(market_type)
if timeframes is None:
timeframes = self._api.timeframes
return list((timeframes or {}).keys())
可以推断其工作方式为:
- spot / margin 模式:
market_type固定为"spot",优先从 ccxt 交易所实例的options["timeframes"]["spot"]读取周期字典; - futures 模式:
market_type切换为 ccxt 中该交易所合约端的名称(ccxt_futures_name,例如不同交易所的 USDT 本位合约端点),从而读取options["timeframes"]中对应合约端的周期字典——这就是为什么合约端的周期列表常常与现货不同; - 如果交易所没有提供
options["timeframes"]分类字典,则回退到 ccxt 实例的顶层timeframes属性,并取其 keys 作为结果。
测试用例 tests/commands/test_commands.py#L316-L360 完整验证了上述分支:当 mock 的 api_mock.options 同时提供 spot(1m, 5m, 15m)与 swap(1m, 15m, 1h)两组周期时,--trading-mode spot 输出 1m, 5m, 15m,而 --trading-mode futures 输出 1m, 15m, 1h。该测试同时覆盖了 --config 与 --exchange 两种入口、以及 --one-column 的逐行输出格式。
与配置校验的关系:timeframe 不合法会怎样
list-timeframes 本身不校验任何配置,但你在配置文件中填写的 timeframe 会在 bot 启动时被 Exchange.validate_timeframes 校验,见 exchange.py#L790-L807:
def validate_timeframes(self, timeframe: str | None) -> None:
"""
Check if timeframe from config is a supported timeframe on the exchange
"""
if not hasattr(self._api, "timeframes") or self._api.timeframes is None:
# If timeframes attribute is missing (or is None), the exchange probably
# has no fetchOHLCV method.
raise OperationalException(
f"The ccxt library does not provide the list of timeframes "
f"for the exchange {self.name} and this exchange "
f"is therefore not supported. ccxt fetchOHLCV: {self.exchange_has('fetchOHLCV')}"
)
if timeframe and (timeframe not in self.timeframes):
raise ConfigurationError(
f"Invalid timeframe '{timeframe}'. This exchange supports: {self.timeframes}"
)
校验分两层:
- 若 ccxt 对该交易所根本不提供
timeframes(通常意味着不支持fetchOHLCV),抛出OperationalException,直接判定交易所不受支持; - 若配置中的
timeframe不在交易所支持列表中,抛出ConfigurationError,错误信息会列出全部合法取值——list-timeframes的输出正是这串合法取值的"预览"。
因此推荐的工作流是:先用 freqtrade list-timeframes --exchange <交易所>(futures 场景加 --trading-mode futures)确认周期,再把它写进配置的 timeframe 字段,避免因笔误导致启动失败。
实用提示与适用前提
- 无需 API 密钥:该命令属于
RunMode.UTIL_EXCHANGE工具类命令,只需交易所公共数据,不需要在配置中提供交易 API key; - futures 数据路径:帮助文本中
-d/--datadir的说明指出 "To see futures data, use trading-mode additionally",即查看合约相关数据文件时需配合--trading-mode futures使用,这与本文讲到的 spot / futures 周期分流逻辑一致; - 输出随 ccxt 与交易所变化:周期列表来自 ccxt 库对应交易所实现,随交易所调整与 ccxt 版本升级而变化,实际输出以
list-timeframes当场结果为准,不要依赖记忆中的旧列表; - 脚本集成:
--one-column输出每行一个周期,可直接用grep、cut等工具筛选,例如判断某个策略周期是否可用:freqtrade list-timeframes --exchange binance -1 | grep -x '4h'。
相关文档入口:docs/commands/list-timeframes.md、docs/utils.md、命令总览 docs/commands/main.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