策略分析示例¶
调试策略可能非常耗时。Freqtrade 提供了辅助函数来可视化原始数据。以下内容假设你正在使用 SampleStrategy,数据来自 Binance 的 5 分钟时间帧,并已将其下载到默认位置的 data 目录中。更多详细信息,请参阅文档。
设置¶
更改工作目录至仓库根目录¶
import os
from pathlib import Path
# Change directory
# Modify this cell to insure that the output shows the correct path.
# Define all paths relative to the project root shown in the cell output
project_root = "somedir/freqtrade"
i = 0
try:
os.chdir(project_root)
if not Path("LICENSE").is_file():
i = 0
while i < 4 and (not Path("LICENSE").is_file()):
os.chdir(Path(Path.cwd(), "../"))
i += 1
project_root = Path.cwd()
except FileNotFoundError:
print("Please define the project root relative to the current directory")
print(Path.cwd())
配置 Freqtrade 环境¶
from freqtrade.configuration import Configuration
# Customize these according to your needs.
# Initialize empty configuration object
config = Configuration.from_files([])
# Optionally (recommended), use existing configuration file
# config = Configuration.from_files(["user_data/config.json"])
# Define some constants
config["timeframe"] = "5m"
# Name of the strategy class
config["strategy"] = "SampleStrategy"
# Location of the data
data_location = config["datadir"]
# Pair to analyze - Only use one pair here
pair = "BTC/USDT"
# Load data using values set above
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", # Make sure to update this to your data
candle_type=CandleType.SPOT,
)
# Confirm success
print(f"Loaded {len(candles)} rows of data for {pair} from {data_location}")
candles.head()
加载并运行策略¶
- 每次修改策略文件后都需要重新运行
# Load strategy using values set above
from freqtrade.data.dataprovider import DataProvider
from freqtrade.resolvers import StrategyResolver
strategy = StrategyResolver.load_strategy(config)
strategy.dp = DataProvider(config, None, None)
strategy.ft_bot_start()
# Generate buy/sell signals using strategy
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”)可用时),或在中间某个信号处,一旦有“仓位”空出就会买入。
# Report results
print(f"Generated {df['enter_long'].sum()} entry signals")
data = df.set_index("date", drop=False)
data.tail()
将现有对象加载到 Jupyter notebook¶
以下单元格假设你已通过命令行界面(cli)生成了数据。
它们将允许你更深入地分析结果,并执行其他方式下因信息过载而难以处理的分析。
将回测结果加载为 pandas 数据框¶
分析交易数据框(也用于下方的绘图)
from freqtrade.data.btanalysis import load_backtest_data, load_backtest_stats
# if backtest_dir points to a directory, it'll automatically load the last backtest file.
backtest_dir = config["user_data_dir"] / "backtest_results"
# backtest_dir can also point to a specific file
# backtest_dir = (
# config["user_data_dir"] / "backtest_results/backtest-result-2020-07-01_20-04-22.json"
# )
# You can get the full backtest statistics by using the following command.
# This contains all information used to generate the backtest result.
stats = load_backtest_stats(backtest_dir)
strategy = "SampleStrategy"
# All statistics are available per strategy, so if `--strategy-list` was used during backtest,
# this will be reflected here as well.
# Example usages:
print(stats["strategy"][strategy]["results_per_pair"])
# Get pairlist used for this backtest
print(stats["strategy"][strategy]["pairlist"])
# Get market change (average change of all pairs from start to end of the backtest period)
print(stats["strategy"][strategy]["market_change"])
# Maximum drawdown ()
print(stats["strategy"][strategy]["max_drawdown_abs"])
# Maximum drawdown start and end
print(stats["strategy"][strategy]["drawdown_start"])
print(stats["strategy"][strategy]["drawdown_end"])
# Get strategy comparison (only relevant if multiple strategies were compared)
print(stats["strategy_comparison"])
# Load backtested trades as dataframe
trades = load_backtest_data(backtest_dir)
# Show value-counts per pair
trades.groupby("pair")["exit_reason"].value_counts()
绘制每日盈利/权益曲线¶
# Plotting equity line (starting with 0 on day 1 and adding daily profit for each backtested day)
import pandas as pd
import plotly.express as px
from freqtrade.configuration import Configuration
from freqtrade.data.btanalysis import load_backtest_stats
# 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
# Fetch trades from database
trades = load_trades_from_db("sqlite:///tradesv3.sqlite")
# Display results
trades.groupby("pair")["exit_reason"].value_counts()
分析已加载交易的并行情况¶
当与回测结合使用且设置非常高的 max_open_trades 时,这有助于找到最佳的 max_open_trades 参数。
analyze_trade_parallelism() 返回一个包含 "open_trades" 列的时间序列数据框,该列表示每个 K 线周期内的未平仓交易数量。
from freqtrade.data.btanalysis import analyze_trade_parallelism
# Analyze the above
parallel_trades = analyze_trade_parallelism(trades, "5m")
parallel_trades.plot()
绘制结果¶
Freqtrade 提供基于 Plotly 的交互式绘图功能。
from freqtrade.plot.plotting import generate_candlestick_graph
# Limit graph period to keep plotly quick and reactive
# Filter trades to one pair
trades_red = trades.loc[trades["pair"] == pair]
data_red = data["2019-06-01":"2019-06-10"]
# Generate candlestick graph
graph = generate_candlestick_graph(
pair=pair,
data=data_red,
trades=trades_red,
indicators1=["sma20", "ema50", "ema55"],
indicators2=["rsi", "macd", "macdsignal", "macdhist"],
)
# Show graph inline
# graph.show()
# Render graph in a separate window
graph.show(renderer="browser")
将每笔交易的平均利润绘制成分布图¶
import plotly.figure_factory as ff
hist_data = [trades.profit_ratio]
group_labels = ["profit_ratio"] # name of the dataset
fig = ff.create_distplot(hist_data, group_labels, bin_size=0.01)
fig.show()
如果您想分享关于如何最好地分析这些数据的想法,欢迎提交问题或拉取请求来改进本文档。