💬 Forum

ZaratustraV25

🏆 League #1023 / 1939

remiotore/ccxt-freqtrade/strategies/ZaratustraV25.py · ★3 · ⑂2 · first seen 2026-07-16 · repo updated 2026-01-11 · ⬇ 1 download

Basics mode: futures timeframe: 5m interface version: 3
Settings stoploss: -0.313 has minimal roi trailing dca
Indicators Bollinger_Bands CCI RSI talib technical
Concepts dca trailing
15 related strategies ( identical code, similar name)

Each tile is a different kind of check — from an instant code lint to full sandboxed backtests and forward tests on recent data. Not sure what a check actually proves? See the FAQ →

Source

Download Raw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these imports ---
from freqtrade.constants import Config
from freqtrade.persistence import Trade
from freqtrade.strategy import IStrategy, informative, IntParameter, DecimalParameter
from freqtrade.optimize.space import Categorical, Dimension, Integer, SKDecimal
from datetime import datetime, timedelta
from pandas import DataFrame
from typing import Dict, List, Optional, Union, Tuple
import talib.abstract as ta
from technical import qtpylib


class ZaratustraV25(IStrategy):
    # Parameters
    INTERFACE_VERSION = 3
    timeframe = '5m'
    can_short = True

    # DCA参数
    max_dca_orders = 2
    max_dca_multiplier = 2.0
    min_dca_profit = -0.05
    max_dca_profit = -0.1

    # 分批减仓参数
    position_adjustment_enable = True
    max_entry_position_adjustment = -1
    max_exit_position_adjustment = 3
    exit_portion_size = 0.3

    # ROI table:
    minimal_roi = {
        "0": 0.147,
        "32": 0.058,
        "48": 0.037,
        "63": 0
    }

    # Stoploss:
    stoploss = -0.313

    # Trailing stop:
    trailing_stop = True
    trailing_stop_positive = 0.064
    trailing_stop_positive_offset = 0.068
    trailing_only_offset_is_reached = False
    
    # Max Open Trades:
    max_open_trades = -1

    @property
    def plot_config(self):
        return {
            'main_plot': {
                'BBU': {},
                'BBM': {},
                'BBL': {},
            },
            'subplots': {
                'Momentum': {
                    'RSI': {'color': 'blue'},
                    'CCI': {'color': 'orange'},
                },
            },
        }

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # RSI and CCI
        dataframe['RSI'] = ta.RSI(dataframe)
        dataframe['CCI'] = ta.CCI(dataframe)

        # Bollinger Bands
        bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
        dataframe['BBU'] = bollinger['upper']
        dataframe['BBM'] = bollinger['mid']
        dataframe['BBL'] = bollinger['lower']

        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['RSI'] < 30) &
                (dataframe['CCI'] < -100) &
                (dataframe['close'] < dataframe['BBL'])
            ),
            ['enter_long', 'enter_tag']
        ] = (1, 'Strong Trend Long')

        dataframe.loc[
            (
                (dataframe['RSI'] > 30) &
                (dataframe['CCI'] > 100) &
                (dataframe['close'] > dataframe['BBU'])
            ),
            ['enter_short', 'enter_tag']
        ] = (1, 'Strong Trend Short')


        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[
            (
                (dataframe['RSI'] > 70) &
                (dataframe['CCI'] > 100)
            ),
            ['exit_long', 'exit_tag']
        ] = (1, 'Long Exit')
        
        dataframe.loc[
            (
                (dataframe['RSI'] < 30) &
                (dataframe['CCI'] < -100)
            ),
            ['exit_short', 'exit_tag']
        ] = (1, 'Short Exit')


        return dataframe
    
    def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, min_stake: float, max_stake: float, **kwargs) -> float:
        """
        处理DCA和分批减仓
        FVGAdvancedStrategy_V2 - Rico X
        """
        if current_profit <= self.min_dca_profit and current_profit >= self.max_dca_profit:
            filled_entries = trade.select_filled_orders('enter_short' if trade.is_short else 'enter_long')
            count_entries = len(filled_entries)
            
            if count_entries < self.max_dca_orders:
                stake_amount = trade.stake_amount * self.max_dca_multiplier
                return stake_amount

        elif current_profit > 0.05:
            filled_exits = trade.select_filled_orders('exit_short' if trade.is_short else 'exit_long')
            count_exits = len(filled_exits)
            
            if count_exits < self.max_exit_position_adjustment:
                return -(trade.amount * self.exit_portion_size)

        return None

    def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, proposed_stake: float, min_stake: float, max_stake: float, entry_tag: str, **kwargs) -> float:
        return proposed_stake

    def leverage(self, pair: str, current_time: datetime, current_rate: float, proposed_leverage: float, max_leverage: float, side: str, **kwargs,) -> float:
        return min(3, max_leverage)  # Use up to 3x leverage if available