Freqtrade算法交易简明教程

本文介绍Freqtrade 的基本功能和加密市场术语、如何使用Python和pandas定义策略以及根据历史数据对策略进行回溯测试。

Freqtrade算法交易简明教程
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK

Freqtrade 是一款用 Python 编写的加密货币算法交易软件。

它允许你:

  • 制定策略:轻松使用 Python 和 pandas。 我们将在本文中创建一个简单的策略,你可以查看 freqtrade 的示例策略存储库
  • 下载市场数据:快速下载你选择的加密货币的历史价格数据。
  • 回测:根据历史数据测试你的策略。 回溯测试是查看你的策略是否有机会在现实世界中赚钱的关键步骤。 它不能保证实际性能,因为市场条件比下载的数据更复杂。
  • 优化:使用 hyperopt 找到最适合你策略的参数。
  • 选择要交易的币对:你的选择可以是基于简单过滤器的静态或动态选择,例如交易量是否大于一定金额。
  • 试运行:使用模拟钱包根据实时数据测试策略。
  • 实时运行:通过加密货币交易所的 API 使用真实资金部署策略。 这是你知道自己在做什么并愿意损失所有钱之后的最后一步。
  • 使用 Telegram 机器人:通过 Telegram 控制和监控你的策略。
  • 分析和可视化交易历史:利用保存文件或通过 SQL 数据库的交易数据。

1、安装 freqtrade

好的,让我们从安装开始深入探讨。

1.1 Docker - 适用于所有平台的最简单方法

Docker 是在所有平台上入门的最快方法,也是 Windows 的推荐方法。 你需要首先安装 Docker 和 docker-compose,然后通过启动 Docker Desktop 确保 Docker 正在运行。

现在可以通过在所需目录中发出以下命令来设置 freqtrade:

mkdir ft_userdata
cd ft_userdata/

# Download the docker-compose file from the repository
curl https://raw.githubusercontent.com/freqtrade/freqtrade/stable/docker-compose.yml -o docker-compose.yml

# Pull the freqtrade image
docker-compose pull

# Create user directory structure
docker-compose run --rm freqtrade create-userdir --userdir user_data

你现在应该具有以下目录结构:

ft_userdata
└───user_data
    ├───backtest_results
    ├───data
    ├───hyperopts
    ├───hyperopt_results
    ├───logs
    ├───notebooks
    ├───plot
    └───strategies

要验证 freqtrade 是否已正确安装并可供使用,可以使用 help命令:

docker-compose run --rm freqtrade --help

你应该看到以下输出:

usage: freqtrade [-h] [-V] 
        {trade,create-userdir,new-config,new-hyperopt,new-strategy,download-data,convert-data,convert-trade-data,list-data,backtesting,edge,hyperopt,hyperopt-list,hyperopt-show,list-exchanges,list-hyperopts,list-markets,list-pairs,list-strategies,list-timeframes,show-trades,test-pairlist,instal l-ui,plot-dataframe,plot-profit} ...

help 命令的输出显示所有可能的 freqtrade 命令。 在本系列中,我们将探索最重要的命令以及如何使用它们。 第一个是回溯测试。

2、回测:freqtrade 如何测试交易策略

在本文中,我们希望创建一个简单的策略并根据历史数据进行回测。 回测根据历史数据测试策略,模拟策略预期进行的交易。 虽然这并不能保证现实世界中的表现,但它很好地表明了获胜/失败的策略。

Freqtrade 通过以下步骤回测策略:

  • 在提供的配置文件中加载币对(ETH/BTC、ADA/BTC、XRP/BTC 等)的历史数据
  • 调用策略的 bot_loop_start() 函数一次。 这会在实时运行中启动一个新循环,而在回溯测试中,只需要一次。
  • 通过调用每个交易对的 populate_indicators() 方法来计算策略的技术指标
  • 通过调用每个交易对的 populate_buy_trend()populate_sell_trend() 方法来计算买入/卖出信号
  • 如果在策略中实现,则通过调用 confirm_trade_entry()confirm_trade_exit() 方法确认买入/卖出交易
  • 循环遍历每个时间段(5m、1h、1d等)并模拟进入点和退出点
  • 最后,生成回测报告,总结指定期间内的所有交易以及相关盈亏

我们将在接下来的段落中定义上面提到的方法,例如 populate_indicators()

要了解更多信息,请务必查看相关文档页面。 它写得特别好并且易于阅读。

3、下载数据

为了进行回溯测试,我们需要来自交易所的历史价格数据。 让我们首先使用以下命令从 Binance 下载一些数据:

docker-compose run --rm freqtrade download-data -p ETH/BTC -t 1d --timerange 20200101-20201231 --exchange binance

该命令的参数告诉 freqtrade 以下内容:

  • -p ETH/BTC - 下载以太坊 (ETH) - 比特币 (BTC) 货币对的数据
  • -t 1d - 下载时间范围为 1 天的数据
  • --timerange 20200101-20201231 - 下载从 01/01/2020 到 31/12/2020 的数据。
  • --exchange binance - 从币安交易所下载数据。 在这里,你可以使用 freqtrade 支持的任何交易所。

该命令生成如下目录和文件:

ft_userdata
└───user_data
    └───data
        └───binance
               ETH_BTC-1d.json

其中包含多个开高低闭卷 (OHLCV) 数据工件,如下所示:

timeOpenHighLowCloseVolume
16228512000000.0730130.0750.07260.073986143662.752
16229376000000.0739890.0759610.0736260.075737120623.423

其中各列含义如下:

  • time:Unix 时间戳(以毫秒为单位)
  • Open:开盘价,烛台开始处的开盘价
  • High:最高价,烛台期间达到的最高价格
  • Low:最低价,烛台期间达到的最低价格
  • Close:收盘价,烛台末端的收盘价
  • Volume:交易量,购买或出售的资产数量,以基础货币(在我们的例子中为 ETH)显示。 BTC 是报价货币。

该数据可以在以下烛台图中清晰地表示:

ETH/BTC 价格以一日 (1d) 烛台形式显示

上面的图表使用烛台来表示比简单的线条更多的信息。 你可以在下图中看到烛台含义的快速描述:

Source: www.ig.com

如果你还记得前面的示例 OHLCV 行,可以看到每个烛台代表每行数据的开盘价、最高价、最低价、收盘价部分。 许多技术交易策略都会寻找烛台形态,我们可能会在后面的文章中对此进行探讨。

《金融市场技术分析》是一本学习这些模式的优秀书籍。 如需简要概述,你还可以查看 Investopedia 的文章了解基本烛台图

现在我们已经看到了数据示例并理解了每一行的含义,让我们继续配置 freqtrade 来运行我们的策略。

4、高频交易配置

我们拥有回测策略所需的数据,但我们需要创建一个配置文件,这将使我们能够轻松控制策略的多个参数。

要创建新配置,我们运行以下命令:

docker-compose run --rm freqtrade new-config --config user_data/learndatasci-config.json

你将看到一些初始问题,我们用以下值回答这些问题:

在继续之前,我们需要打开配置文件并设置 pair_whitelist = [“ETH/BTC”],这会建立我们感兴趣的货币对。 然后我们就准备出发了。

你暂时不需要担心其他任何事情,但是你应该确保了解其他配置选项的含义,因此请务必访问相关文档

5、实施简单的自定义策略 - 移动平均线交叉

在这里,我们将定义一种简单的移动平均策略,类似于《Python for Finance》系列中的策略。 如果你还没有阅读过,请务必结账。 你可以在 Investopedia 中找到更多详细信息。

我要告诉你一个小秘密。 交易其实非常简单,你只需要做两件事:

  • 低价买入
  • 高价卖出

这么容易吗? 有什么问题吗? 棘手的是找到实际的低点和高点。

移动平均线策略背后的思想如下:

你有两条线:

  • 慢速移动平均线 (SMA):过去值的长期平均值,代表总体趋势。
  • 快速移动平均线 (FMA):过去值的短期平均值,代表当前趋势。

对于我们的策略,我们将使用以下指标:

  • 当 FMA 穿越 SMA 上方时买入,表明趋势向上。
  • 当 FMA 穿越 SMA 下方时卖出,表明趋势下降。

这称为移动平均线交叉策略:

6、为 freqtrade 定义自定义策略

让我们使用 pandas 转换 freqtrade 中的移动平均线交叉策略。

首先,我们需要创建一个新的策略文件来保存买入/卖出信号背后的逻辑。

!docker-compose run --rm freqtrade new-strategy -s SimpleMA_strategy --template minus`

现在,我们可以在策略文件夹中找到新创建的文件:

ft_userdata
└───user_data
    ...
    └───strategies
            SimpleMA_strategy.py

SimpleMA_strategy.py 包含一个自动生成的类 SimpleMA_strategy 以及我们需要更新的几个函数。

为了定义我们的简单策略,我们需要更新以下三个函数:

  • populate_indicators()
  • populate_buy_trend()
  • populate_sell_trend()

让我们逐一讨论一下这些内容。

6.1 populate_indicators()

在这里,我们计算我们的策略产生买入/卖出信号所需的指标。

为 ETH/BTC 绘制的快速移动平均线(蓝线)和慢速移动平均线(黄线)指标

根据我们的策略,我们计算快速移动平均线 fast_MA(使用最后 5 个烛台计算)和慢速移动平均线 Slow_ma(使用前 50 个烛台计算):

class SimpleMA_strategy(IStrategy):
    
    ...
    
    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        fast_period = 5
        slow_period = 50
        dataframe['fast_MA'] = ta.SMA(dataframe, timeperiod=fast_period)
        dataframe['slow_MA'] = ta.SMA(dataframe, timeperiod=slow_period)
        
        return dataframe

请注意,我们将数据帧作为参数传递,对其进行操作,然后返回它。 我们所有的函数都会以这种方式处理数据帧。

如果你有兴趣查看简单移动平均线以外的指标,请查看 ta-lib 文档

6.2 populate_buy_trend()

该函数填充我们的买入信号,当我们策略中的 fast_MA 穿过 Slow_MA 时,就会触发该信号。

我们可以通过更新 populate_buy_trend() 以包含以下逻辑来实现此目的:

class SimpleMA_strategy(IStrategy):
    
    ...
    
    def populate_indicators(...):
        ...
    
    def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
          (
            qtpylib.crossed_above(dataframe['fast_MA'], dataframe['slow_MA'])
          ),
          'buy'] = 1
        
        return dataframe

使用qtpylib,我们可以轻松找到交叉点。 本质上,当我们的购买条件 (crossed_above) 被触发时,上面的代码会用 1 填充购买列。

6.3 populate_sell_trend()

以与前一个函数类似的方式,该函数填充我们的卖出信号:

根据我们的策略,这是当 fast_MA 穿过 Slow_MA 下方时:

class SimpleMA_strategy(IStrategy):
    
    ...
    
    def populate_indicators(...):
        ...
    
    def populate_buy_trend(...):
        ...
        
    def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
          (
            qtpylib.crossed_below(dataframe['fast_MA'], dataframe['slow_MA'])
          ),
          'sell'
        ] = 1
        
        return dataframe

我们现在使用 crossed_below(与 crossed_above 相反),当我们的卖出条件被触发时,它将用 1 填充卖出列。

默认情况下,生成的 freqtrade 策略文件包含更多选项,例如 ROI(投资回报率)和止损,这将在本系列文章的第二部分中讨论。 我们现在将禁用它们:

class SimpleMA_strategy(IStrategy):
    
    ...
    
    # the following statement disables selling due to ROI
    minimal_roi = {
        "0": 100
    }
    
    # the following statement disables selling due to stop-loss
    stoploss = -1.0
    
    def populate_indicators(...):
        ...
    
    def populate_buy_trend(...):
        ...
        
    def populate_sell_trend(...):
        ...

现在我们已经填写了策略,我们可以测试它在过去数据上的表现。

7、回测策略

定义了我们的简单策略后,现在我们希望使用历史数据和回测来评估它,这使我们能够在过去进行交易,看看它们的表现如何。

回溯测试并不能完美地代表我们的策略的执行情况,因为其他因素也会影响实时市场的回报,例如滑点。

要使用 freqtrade 执行回溯测试,我们可以使用刚刚创建的类和函数运行以下命令:

docker-compose run --rm freqtrade backtesting 
    --strategy SimpleMA_strategy -i 1d -p ETH/BTC 
    --timerange 20200101-20201231 
    --starting-balance 1
    -c ./user_data/learndatasci-config.json

上述命令中的参数如下:

ArgumentDescription
--strategy SimpleMA_strategyuse the SimpleMA_strategy strategy we created above.
-i 1duse 1 day candlesticks
  • --p ETH/BTC - 交易 ETH/BTC 货币对,将我们的 BTC 换成 ETH
  • --timerange 20200101-20201231 - 2020年的回测,从第一天01/01/2020到最后一天12/31/2020。
  • c ./user_data/config-learndatasci.json 我们正在使用本文前面定义的配置。
  • --starting-balance 1 我们从 1 BTC 的余额开始。
Result for strategy SimpleMA_strategy
========================================================== BACKTESTING REPORT ==========================================================
|    Pair |   Buys |   Avg Profit % |   Cum Profit % |   Tot Profit BTC |   Tot Profit % |      Avg Duration |   Win  Draw  Loss  Win% |
|---------+--------+----------------+----------------+------------------+----------------+-------------------+-------------------------|
| ETH/BTC |      6 |           8.47 |          50.81 |       0.05086506 |           5.09 | 34 days, 12:00:00 |     3     0     3  50.0 |
|   TOTAL |      6 |           8.47 |          50.81 |       0.05086506 |           5.09 | 34 days, 12:00:00 |     3     0     3  50.0 |
==================================================== SELL REASON STATS =====================================================
|   Sell Reason |   Sells |   Win  Draws  Loss  Win% |   Avg Profit % |   Cum Profit % |   Tot Profit BTC |   Tot Profit % |
|---------------+---------+--------------------------+----------------+----------------+------------------+----------------|
|   sell_signal |       6 |      3     0     3  50.0 |           8.47 |          50.81 |        0.0508651 |          50.81 |
===================================================== LEFT OPEN TRADES REPORT ======================================================
|   Pair |   Buys |   Avg Profit % |   Cum Profit % |   Tot Profit BTC |   Tot Profit % |   Avg Duration |   Win  Draw  Loss  Win% |
|--------+--------+----------------+----------------+------------------+----------------+----------------+-------------------------|
|  TOTAL |      0 |           0.00 |           0.00 |       0.00000000 |           0.00 |           0:00 |     0     0     0     0 |
=============== SUMMARY METRICS ===============
| Metric                | Value               |
|-----------------------+---------------------|
| Backtesting from      | 2020-01-01 00:00:00 |
| Backtesting to        | 2020-12-31 00:00:00 |
| Max open trades       | 1                   |
|                       |                     |
| Total trades          | 6                   |
| Starting balance      | 1.00000000 BTC      |
| Final balance         | 1.05086506 BTC      |
| Absolute profit       | 0.05086506 BTC      |
| Total profit %        | 5.09%               |
| Trades per day        | 0.02                |
| Avg. stake amount     | 0.10000000 BTC      |
| Total trade volume    | 0.60000000 BTC      |
|                       |                     |
| Best Pair             | ETH/BTC 50.81%      |
| Worst Pair            | ETH/BTC 50.81%      |
| Best trade            | ETH/BTC 36.59%      |
| Worst trade           | ETH/BTC -10.57%     |
| Best day              | 0.03662727 BTC      |
| Worst day             | -0.01058107 BTC     |
| Days win/draw/lose    | 3 / 277 / 3         |
| Avg. Duration Winners | 51 days, 16:00:00   |
| Avg. Duration Loser   | 17 days, 8:00:00    |
| Zero Duration Trades  | 0.00% (0)           |
| Rejected Buy signals  | 0                   |
|                       |                     |
| Min balance           | 1.02441263 BTC      |
| Max balance           | 1.06732320 BTC      |
| Drawdown              | 16.44%              |
| Drawdown              | 0.01645814 BTC      |
| Drawdown high         | 0.06732320 BTC      |
| Drawdown low          | 0.05086506 BTC      |
| Drawdown Start        | 2020-09-10 00:00:00 |
| Drawdown End          | 2020-12-19 00:00:00 |
| Market change         | 24.93%              |
===============================================

我们得到一份完整的报告,其中包含指定期间内所有交易的结果。

Freqtrade 将报告分为四个部分:

  1. 回测报告

显示每个货币对的性能报告,在我们的例子中,只有 ETH/BTC。

平均利润 % 列显示所有交易的平均利润,而累计利润 % 列总结所有利润/损失。 总利润 % 列显示相对于起始余额的总利润 %。 ~ 频率贸易文档

2. 卖出原因统计

该报告向我们展示了卖出原因的表现。 根据我们的策略,我们仅使用卖出信号,因此我们只有 1 行。 一般来说,我们也可以出于其他原因出售,例如可接受的投资回报率(ROI)和止损。 我们将在本系列的下一篇文章中看到这一点。

3. 未平仓交易报告

这一部分显示回测结束时未平仓的所有交易。 在我们的例子中,我们没有任何,一般来说,它不是很重要,因为它代表回测的结束状态。

4. 指标概要

就我个人而言,这是我通常首先关注的领域。 最需要指出的部分如下:

  • Trades per day - 每日交易数,每日平仓交易的平均数量。 我通常寻找每天进行大约十笔交易的策略。
  • Total profit% - 利润总额 % ,利润占期初余额的百分比。
  • Drawdown - 最大连续亏损金额
  • Market change - 市场变化,指定时期内市场增长/收缩的程度。 当交易多个货币对时,该指标所有货币对从指定时期开始到结束所发生的市场变化的平均值。 在我们的案例中,ETH/BTC 市场在 2020 年增长了 24.93%。在不同的市场条件下测试策略至关重要,而不仅仅是在上升趋势的市场中测试策略。

要完整了解该报告,请务必阅读相关文档

8、注意事项和改进

我们可以看到只发生了六笔交易。 这些交易产生了 5.09% 的利润,从 1 BTC 开始,到 1.05086506 BTC 结束。

考虑到所涉及的风险,这个结果并不令人印象深刻。 然而,这个策略非常简单,并且还有很大的改进空间:

  • 与购买并持有仅持有 ETH 相比,即在测试期开始时将我们的整个 BTC 堆栈转换为 ETH,我们将获得 24.93%(市场变化指标),但这不是我们通常可以预期的。 我们的风险敞口要少得多,每笔交易只押注 10% 的筹码,而不是全部。 在不同条件下测试我们的策略非常重要——不仅是在市场增长时,而且在市场萎缩时。
  • 交易更多的货币对。我们只考虑了以太坊,它是我们可以交易的数百种货币之一。 此限制仅允许一次进行一笔交易,这显然不是最理想的。
  • 使用更高级的策略。我们可以说使用了最简单的策略之一,它仅使用简单的移动平均线作为指标。 增加复杂性并不一定意味着更好的性能,但是我们可以对大量指标组合进行相互回测,以找到最佳策略。
  • 优化参数。目前,我们还没有尝试优化任何超参数,例如移动平均周期、投资回报和止损。
  • 较小的时间段。我们只考虑每日烛台,这就是机器人每天仅发现约 0.02 笔交易的原因之一,其交易次数比人类交易者少得多。 机器人可以通过更频繁的交易和查看更详细的烛台来赚取更多利润。

9、绘制结果

要使用 freqtrade 的绘图命令,我们需要更改 docker-compose.yml 文件。 我们唯一需要做的就是注释掉一行并取消注释另一行。 请参阅以下文件摘录以查看示例:

---
version: '3'
services:
  freqtrade:
    # image: freqtradeorg/freqtrade:stable      <--- comment this line
    # image: freqtradeorg/freqtrade:develop
    # Use plotting image
    image: freqtradeorg/freqtrade:develop_plot  <--- uncomment this line
    ...

这告诉 docker-compose 拉取包含正确绘图库的 freqtrade Docker 镜像。

我们现在可以使用 freqtradeplot-dataframe 命令可视化我们的数据、指标和买入/卖出信号。

docker-compose run --rm freqtrade plot-dataframe -s SimpleMA_strategy --config ./user_data/learndatasci-config.json -i 1d --timerange 20200101-20201231 --indicators1 fast_MA slow_MA

--indicators1 选项定义我们要绘制的指标,即 fast_MA 和 Slow_MA。 这些必须在使用 -s 选项指定的策略内定义。

默认情况下,这会在绘图目录中创建一个html 文件: ./user_data/plot/freqtrade-plot-ETH_BTC-1d.html

ft_userdata
└───user_data
    ...
    └───plot
          freqtrade-plot-ETH_BTC-1d.html

你可以在此处查看此交互式图的完整版本。

将鼠标悬停在绘图上,查看机器人实际上如何执行我们希望它执行的操作,如我们的简单移动平均策略所定义:

  • 当 fast_MA 穿过 Slow_MA 下方时买入。
  • 当 fast_MA 穿过 Slow_MA 时卖出。

要了解还可以使用plot-dataframe 执行哪些操作,请运行 docker-compose run --rm freqtradeplot-dataframe -h 或访问相关文档


原文链接:How to Make an Algo Trading Crypto Bot with Python (Part 1)

DefiPlot翻译整理,转载请标明出处

通过 NowPayments 打赏