FreqTrade 量化交易超跌抄底策略

分享一个交易策略:当价格在过去 24 小时内下跌超过 20% 时,生成买入信号,并在盈利达到 10% 时自动卖出。简单回测 SHIB 在 20220101-20250201 的结果如下:

┏━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃               ┃        ┃              ┃    Tot Profit ┃              ┃               ┃     Win  Draw ┃               ┃
┃      Strategy ┃ Trades ┃ Avg Profit % ┃          USDT ┃ Tot Profit % ┃  Avg Duration ┃    Loss  Win% ┃      Drawdown ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ DipBuyerStra… │     20 │         9.99 │     56064.350 │       560.64 │       5 days, │      20     0 │ 0 USDT  0.00% │
│               │        │              │               │              │      21:28:00 │       0   100 │               │
└───────────────┴────────┴──────────────┴───────────────┴──────────────┴───────────────┴───────────────┴───────────────┘

这个策略的重点是币圈的超跌+快速回弹,所以要求盘子适当大,没有支撑的纯山寨 meme 不合适,其它币种可以适当调节超跌、止盈比例。

核心策略代码:

import freqtrade.vendor.qtpylib.indicators as qtpylib
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
import numpy as np

class DipBuyerStrategy(IStrategy):
    INTERFACE_VERSION = 3
    minimal_roi = {
        "0": 0.1  # 10% 盈利目标
    }
    stoploss = -0.999  # 不需要止损
    trailing_stop = False

    timeframe = '1m'
    process_only_new_candles = True
    startup_candle_count = 1440  # Need 24 hours of data

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        // 计算依赖的指标,24 小时变动幅度
        dataframe['price_24h_ago'] = dataframe['close'].shift(1440)
        dataframe['price_change_24h'] = (dataframe['close'] - dataframe['price_24h_ago']) / dataframe['price_24h_ago']
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        // 下跌 20% 生成买入信号
        dataframe.loc[
            (
                (dataframe['price_change_24h'] < -0.2) &
                (dataframe['volume'] > 0)
            ),
            'enter_long'] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        // 卖出信号依赖 ROI,此处不生成
        dataframe['exit_long'] = 0
        return dataframe

    def custom_stake_amount(self, pair: str, current_time: 'datetime', current_rate: float,
                          proposed_stake: float, min_stake: float, max_stake: float,
                          **kwargs) -> float:
        available_balance = self.wallets.get_available_stake_amount()
        stake_amount = available_balance
        stake_amount = min(max(stake_amount, min_stake), max_stake)
        return stake_amount

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注