Skip to content
All library documents

ClucMay7 Mean-Reversion Entries Below the Lower Bollinger Band

Code Freqtrade

Summary

This five-minute long-only strategy looks for sharp price weakness below a longer-term average and the lower Bollinger Band. It enters when the close is below the 50-period EMA and below 98.5% of the lower band, subject to a volume condition comparing current volume with a shifted 30-bar average. The code also calculates RSI, smoothed RSI, MACD, and ADX, though these indicators do not affect the shown entry or exit rules.

The strategy exits when price rises above the Bollinger middle band. It specifies a 1% minimal return target and a 5% stop loss, with settings that may be overridden by configuration. The document provides implementation rules but no historical test results, trade examples, or performance evidence. Its mean-reversion premise, volume filter, and risk settings therefore remain unvalidated here; the volume threshold is notably permissive, allowing volume below twenty times the reference average.

Key ideas

  • The strategy enters long below both the 50-period EMA and a threshold beneath the lower Bollinger Band.
  • Entry volume is compared with the prior 30-bar rolling average.
  • The exit signal occurs when the close crosses above the Bollinger middle band.
  • RSI, MACD, and ADX are calculated but do not appear in the trading conditions.
  • The code states a 1% minimal ROI and a 5% stop loss, subject to configuration overrides.

Tags

Full text
# ClucMay72018.py


```py
# --- Do not remove these libs ---
from freqtrade.strategy import IStrategy
from typing import Dict, List
from functools import reduce
from pandas import DataFrame
# --------------------------------

import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
from typing import Dict, List
from functools import reduce
from pandas import DataFrame, DatetimeIndex, merge
# --------------------------------

import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
import numpy  # noqa


class ClucMay72018(IStrategy):
    """

    author@: Gert Wohlgemuth

    works on new objectify branch!

    """

    INTERFACE_VERSION: int = 3
    # Minimal ROI designed for the strategy.
    # This attribute will be overridden if the config file contains "minimal_roi"
    minimal_roi = {
        "0": 0.01
    }

    # Optimal stoploss designed for the strategy
    # This attribute will be overridden if the config file contains "stoploss"
    stoploss = -0.05

    # Optimal timeframe for the strategy
    timeframe = '5m'

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=5)
        rsiframe = DataFrame(dataframe['rsi']).rename(columns={'rsi': 'close'})
        dataframe['emarsi'] = ta.EMA(rsiframe, timeperiod=5)
        macd = ta.MACD(dataframe)
        dataframe['macd'] = macd['macd']
        dataframe['adx'] = ta.ADX(dataframe)
        bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
        dataframe['bb_lowerband'] = bollinger['lower']
        dataframe['bb_middleband'] = bollinger['mid']
        dataframe['bb_upperband'] = bollinger['upper']
        dataframe['ema100'] = ta.EMA(dataframe, timeperiod=50)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on TA indicators, populates the buy signal for the given dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        dataframe.loc[
            (
                    (dataframe['close'] < dataframe['ema100']) &
                    (dataframe['close'] < 0.985 * dataframe['bb_lowerband']) &
                    (dataframe['volume'] < (dataframe['volume'].rolling(window=30).mean().shift(1) * 20))
            ),
            'enter_long'] = 1

        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        """
        Based on TA indicators, populates the sell signal for the given dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        dataframe.loc[
            (
                (dataframe['close'] > dataframe['bb_middleband'])
            ),
            'exit_long'] = 1
        return dataframe

```

Shown in full with attribution under the source's licence. Licence: GPL-3.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.