Freqtrade 数据可视化指南:使用 plot-dataframe 与 plot-profit 绘制价格、指标与收益
导读
plot-dataframe 与 plot-profit 是 Freqtrade 提供的两条交互式图表命令,前者用于将策略的 K 线、指标、买卖信号与真实成交叠加在同一张图上,后者用于把回测或实盘结果转化为收益曲线、回撤区间与并行度分析视图。本文以 docs/plotting.md 为骨架,结合 freqtrade/plot/plotting.py 的源码实现,完整讲解两条命令的参数语义、在策略中声明高级绘图配置的方法,以及输出的 HTML 文件中各类图元(买卖信号、成交标记、Bollinger 区间)的含义,帮助你定位策略问题、判断算法收益特征。
弃用提示(Deprecated):
plot-dataframe与plot-profit目前处于维护模式(maintenance mode)。官方给出的原因有两方面:一是中等规模的图也可能带来性能问题;二是“生成文件再用浏览器打开”这一交互方式本身不够直观。虽然短期内没有移除计划,但这两个命令不再被积极维护,若未来需重大改动以保持其可用,可能随时被移除。官方建议新项目直接使用 FreqUI 完成绘图需求,它不存在同类性能问题。阅读本文时应将该能力视为“沉淀已久的成熟辅助工具”,而非优先推荐的新方案。
安装绘图依赖
绘图模块依赖 Plotly 库。通过 requirements-plot.txt 安装或升级:
pip install -U -r requirements-plot.txt
从源码看,plotting.py 在模块顶部即尝试导入 plotly.graph_objects、plotly.offline.plot 与 plotly.subplots.make_subplots(见 freqtrade/plot/plotting.py 的 try/except ImportError 分支),若未安装 plotly 会在导入时打印提示并退出。因此两条绘图命令的依赖被刻意设计为可选,避免影响正常交易流程——freqtrade/commands/plot_commands.py 中两个命令的入口函数也都采用“函数内部延迟导入”策略,仅在真正执行绘图时才加载绘图依赖。
plot-dataframe:绘制价格与指标
freqtrade plot-dataframe 子命令生成一张包含三个子图的交互式 HTML 图:
- 主图:K 线(蜡烛图)与跟随价格的指标(如 SMA/EMA),同时叠加策略的买卖信号与真实成交标记;
- 成交量柱状图;
- 额外的指标子图,由
--indicators2指定。
生成的图文件以 freqtrade-plot-<pair>-<timeframe>.html 命名,存储在 user_data/plot/ 目录下(文件名生成逻辑见 generate_plot_filename)。注意:每条命令调用会为每个交易对生成一张独立的图文件。
常用参数
plot-dataframe 除常规全局参数(-c/--config、-d/--datadir、--userdir、-v/--verbose 等)与策略参数(-s/--strategy、--strategy-path、--recursive-strategy-search、--freqaimodel 等)外,专属选项如下:
| 参数 | 说明 |
|---|---|
-p, --pairs PAIRS [PAIRS ...] |
限定要绘制的交易对,多个交易对以空格分隔 |
--indicators1 INDICATORS1 [...] |
主图(第一行)中的指标,空格分隔。默认 ['sma', 'ema3', 'ema5'] |
--indicators2 INDICATORS2 [...] |
第三行子图中的指标,空格分隔。默认 ['macd', 'macdsignal'] |
--plot-limit INT |
绘制的 K 线数量上限。注意:过高的值会导致文件体积巨大。默认 750 |
--db-url PATH |
覆盖交易数据库 URL。Live 模式默认 sqlite:///tradesv3.sqlite,Dry Run 模式默认 sqlite:///tradesv3.dryrun.sqlite |
--trade-source {DB,file} |
交易来源:DB(数据库)或 file(回测结果文件)。默认 file |
--export {none,trades,signals} |
回测导出内容选项(默认 trades) |
--backtest-filename, --export-filename PATH |
指定回测结果文件。假设基础目录为 user_data/backtest_results/ 或 --export-directory 指定目录 |
--timerange TIMERANGE |
限定时间范围,格式 yyyymmdd 或 yyyymmddThhmm(如 20240101-20240201T1200) |
-i, --timeframe TIMEFRAME |
指定时间周期(1m、5m、30m、1h、1d 等) |
--no-trades |
不使用回测文件与数据库中的交易数据 |
上述选项的定义与默认值可直接在 freqtrade/commands/cli_options.py 的 indicators1、indicators2、plot_limit、no_trades、trade_source 等条目中验证。完整命令用法(usage 输出)见 docs/commands/plot-dataframe.md。
基础使用示例
最简调用(需要策略类名与交易对):
freqtrade plot-dataframe -p BTC/ETH --strategy AwesomeStrategy
-p/--pairs 用于指定要绘制的交易对。
自定义指标:--indicators1 对应主图指标;--indicators2 对应数值量纲与价格差异较大的子图指标(如 MACD):
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --indicators1 sma ema --indicators2 macd
命令参数会合并进绘图配置:当命令行提供了
--indicators1/--indicators2时,它们会覆盖策略中plot_config对应的main_plot/subplots(见 create_plotconfig 的实现与 tests/test_plotting.py 中test_create_plotconfig用例)。若两者都未提供,则回退到默认值sma/ema3/ema5与macd/macdsignal。
进一步使用场景
绘制多个交易对(空格分隔):
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH XRP/ETH
限定时间范围以放大局部细节:
freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --timerange=20180801-20180805
使用数据库中的真实成交记录绘图(--db-url 需搭配 --trade-source DB):
freqtrade plot-dataframe --strategy AwesomeStrategy --db-url sqlite:///tradesv3.dry_run.sqlite -p BTC/ETH --trade-source DB
使用回测结果文件绘图(默认 --trade-source file):
freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/backtest_results/backtest-result.json -p BTC/ETH
图表元素的语义
plot-dataframe 需要回测数据(OHLCV)、一个策略,以及(可选)与该策略匹配的成交来源——回测结果文件或数据库。最终主图包含以下图元(plot_trades 与 generate_candlestick_graph 中的实现均一一对应):
| 图元 | 含义 | 源码实现 |
|---|---|---|
| 绿色三角(向上) | 策略的买入信号(enter signal)。注意并非每个买入信号都会真正成交,请与青色圆圈对比 | create_scatter(data, "enter_long", "green", "up") |
| 红色三角(向下) | 策略的卖出/退出信号(exit signal)。同样并非每个退出信号都会终结一笔交易,请与红/绿方块对比 | create_scatter(data, "exit_long", "red", "down") |
| 青色圆圈 | 交易的入场点(实际成交 entry) | trade_entries:marker.color=cyan、symbol=circle-open |
| 红色方块 | 亏损或零收益交易的出场点 | trade_exits_loss:profit_ratio <= 0 时红色 |
| 绿色方块 | 盈利交易的出场点 | trade_exits:profit_ratio > 0 时绿色 |
| 主图指标 | 与价格同量纲的指标(SMA/EMA),由 --indicators1 指定 |
见 add_indicators |
| 成交量柱 | 主图底部的成交量柱状图 | go.Bar 固定放置在第二行 |
| 子图指标 | 量纲不同的指标(MACD、RSI 等)绘制在成交量下方,由 --indicators2 指定 |
每个子图占据独立行 |
此外,Hover 悬停文本会汇总每笔交易的关键信息,包括 profit_ratio(收益率百分比)、enter_tag(入场标签)、exit_reason(退出原因)与 trade_duration(持仓分钟数),便于快速排查。
下图给出了带指标与成交标记的典型效果:
Bollinger Bands 自动绘制:只要策略 DataFrame 中存在
bb_lowerband与bb_upperband两列,绘图器就会自动以浅蓝色区域填充下轨至上轨之间的区域(见 plot_area,默认填充色rgba(0,176,246,0.2)),无需在--indicators1中显式声明。事实上generate_candlestick_graph会在填充后尝试把这两个列从主图配置中剔除,避免重复绘制。
交易持仓调整(position adjustments)注意:若策略启用了
position_adjustment_enable/adjust_trade_position(),由于多次加仓会对初始买入价做平均,成交的开始价格很可能落在蜡烛区间之外,这是正常现象。
高级绘图配置:策略内 plot_config
基础指标绘制之外,plot_config 支持三类进阶能力:
- 为每个指标指定固定颜色(避免不同次绘图因随机配色不同而难以对比);
- 指定多个额外子图(例如同时展示 MACD 与 RSI);
- 指定指标对,并在两者之间填充区域。
plot_config 在 IStrategy 基类 中被声明为类级属性 plot_config: dict = {},建议以 @property 形式在策略中覆写。支持的类型有 scatter(散点/折线,默认)与 bar(柱状)。plotly 字典中的额外参数会透传给 plotly.graph_objects.* 构造函数——仅在 Plotly 库中生效,在 freq-ui 中会被忽略。
完整示例(可直接放入策略类):
@property
def plot_config(self):
"""
构建返回字典的方式有很多种。
唯一关键点是返回值本身。
例如:
plot_config = {'main_plot': {}, 'subplots': {}}
"""
plot_config = {}
plot_config['main_plot'] = {
# 主图指标配置。
# 假设策略中定义了 emashort 和 emalong 两个参数。
f'ema_{self.emashort.value}': {'color': 'red'},
f'ema_{self.emalong.value}': {'color': '#CCCCCC'},
# 不指定 color 时,系统随机选择一种颜色。
'sar': {},
# 在 senkou_a 与 senkou_b 之间填充区域
'senkou_a': {
'color': 'green', # 可选
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud', # 可选
'fill_color': 'rgba(255,76,46,0.2)', # 可选
},
# 也绘制 senkou_b 本身,而不只是填充到它的区域
'senkou_b': {}
}
plot_config['subplots'] = {
# 创建 MACD 子图
"MACD": {
'macd': {'color': 'blue', 'fill_to': 'macdhist'},
'macdsignal': {'color': 'orange'},
'macdhist': {'type': 'bar', 'plotly': {'opacity': 0.9}}
},
# 额外 RSI 子图
"RSI": {
'rsi': {'color': 'red'}
}
}
return plot_config
上述配置隐含的前提是:ema10、ema50、senkou_a、senkou_b、macd、macdsignal、macdhist、rsi 都是策略 DataFrame 中实际存在的列。源码会在渲染前逐一校验列名:不存在的指标会被记录日志并跳过,fill_to 目标列缺失时同样被跳过(见 add_indicators 与 add_areas)。freqtrade 自带的“full”策略模板同样使用了该配置模式,可参考 freqtrade/templates/strategy_subtemplates/plot_config_full.j2(其中将 tema、sar 画在主图,将 MACD、RSI 拆成两个子图)。
作为普通属性声明(历史写法)
plot_config 也可以直接作为类属性(attribute)赋值,这是旧版本默认写法。缺点在于:属性赋值时机早于策略参数实例化,无法引用 self.ema_long.value 这类策略参数,因而限制了部分动态配置能力:
plot_config = {
'main_plot': {
# 主图指标配置:指定 ema10 为红色,ema50 为灰色调
'ema10': {'color': 'red'},
'ema50': {'color': '#CCCCCC'},
# 不指定 color 时,系统随机选择一种颜色。
'sar': {},
# 在 senkou_a 与 senkou_b 之间填充区域
'senkou_a': {
'color': 'green', # 可选
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud', # 可选
'fill_color': 'rgba(255,76,46,0.2)', # 可选
},
# 也绘制 senkou_b 本身,而不只是填充到它的区域
'senkou_b': {}
},
'subplots': {
# 创建 MACD 子图
"MACD": {
'macd': {'color': 'blue', 'fill_to': 'macdhist'},
'macdsignal': {'color': 'orange'},
'macdhist': {'type': 'bar', 'plotly': {'opacity': 0.9}}
},
# 额外 RSI 子图
"RSI": {
'rsi': {'color': 'red'}
}
}
}
再次强调:
plotly参数仅在使用 Plotly 绘图库时生效,不适用于 freq-ui。
从源码层面看,绘图时配置的合并顺序为:命令行 --indicators1/--indicators2 > 策略 plot_config 中同名字段 > 内置默认值,绘制入口 load_and_plot_trades 依次完成策略加载、bot_loop_start() 钩子触发、K 线分析与逐交易对出图。图的实际行数由 2 + subplots 数量 决定——第一行价格主图、第二行固定成交量、其余行依次为各子图。
plot-profit:绘制收益、回撤与并行度
freqtrade plot-profit 生成包含六个子面板的收益分析图(底层由 generate_profit_graph 一次性构造 6 行子图,行高比例约为 1:1:1:0.5:0.75:0.75):
- 全部交易对的平均收盘价——用来判断整体市场走势(“行情本身在涨还是在跌”)。
- 回测汇总收益(Combined Profit)——注意这并非真实世界收益,而是更接近“估算值”。该图用于判断算法是否有效:是追求稳定的小额盈利,还是低频次、大幅波动的盈利模式;同时会用绿色空心方块标出 最大回撤区间(Max drawdown)的起点与终点,Hover 上会直接给出相对账户回撤百分比。
- 每个交易对各自的收益——便于发现“异常点”,即某个交易对在某个时间段引发的收益尖峰。
- 交易并行度(Parallelism)——展示同一时刻同时持仓的交易数量,帮助你判断
max_open_trades是否经常被触顶。 - 水下曲线(Underwater Plot,绝对回撤):以红色填充表示净值相对峰值的回撤深度。
- 相对回撤百分比(Relative Drawdown):以绿色填充、按百分比刻度展示回撤幅度。
上述面板在 generate_profit_graph 中均有对应实现:add_max_drawdown 依赖 freqtrade/data/metrics.py 的 calculate_max_drawdown;add_underwater 依赖 calculate_underwater;add_parallelism 则调用 freqtrade/data/btanalysis.py 的 analyze_trade_parallelism 统计各时点开仓数量。若所选时间范围内没有成交数据,对应的绘图函数会记录警告并跳过相应面板。
plot-profit 的专属参数如下(全局/策略参数同前,完整 usage 见 docs/commands/plot-profit.md):
| 参数 | 说明 |
|---|---|
-p, --pairs PAIRS [...] |
限定参与计算的交易对,空格分隔 |
--timerange TIMERANGE |
限定时间范围 |
--export {none,trades,signals} |
回测导出选项(默认 trades) |
--backtest-filename, --export-filename PATH |
指定回测结果文件 |
--db-url PATH |
交易数据库 URL(Live:tradesv3.sqlite;Dry Run:tradesv3.dryrun.sqlite) |
--trade-source {DB,file} |
交易来源,默认 file |
-i, --timeframe TIMEFRAME |
指定时间周期(必须能在配置或命令行中解析出,否则 plot_profit 会抛出 OperationalException,见 freqtrade/plot/plotting.py) |
--auto-open |
生成后自动在浏览器中打开图表 |
注意两条命令都要求至少给出 --datadir 或 --config 之一,否则入口校验会抛出 ConfigurationError(见 freqtrade/commands/plot_commands.py 的 validate_plot_args)。
使用示例
使用自定义回测导出文件:
freqtrade plot-profit -p LTC/BTC --export-filename user_data/backtest_results/backtest-result.json
使用自定义数据库:
freqtrade plot-profit -p LTC/BTC --db-url sqlite:///tradesv3.sqlite --trade-source DB
指定数据目录(例如按交易所保存的 binance_save 数据):
freqtrade --datadir user_data/data/binance_save/ plot-profit -p LTC/BTC
生成的收益图统一保存为 freqtrade-profit-plot.html,位于 user_data/plot/ 目录下(是否自动打开取决于 --auto-open 或配置项 plot_auto_open)。若所选交易对或时间范围内没有任何已平仓交易,绘图程序会直接报错终止——因为“未平仓交易还无法计算收益”,同时源码也会过滤掉未平仓(close_date 为空)的交易。
从源码看两条命令的执行链路
两条命令共享同一套基础设施(freqtrade/commands/plot_commands.py):
validate_plot_args校验数据源参数是否齐全;setup_utils_configuration(args, RunMode.PLOT)构建绘图专用配置对象;plot-dataframe进入load_and_plot_trades:加载策略与交易所 → 构造DataProvider→ 调用策略钩子 →init_plotscript按交易对加载 OHLCV 与成交数据并裁剪到所选时间范围 → 逐对运行strategy.analyze_ticker()生成带指标/信号列的 DataFrame →generate_candlestick_graph构造图表 → 保存到user_data/plot/;plot-profit进入plot_profit:加载交易(来源可为回测文件或 DB)→ 过滤出目标交易对中的已平仓交易 → 计算累计收益、回撤与并行度 → 渲染六面板 HTML 并落盘。
init_plotscript 会利用 expand_pairlist 展开交易对列表,并通过 freqtrade/configuration/timerange.py 的 TimeRange.parse_timerange 解析 --timerange;--plot-limit 则会限制参与绘制的蜡烛数量,以控制生成文件的体积。对应测试覆盖了从参数校验、指标/区域叠加到无成交报错等各分支,可在 tests/test_plotting.py 中查看(如 test_create_plotconfig、test_generate_candlestick_graph_no_signals_no_trades、test_start_plot_profit_error)。
小结与迁移建议
- 价格/指标/K 线图用
freqtrade plot-dataframe,其图元(信号三角、成交圆/方块、Bollinger 区域)语义已在文中逐一给出,适合对单策略、单交易对做微观复盘; - 收益/回撤/并行度分析用
freqtrade plot-profit,六个面板自上而下覆盖“市场走势 → 整体收益 → 分交易对收益 → 并行度 → 绝对/相对水下曲线”,适合判断算法的宏观收益形态; - 两者生成的均为
user_data/plot/下的自包含 HTML 文件(每交易对一图或单张收益总图),可直接用浏览器打开并交互缩放; - 若追求更流畅的交互体验、支持实时更新且不依赖本地文件,请改用官方推荐的 FreqUI;它与本文所述 Plotly 命令共用同一套“策略产生 DataFrame 指标列”的约定,因此策略中通过
plot_config声明指标与配色的思路仍然具有参考价值。
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 StartedRust0627
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


