Skip to content

策略分析示例

调试策略可能会耗费大量时间。Freqtrade提供了用于可视化原始数据的辅助函数。 以下假设您正在使用SampleStrategy策略,来自币安的5分钟时间框架的数据,并将它们下载到默认位置的data目录中。 有关更多详细信息,请参阅文档

设置

将工作目录更改为存储库根目录

import os
from pathlib import Path

# 更改目录
# 修改此单元格以确保输出显示正确的路径。
# 将所有路径定义为相对于单元格输出中显示的项目根的路径
project_root = "somedir/freqtrade"
i=0
try:
    os.chdir(project_root)
    assert Path('LICENSE').is_file()
except:
    while i<4 and (not Path('LICENSE').is_file()):
        os.chdir(Path(Path.cwd(), '../'))
        i+=1
    project_root = Path.cwd()
print(Path.cwd())

配置 Freqtrade 环境

from freqtrade.configuration import Configuration

# 根据您的需要进行自定义设置。

# 初始化空配置对象
config = Configuration.from_files([])
# 可选地(建议),使用现有的配置文件
# config = Configuration.from_files(["user_data/config.json"])# 定义一些常数
config["timeframe"] = "5m"
# 策略类的名称
config["strategy"] = "SampleStrategy"
# 数据的位置
data_location = config["datadir"]
# 要分析的交易对 - 只使用一个交易对
pair = "BTC/USDT"
# 使用上述设置的值加载数据
from freqtrade.data.history import load_pair_history
from freqtrade.enums import CandleType

candles = load_pair_history(datadir=data_location,
                            timeframe=config["timeframe"],
                            pair=pair,
                            data_format="json",  # 请确保将此项更新为您的数据格式
                            candle_type=CandleType.SPOT,
                            )

# 确认加载成功
print(f"从{data_location}中加载了{len(candles)}{pair}的数据")
candles.head()

加载并运行策略

  • 每当策略文件发生更改时重新运行
# 使用上述设置的值加载策略
from freqtrade.resolvers import StrategyResolver
from freqtrade.data.dataprovider import DataProvider
strategy = StrategyResolver.load_strategy(config)
strategy.dp = DataProvider(config, None, None)
strategy.ft_bot_start()

# 使用策略生成买入/卖出信号
df = strategy.analyze_ticker(candles, {'pair': pair})
df.tail()

显示交易细节

  • 注意,也可以使用data.head(),但是大多数技术指标在数据框的顶部有一些"启动"数据。
  • 可能会遇到的一些问题 * 数据框末尾具有NaN值的列 * 在crossed*()函数中使用具有完全不同单位的列
  • 与完整回测的比较 * 从analyze_ticker()中获得一个交易对的200个买入信号,并不意味着在回测过程中将进行200笔交易。 * 假设您只使用一个条件,例如,df['rsi'] < 30作为买入条件,这将为每个交易对生成多个连续的"买入"信号(直到rsi返回> 29)。机器人只会在第一个信号上买入(并且只有当交易槽("max_open_trades")仍然可用时),或者在中间信号中的一个信号上买入,一旦有一个"槽"可用为止。
# 报告结果
print(f"已生成{df['enter_long'].sum()}个入场信号")
data = df.set_index('date', drop=False)
data.tail()

将现有对象加载到Jupyter笔记本中

以下部分假设您已经使用CLI生成了数据。
它们将允许您深入分析您的结果,并执行其他方式下会导致信息过载的分析。

加载回测结果到pandas数据框架中

分析交易数据框架(下面的绘图也使用了它)

from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats

# 如果backtest_dir指向一个目录,则将自动加载最后的回测文件。
backtest_dir = config["user_data_dir"] / "backtest_results"
# backtest_dir也可以指向一个具体的文件 
# backtest_dir = config["user_data_dir"] / "backtest_results/backtest-result-2020-07-01_20-04-22.json"
# 您可以使用以下命令获取完整的回测统计信息。
# 这包含用于生成回测结果的所有信息。
stats = load_backtest_stats(backtest_dir)

strategy = 'SampleStrategy'
# 每个策略都有可用的所有统计信息,因此如果在回测过程中使用了`--strategy-list`,这些信息也会反映在这里。
# 示例用法:
print(stats['strategy'][strategy]['results_per_pair'])
# 获取用于此回测的交易对列表
print(stats['strategy'][strategy]['pairlist'])
# 获取市场变动(从回测开始到回测结束的所有交易对的平均变动)
print(stats['strategy'][strategy]['market_change'])
# 最大回撤()
print(stats['strategy'][strategy]['max_drawdown'])
# 最大回撤开始和结束
print(stats['strategy'][strategy]['drawdown_start'])
print(stats['strategy'][strategy]['drawdown_end'])


# 获取策略比较(仅在比较多个策略时相关)
print(stats['strategy_comparison'])
# 作为数据框加载回测交易记录
trades = load_backtest_data(backtest_dir)

# 按交易对显示退出原因的数量统计
trades.groupby("pair")["exit_reason"].value_counts()

绘制每日盈利/资金曲线

# 绘制资金曲线(从第一天开始,每天添加回测盈利)

from freqtrade.configuration import Configuration
from freqtrade.data.btanalysis import load_backtest_stats
import plotly.express as px
import pandas as pd

# strategy = 'SampleStrategy'
# config = Configuration.from_files(["user_data/config.json"])
# backtest_dir = config["user_data_dir"] / "backtest_results"

stats = load_backtest_stats(backtest_dir)
strategy_stats = stats['strategy'][strategy]

df = pd.DataFrame(columns=['dates','equity'], data=strategy_stats['daily_profit'])
df['equity_daily'] = df['equity'].cumsum()

fig = px.line(df, x="dates", y="equity_daily")
fig.show()

将实时交易结果加载到pandas数据框中

如果您已经进行了一些交易并想要分析您的表现

from freqtrade.data.btanalysis import load_trades_from_db

# 从数据库中获取交易数据
trades = load_trades_from_db("sqlite:///tradesv3.sqlite")

# 显示结果
trades.groupby("pair")["exit_reason"].value_counts()

分析加载的交易并行性

在与--disable-max-market-positions一起与回测一起使用时,这可能对找到最佳的max_open_trades参数非常有用。

analyze_trade_parallelism()返回一个时间序列的DataFrame,其中包含一个"open_trades"列,该列指定每个蜡烛图的开放交易数。

from freqtrade.data.btanalysis import analyze_trade_parallelism

# 分析上述交易
parallel_trades = analyze_trade_parallelism(trades, '5m')

parallel_trades.plot()

绘制结果

Freqtrade基于plotly提供了交互式绘图功能。

from freqtrade.plot.plotting import generate_candlestick_graph
# 限制图表周期以保持plotly的快速和反应能力

# 将交易筛选为一对
trades_red = trades.loc[trades['pair'] == pair]

data_red = data['2019-06-01':'2019-06-10']
# 生成蜡烛图
graph = generate_candlestick_graph(pair=pair,
                                   data=data_red,
                                   trades=trades_red,
                                   indicators1=['sma20', 'ema50', 'ema55'],
                                   indicators2=['rsi', 'macd', 'macdsignal', 'macdhist']
                                  )
# 内联显示图表
# graph.show()

# 在单独的窗口中渲染图表
graph.show(renderer="browser")

绘制平均每次交易利润的分布图

import plotly.figure_factory as ff

hist_data = [trades.profit_ratio]
group_labels = ['profit_ratio']  # 数据集的名称

fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)
fig.show()

如果您想分享有关如何最好分析数据的想法,请随时发起一个问题或Pull Request来扩充这个文档。