Freqtrade 新人完整上手教程(2025.12 版|Docker|已验证)
适用人群:
- 完全没接触过 Freqtrade
- 或者之前各种 network / ccxt / python 环境问题
- 想一次就跑通回测闭环
一、准备条件(只需要这 3 个)
- macOS / Linux / Windows(推荐 macOS / Linux)
- Docker Desktop 已安装并启动
- 能正常访问 Binance(不用代理)
⚠️ 本教程 不使用本机 Python 跑 freqtrade
所有 freqtrade 相关操作 全部在 Docker 里完成
二、启动 Docker(很多人卡在这里)
1️⃣ 启动 Docker Desktop
- 打开 Docker Desktop App
- 等右上角 🐳 显示 Running
2️⃣ 验证 Docker daemon 正常
bash
docker info
能输出一大堆信息即可。
三、拉取 Freqtrade 官方镜像(一次性)
bash
docker pull freqtradeorg/freqtrade:stable
看到 Downloaded newer image 即成功。
四、创建项目目录
bash
mkdir -p ~/freqtrade-demo
cd ~/freqtrade-demo
mkdir -p user_data
最终结构:
freqtrade-demo/
└── user_data/
五、初始化 user_data(官方标准步骤)
bash
docker run --rm -it \
-v $(pwd)/user_data:/freqtrade/user_data \
freqtradeorg/freqtrade:stable \
create-userdir --userdir user_data
成功后本地应出现:
user_data/
├── data/
├── logs/
└── strategies/
六、写一份【最小可用】config.json(⚠️ 关键)
这是 2025.12 版本必须能跑回测的配置
已考虑
entry_pricing / exit_pricing的新校验规则
user_data/config.json
json
{
"$schema": "https://schema.freqtrade.io/schema.json",
"max_open_trades": 1,
"stake_currency": "USDT",
"stake_amount": 100,
"tradable_balance_ratio": 0.99,
"fiat_display_currency": "USD",
"timeframe": "5m",
"dry_run": true,
"trading_mode": "spot",
"entry_pricing": {
"price_side": "same",
"use_order_book": false
},
"exit_pricing": {
"price_side": "same",
"use_order_book": false
},
"exchange": {
"name": "binance",
"key": "",
"secret": "",
"ccxt_config": {
"enableRateLimit": true
},
"ccxt_async_config": {
"enableRateLimit": true
},
"pair_whitelist": [
"BTC/USDT"
],
"pair_blacklist": []
},
"pairlists": [
{ "method": "StaticPairList" }
],
"bot_name": "freqtrade",
"initial_state": "stopped",
"internals": {
"process_throttle_secs": 5
}
}
重要说明(新人必读)
- 不要用 futures
- 不要用 VolumePairList
- 不要启用 order_book
- 否则很容易卡在 exchangeInfo / markets 加载
七、下载历史数据(生成 feather 文件)
bash
docker run --rm -it \
-v $(pwd)/user_data:/freqtrade/user_data \
freqtradeorg/freqtrade:stable \
download-data \
--exchange binance \
--pairs BTC/USDT \
--timeframes 5m
成功后你会看到:
user_data/data/binance/BTC_USDT-5m.feather
这一步说明:
数据层已经完全 OK
八、生成第一个策略(使用新版模板)
⚠️ 新版 没有 basic 模板
bash
docker run --rm -it \
-v $(pwd)/user_data:/freqtrade/user_data \
freqtradeorg/freqtrade:stable \
new-strategy \
--strategy MyFirstStrategy \
--template minimal \
--userdir user_data
生成文件:
user_data/strategies/MyFirstStrategy.py
九、写一个"最简单但能交易"的策略
打开 user_data/strategies/MyFirstStrategy.py,改成如下核心逻辑:
python
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
class MyFirstStrategy(IStrategy):
timeframe = "5m"
minimal_roi = {
"0": 0.1
}
stoploss = -0.1
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe["ma20"] = ta.SMA(dataframe["close"], timeperiod=20)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["close"] > dataframe["ma20"]),
"enter_long",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe["close"] < dataframe["ma20"]),
"exit_long",
] = 1
return dataframe
这是一个教学用策略 :
均线之上买,跌破均线卖
目的不是赚钱,而是验证系统
十、运行回测(🎯 教程最终目标)
bash
docker run --rm -it \
-v $(pwd)/user_data:/freqtrade/user_data \
freqtradeorg/freqtrade:stable \
backtesting \
--config user_data/config.json \
--strategy MyFirstStrategy
十一、成功标志(非常重要)

知识补充
在上面的测试代码中,我们没有明确制定数据,只是写了一个策略, 那么我们是如何跑出来数据的呢?也就是回测结果?
MyFirstStrategy并没有"自己去拿数据"👉 它使用的是 freqtrade 回测引擎自动加载的历史 K 线数据
👉 数据来源是你之前用
download-data下载到本地的
user_data/data/binance/BTC_USDT-5m.feather
策略代码本身 = 完全不知道数据从哪来
这是一个非常关键、非常工程化的设计。
我们把"数据从哪来"按顺序拆开
下面这 6 步,就是你刚才那次回测真实发生的事情。
第 1 步:你运行了 backtesting 命令
bash
docker run ... freqtrade backtesting \
--config user_data/config.json \
--strategy MyFirstStrategy
👉 这一步你明确指定了两样东西:
- 用哪个 配置
- 用哪个 策略
你没有指定数据文件,这是"刻意设计的"。
第 2 步:freqtrade 读取 config.json(这是数据入口)
在你的 config.json 里,有这几项(非常关键):
json
"timeframe": "5m",
"exchange": {
"name": "binance",
"pair_whitelist": [
"BTC/USDT"
]
}
这三条信息合在一起,就已经唯一确定了数据集:
Binance 交易所
BTC/USDT
5 分钟 K 线
第 3 步:回测引擎自动映射到本地数据目录
Freqtrade 内部逻辑(简化版)是:
text
exchange = binance
pair = BTC/USDT
timeframe= 5m
↓
去本地找:
user_data/data/binance/BTC_USDT-5m.feather
👉 这一步是自动的,不需要你写任何代码。
只要这个文件存在:
- 不访问交易所
- 不联网
- 回测是 100% 本地的
第 4 步:feather → pandas DataFrame
回测引擎内部会做这件事(伪代码):
python
df = pd.read_feather("BTC_USDT-5m.feather")
这就是你之前手动读出来看到的那张表:
date | open | high | low | close | volume
第 5 步:把 DataFrame 交给你的策略
现在重点来了。
你的策略里写的是:
python
def populate_indicators(self, dataframe, metadata):
注意这个参数名:
python
dataframe
👉 这个 dataframe 就是刚才那张历史 K 线表。
策略函数的真实调用过程是:
text
回测引擎
↓
for 每个交易对(BTC/USDT)
↓
把历史 K 线 DataFrame
↓
传给 MyFirstStrategy.populate_xxx()
第 6 步:你的策略只是"在这张表上打标记"
你在策略里做的事,本质是:
python
dataframe["ma20"] = ...
dataframe.loc[条件, "enter_long"] = 1
dataframe.loc[条件, "exit_long"] = 1
你没有拉数据
你没有指定文件
你没有写 IO
你只是:
在 freqtrade 提供的历史数据上
写"如果这样,就买 / 卖"
那为什么它能跑出"真实的亏损"?
因为这一切都是真实发生的:
| 项目 | 是否真实 |
|---|---|
| K 线数据 | ✅ 来自 Binance |
| 时间顺序 | ✅ 严格按时间 |
| 买卖逻辑 | ✅ 你亲手写的 |
| 资金变化 | ✅ 模拟撮合 |
| 回测统计 | ✅ 实际计算 |
👉 所以结果是 真实逻辑 + 真实历史 = 真实回测结果。
一个非常重要的"设计哲学"(你已经踩到核心了)
freqtrade = 策略与数据彻底解耦
这意味着:
-
策略作者 不关心数据从哪来
-
数据来源:
- 回测:本地 feather
- 实盘:交易所实时行情
-
策略代码 一行都不用改
这也是为什么你可以:
同一份策略
→ 回测
→ dry-run
→ 实盘
回答你最核心的那句话(直接回答)
"我也没看见我们指定数据啊"
答案是:
你在
config.json里已经"隐式指定了"数据集:
- 交易所:binance
- 交易对:BTC/USDT
- 周期:5m
freqtrade 自动帮你把它映射到本地的
.feather数据文件。