首页
/ Freqtrade new-config 命令详解:交互式生成交易所配置文件的完整原理与实践

Freqtrade new-config 命令详解:交互式生成交易所配置文件的完整原理与实践

2026-09-06 17:28:52作者:翟江哲Frasier

本篇围绕 Freqtrade 的 freqtrade new-config 命令展开,讲解如何通过一组交互式问答生成一份可运行的 config.json,并结合仓库源码剖析其命令注册、问答收集、Jinja2 模板渲染与文件写入的完整调用链。读完本文,你将掌握该命令的参数、每一项交互问题的作用与默认值、生成配置的结构组成,以及覆盖已存在文件等边界行为,从而独立完成从“零配置”到“可启动机器人”的第一步。

命令概览与 CLI 参数

new-config 是 Freqtrade 提供的配置生成子命令,官方文档页 docs/commands/new-config.md 给出了其命令行帮助输出:

usage: freqtrade new-config [-h] [-c PATH]

options:
  -h, --help         show this help message 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.

从源码可以确认该命令支持的参数非常精简。在 freqtrade/commands/arguments.py 中,子命令构建逻辑位于约 442 行处:

# add new-config subcommand
build_config_cmd = subparsers.add_parser(
    "new-config",
    help="Create new config",
)
build_config_cmd.set_defaults(func=start_new_config)
self._build_args(optionlist=ARGS_BUILD_CONFIG, parser=build_config_cmd)

其中 ARGS_BUILD_CONFIG = ["config"](同文件第 140 行),即该子命令仅挂载了 -c/--config 一个选项,用于指定要写入的新配置文件路径。若未指定,则按 Freqtrade 通用规则回退到 userdir/config.jsonconfig.json(取已存在者)。

执行流程:start_new_config 做了什么

子命令的处理函数是 freqtrade/commands/build_config_commands.py 中的 start_new_config

def start_new_config(args: dict[str, Any]) -> None:
    """
    Create a new strategy from a template
    Asking the user questions to fill out the template accordingly.
    """
    from freqtrade.configuration.deploy_config import (
        ask_user_config,
        ask_user_overwrite,
        deploy_new_config,
    )
    from freqtrade.configuration.directory_operations import chown_user_directory

    config_path = Path(args["config"][0])
    chown_user_directory(config_path.parent)
    if config_path.exists():
        overwrite = ask_user_overwrite(config_path)
        if overwrite:
            config_path.unlink()
        else:
            raise OperationalException(
                f"Configuration file `{config_path}` already exists. "
                "Please delete it or use a different configuration file name."
            )
    selections = ask_user_config()
    deploy_new_config(config_path, selections)

整体流程可归纳为四步:

  1. 确定目标路径:取 --config 的第一个值作为输出文件路径,并调用 chown_user_directory 调整所在目录属主(该函数在 freqtrade/configuration/directory_operations.py 中,主要用于 Docker 等容器场景下保证当前用户可写)。
  2. 覆盖确认:若目标文件已存在,则调用 ask_user_overwrite 弹出确认框;用户拒绝时抛出 OperationalException,提示删除该文件或改用其他文件名;用户同意则先删除旧文件再重建。
  3. 交互式问答ask_user_config() 收集全部配置选项,返回一个键值字典。
  4. 模板渲染与落盘deploy_new_config(config_path, selections) 将选项填入 Jinja2 模板并写入磁盘。

交互式问答:ask_user_config 的问题清单

问答逻辑集中在 freqtrade/configuration/deploy_config.pyask_user_config(),底层使用 questionary 库(支持 confirm/text/select/password/autocomplete 等题型)。问题按顺序如下,各项均有内置默认值:

问题字段 题型 含义与默认值
dry_run confirm 是否启用 Dry-run 模拟交易,默认 True
stake_currency text 计价货币,默认 USDT
stake_amount text 单笔投入金额(数字或 unlimited),默认 unlimited,并做浮点数校验
max_open_trades text 最大同时持仓数(整数,-1 表示不限制),默认 3
timeframe_in_config select 选择“由策略定义时间框架”还是“在配置中覆盖”
timeframe text 仅当上一项选择“在配置中覆盖”时出现,默认 5m
fiat_display_currency text 报表用的法币显示货币(留空可禁用法币换算),默认 USD
exchange_name select binancebinanceusbingxgatehtxkrakenkucoinokx 中选择,或选 other 后输入 ccxt 支持的任意交易所(autocomplete 题型给出 available_exchanges() 提示)
trading_mode confirm 是否交易永续合约(perpetual futures),默认 False;仅当交易所为 binancegateokxbybit 时才提问,答案会被过滤为 futures/spot
exchange_api_key / exchange_secret password 仅在关闭 dry_run 时提问
exchange_api_key_password password 仅当非 dry-run 且交易所为 kucoinokx 时提问
telegram / telegram_token / telegram_chat_id confirm + password 是否启用 Telegram 通知及凭据
api_server confirm 是否启用 REST API(含 FreqUI),默认 False
api_server_listen_addr text API 监听地址,Docker 内默认 0.0.0.0,否则默认 127.0.0.1(该默认值由 running_in_docker() 检测决定)
api_server_username / api_server_password text/password API 用户名默认 freqtrader,密码必填

问答结束后还有几个关键的后置处理(deploy_config.py):

answers = prompt(questions)

if not answers:
    # Interrupted questionary sessions return an empty dict.
    raise OperationalException("User interrupted interactive questions.")
# Ensure default is set for non-futures exchanges
answers["trading_mode"] = answers.get("trading_mode", "spot")
answers["margin_mode"] = "isolated" if answers.get("trading_mode") == "futures" else ""
# Force JWT token to be a random string
answers["api_server_jwt_key"] = secrets.token_hex()
answers["api_server_ws_token"] = secrets.token_urlsafe(25)
  • 用户在交互中直接退出(Ctrl-C 等)会返回空字典,此时命令以 OperationalException("User interrupted interactive questions.") 终止;
  • 非期货交易所统一补默认值 trading_mode = "spot"margin_mode = "";期货则默认 margin_mode = "isolated"(逐仓);
  • 自动生成随机密钥:无论是否启用 API,api_server_jwt_keysecrets.token_hex())与 api_server_ws_tokensecrets.token_urlsafe(25))都会被随机填充,保证每次生成的配置都有不可预测的鉴权凭据。

模板渲染:从选项到 JSON 文件

deploy_new_config() 是真正产出配置文件的函数(deploy_config.py):

def deploy_new_config(config_path: Path, selections: dict[str, Any]) -> None:
    from jinja2.exceptions import TemplateNotFound

    from freqtrade.exchange import MAP_EXCHANGE_CHILDCLASS
    from freqtrade.util import render_template

    try:
        exchange_template = MAP_EXCHANGE_CHILDCLASS.get(
            selections["exchange_name"], selections["exchange_name"]
        )

        selections["exchange"] = render_template(
            templatefile=f"subtemplates/exchange_{exchange_template}.j2", arguments=selections
        )
    except TemplateNotFound:
        selections["exchange"] = render_template(
            templatefile="subtemplates/exchange_generic.j2", arguments=selections
        )

    config_text = render_template(templatefile="base_config.json.j2", arguments=selections)

    logger.info(f"Writing config to `{config_path}`.")
    ...
    config_path.write_text(config_text)

其工作分两层:

  1. 交易所子模板:优先查找 freqtrade/templates/subtemplates/ 目录下与所选交易所对应的子模板(如 exchange_binance.j2exchange_kucoin.j2 等);若该交易所在 Freqtrade 中没有专属子类(MAP_EXCHANGE_CHILDCLASS 查不到或模板不存在),则回退到通用模板 exchange_generic.j2。以 exchange_binance.j2 为例,Binance 专属模板会额外预置 pair_blacklist: ["BNB/.*"],而通用模板的黑白名单为空数组:

    "exchange": {
        "name": "binance",
        "api_key": "...",
        "secret": "...",
        "ccxt_config": {},
        "ccxt_async_config": {},
        "pair_whitelist": [
        ],
        "pair_blacklist": [
            "BNB/.*"
        ]
    }
    
  2. 主模板:用问答结果渲染 freqtrade/templates/base_config.json.j2,生成最终 JSON。

生成配置的结构组成

以主模板为据,生成出的 config.json 至少包含以下段落({{ }} 为按问答填充的变量):

  • 顶层策略参数max_open_tradesstake_currencystake_amounttradable_balance_ratio(固定 0.99)、dry_rundry_run_wallet(固定 1000)、trading_modemargin_mode;仅当选择“在配置中覆盖时间框架”时才会写入 timeframe 字段;fiat_display_currency 为空时整行省略;
  • 订单与定价unfilledtimeout(entry/exit 均 10 分钟,单位 minutes)、entry_pricingexit_pricingprice_side: sameuse_order_book: trueorder_book_top: 1 等);
  • exchange 段:即上面子模板渲染结果;
  • pairlists:默认写入一个 VolumePairListnumber_assets: 20sort_key: quoteVolumerefresh_period: 1800),即按交易量挑选前 20 个资产;
  • telegramenabled 与 token/chat_id;
  • api_server:监听地址、listen_port 固定 8080、随机生成的 jwt_secret_keyws_token、用户名密码;
  • 其余bot_name: freqtradeinitial_state: runningforce_entry_enable: falseinternals.process_throttle_secs: 5
  • 文件首行引用了 $schemahttps://schema.freqtrade.io/schema.json),便于编辑器对配置做校验与补全。

测试用例验证的边界行为

单元测试 tests/commands/test_build_config.py 对上述实现做了逐项验证,可作为行为依据:

  • test_start_new_config:分别以 bybitbinancekraken 三个交易所为参数,模拟“文件已存在并确认覆盖”的场景,断言日志中出现 Writing config to ...write_text 只调用一次、旧文件被 unlink 一次,且渲染结果中 exchange.nameapi_keytimeframe 与输入一致;
  • test_start_new_config_exists:文件已存在但用户拒绝覆盖时,抛出匹配 Configuration .* already exists\.OperationalException
  • test_validate_is_int / test_validate_is_float:确认 max_open_trades 的整型校验("2.0""-ee" 均不通过)与 stake_amount 的浮点校验("2.0""-0.5" 通过,"-0.5e" 不通过);
  • test_ask_user_config:当 questionary 返回空字典(用户中断)时抛出 User interrupted interactive questions.

小结与后续步骤

new-config 的价值在于把一份易错的手工配置变成了“问答 + 模板”的确定性流程:交互式问答(ask_user_config)→ 交易所子模板选择(专属模板优先、通用模板兜底)→ 主模板渲染 → 写入目标路径,同时自动随机化 JWT 与 WebSocket 令牌、对中断和覆盖场景给出明确异常。生成配置后,日志会提示“Please make sure to check the configuration contents and adjust settings to your needs”,建议结合 配置参考文档 核对各字段,并可通过 freqtrade show-config 命令查看最终合并后的有效配置。完整字段语义可进一步对照 freqtrade/config_schema/ 中的配置校验逻辑阅读。

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