首页
/ freqtrade list-timeframes:查询交易所支持的 K 线周期(Timeframe)并理解其底层校验机制

freqtrade list-timeframes:查询交易所支持的 K 线周期(Timeframe)并理解其底层校验机制

2026-09-06 15:56:49作者:裘旻烁

list-timeframes 是 freqtrade 提供的命令行工具,用于打印指定交易所当前支持的全部 K 线周期(timeframe),是编写策略、下载数据前确认 timeframe 取值是否合法的直接手段。本篇完整收录该命令的用法与参数说明,并结合 list_commands.pyexchange.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.pyNO_CONF_REQURIED 白名单中(见 arguments.py#L281-L302),即不强制要求提供配置文件——可以通过 --exchange 直接指定交易所运行;
  • 该子命令注册的选项集为 ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column", "trading_mode"](见 arguments.py#L114),与帮助输出一致;
  • --trading-mode 的可选值来自 constants.TRADING_MODES,即 spotmarginfutures 三者(定义见 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 exchangeOperationalException——这一点在 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)}"
        )

从这段实现可以确认三个行为:

  1. RunMode.UTIL_EXCHANGE 模式初始化配置,只加载交易所定义所需的最小配置,不启动交易逻辑;
  2. 显式把 config["timeframe"] 置为 None(注释写明 "Do not use timeframe set in the config")。也就是说,即使配置文件里写了 timeframe,它既不会被校验、也不会影响输出——本命令只关心"交易所支持什么",而不关心"你的配置写了什么";
  3. 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 同时提供 spot1m, 5m, 15m)与 swap1m, 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}"
        )

校验分两层:

  1. 若 ccxt 对该交易所根本不提供 timeframes(通常意味着不支持 fetchOHLCV),抛出 OperationalException,直接判定交易所不受支持;
  2. 若配置中的 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 输出每行一个周期,可直接用 grepcut 等工具筛选,例如判断某个策略周期是否可用:freqtrade list-timeframes --exchange binance -1 | grep -x '4h'

相关文档入口:docs/commands/list-timeframes.mddocs/utils.md、命令总览 docs/commands/main.md

登录后查看全文
热门项目推荐
相关项目推荐