""" SwingHighToSky Strategy author = "Kevin Ossenbrück" copyright = "Free For Use" credits = ["Bloom Trading, Mohsen Hassan"] license = "MIT" version = "1.0" maintainer = "Kevin Ossenbrück" email = "kevin.ossenbrueck@pm.de" status = "Live" Github: https://github.com/freqtrade/freqtrade-strategies This strategy uses CCI (Commodity Channel Index) and RSI indicators to identify mean reversion opportunities. Entry: When CCI crosses below threshold AND RSI shows strength Exit: When CCI and RSI reach overbought levels """ from freqtrade.strategy import IStrategy, IntParameter from functools import reduce from pandas import DataFrame import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib import numpy class SwingHighToSky(IStrategy): INTERFACE_VERSION = 3 timeframe = '15m' stoploss = -0.34338 minimal_roi = {"0": 0.27058, "33": 0.0853, "64": 0.04093, "244": 0} # Buy hyperspace parameters buy_cci = IntParameter(low=-200, high=200, default=-175, space='buy', optimize=True) buy_cciTime = IntParameter(low=10, high=80, default=72, space='buy', optimize=True) buy_rsi = IntParameter(low=10, high=90, default=90, space='buy', optimize=True) buy_rsiTime = IntParameter(low=10, high=80, default=36, space='buy', optimize=True) # Sell hyperspace parameters sell_cci = IntParameter(low=-200, high=200, default=-106, space='sell', optimize=True) sell_cciTime = IntParameter(low=10, high=80, default=66, space='sell', optimize=True) sell_rsi = IntParameter(low=10, high=90, default=88, space='sell', optimize=True) sell_rsiTime = IntParameter(low=10, high=80, default=45, space='sell', optimize=True) # Buy hyperspace params (already optimized) buy_params = { "buy_cci": -175, "buy_cciTime": 72, "buy_rsi": 90, "buy_rsiTime": 36, } # Sell hyperspace params (already optimized) sell_params = { "sell_cci": -106, "sell_cciTime": 66, "sell_rsi": 88, "sell_rsiTime": 45, } def informative_pairs(self): return [] def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Calculate CCI and RSI indicators for various timeperiods. The strategy will use the values with timeperiods from the buy/sell parameters. """ # Calculate CCI for different timeperiods (for buy signals) for val in self.buy_cciTime.range: dataframe[f'cci-{val}'] = ta.CCI(dataframe, timeperiod=val) # Calculate CCI for different timeperiods (for sell signals) for val in self.sell_cciTime.range: dataframe[f'cci-sell-{val}'] = ta.CCI(dataframe, timeperiod=val) # Calculate RSI for different timeperiods (for buy signals) for val in self.buy_rsiTime.range: dataframe[f'rsi-{val}'] = ta.RSI(dataframe, timeperiod=val) # Calculate RSI for different timeperiods (for sell signals) for val in self.sell_rsiTime.range: dataframe[f'rsi-sell-{val}'] = ta.RSI(dataframe, timeperiod=val) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Buy signal when: - CCI crosses below buy_cci threshold (mean reversion signal) - RSI is below buy_rsi threshold (not too overbought) """ dataframe.loc[ ( (dataframe[f'cci-{self.buy_cciTime.value}'] < self.buy_cci.value) & (dataframe[f'rsi-{self.buy_rsiTime.value}'] < self.buy_rsi.value) ), 'enter_long'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: """ Sell signal when: - CCI crosses above sell_cci threshold (reversal signal) - RSI is above sell_rsi threshold (overbought condition) """ dataframe.loc[ ( (dataframe[f'cci-sell-{self.sell_cciTime.value}'] > self.sell_cci.value) & (dataframe[f'rsi-sell-{self.sell_rsiTime.value}'] > self.sell_rsi.value) ), 'exit_long'] = 1 return dataframe