💬 Forum

hansencandlepatternV1

uploads/hansencandlepatternV1.py · uploaded by 🐋 Ron · first seen 2026-07-17

Basics mode: spot timeframe: 1h interface version: 3
Settings stoploss: -0.1 has minimal roi hyperopt hyperopt params: 3
Indicators Bollinger_Bands EMA RSI SMA talib
Methods EWO plot_config
8 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 →

 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
# --- Do not remove these libs --- freqtrade backtesting --strategy SmoothScalp --timerange 20210110-20210410
from freqtrade.strategy.interface 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
# noqa
import numpy
from freqtrade.strategy import DecimalParameter, IntParameter

def EWO(dataframe, ema_length=5, ema2_length=35):
    df = dataframe.copy()
    ema1 = ta.EMA(df, timeperiod=ema_length)
    ema2 = ta.EMA(df, timeperiod=ema2_length)
    emadif = (ema1 - ema2) / df['close'] * 100
    return emadif

class hansencandlepatternV1(IStrategy):
    INTERFACE_VERSION = 3
    '\n        This strategy is only an experiment using candlestick pattern to be used as buy or sell indicator. Do not use this strategy live.\n    '
    timeframe = '1h'
    minimal_roi = {'0': 10}
    stoploss = -0.1
    # Buy hyperspace params:
    buy_params = {'base_nb_candles_buy': 11, 'ewo_high': 2.337, 'ewo_low': -15.87, 'low_offset': 0.979, 'rsi_buy': 55}
    # Sell hyperspace params:
    sell_params = {'base_nb_candles_sell': 17, 'high_offset': 0.997}
    # Protection
    fast_ewo = 50
    slow_ewo = 200
    ewo_low = DecimalParameter(-20.0, -8.0, default=buy_params['ewo_low'], space='buy', optimize=True)
    ewo_high = DecimalParameter(2.0, 12.0, default=buy_params['ewo_high'], space='buy', optimize=True)
    rsi_buy = IntParameter(30, 70, default=buy_params['rsi_buy'], space='buy', optimize=True)

    @property
    def plot_config(self):
        # Main plot indicators
        # Subplots
        return {'main_plot': {'bb_lowerband': {'color': 'lightblue'}, 'bb_middleband': {'color': 'green'}, 'bb_upperband': {'color': 'lightblue'}, 'emao': {'color': 'orange'}, 'emac': {'color': 'blue'}}, 'subplots': {'BB%': {'bb_percent': {'color': 'blue'}}, 'RSI': {'rsi': {'color': 'blue'}}, 'EWO': {'EWO': {'color': 'blue'}}, 'Candles': {'3LINESTRIKE': {'color': 'blue'}, 'ENGULFING': {'color': 'red'}, 'SPINNINGTOP': {'color': '#9b91bb'}, 'ABANDONEDBABY': {'color': '#9b91bb'}, 'INVERTEDHAMMER': {'color': 'red'}, 'DOJI': {'color': '#9b91bb'}, 'DOJISTAR': {'color': '#9b91bb'}, 'DRAGONFLYDOJI': {'color': 'red'}, 'MORNINGSTARDOJI': {'color': '#9b91bb'}, 'ABANDONEDBABY': {'color': '#9b91bb'}, 'HARAMI': {'color': '#9b91bb'}, 'EVENINGTSTAR': {'color': '#9b91bb'}}}}

    def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe['3LINESTRIKE'] = ta.CDL3LINESTRIKE(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['INVERTEDHAMMER'] = ta.CDLINVERTEDHAMMER(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['ENGULFING'] = ta.CDLENGULFING(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['DOJI'] = ta.CDLDOJI(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['DOJISTAR'] = ta.CDLDOJISTAR(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['DRAGONFLYDOJI'] = ta.CDLDRAGONFLYDOJI(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['MORNINGDOJISTAR'] = ta.CDLMORNINGDOJISTAR(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['SPINNINGTOP'] = ta.CDLSPINNINGTOP(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['ABANDONEDBABY'] = ta.CDLABANDONEDBABY(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['EVENINGSTAR'] = ta.CDLEVENINGSTAR(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['HARAMI'] = ta.CDLHARAMI(dataframe['open'], dataframe['high'], dataframe['low'], dataframe['close'])
        dataframe['ha_close'] = (dataframe['open'] + dataframe['high'] + dataframe['low'] + dataframe['close']) / 4
        dataframe['ha_open'] = (dataframe['open'].shift(2) + dataframe['close'].shift(2)) / 2
        # dataframe['hhigh'] = dataframe[['open','close','high']].max(axis=1)
        # dataframe['hlow'] = dataframe[['open','close','low']].min(axis=1)
        dataframe['emac'] = ta.SMA(dataframe['ha_close'], timeperiod=6)
        dataframe['emao'] = ta.SMA(dataframe['ha_open'], timeperiod=6)
        # Bollinger Bands (TV)
        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['bb_percent'] = (dataframe['bb_upperband'] - dataframe['bb_lowerband']) / dataframe['bb_middleband'] * 100
        # Elliot
        dataframe['EWO'] = EWO(dataframe, self.fast_ewo, self.slow_ewo)
        # RSI
        dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
        return dataframe

    def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        # ((dataframe['HARAMI'] < 0)|(dataframe['EVENINGSTAR'] < 0)|(dataframe['3LINESTRIKE'] < 0)|(dataframe['ENGULFING'] > 0)|(dataframe['ABANDONEDBABY'] > 0)|(dataframe['INVERTEDHAMMER'] > 0)|(dataframe['ENGULFING'] > 0)|(dataframe['DOJI'] < 0)|(dataframe['DOJISTAR'] > 0)|(dataframe['MORNINGDOJISTAR'] > 0)|(dataframe['ABANDONEDBABY'] > 0))&
        # (dataframe['SPINNINGTOP'] == 0) &
        # (dataframe['emac'] < dataframe['emao']) &
        # ((dataframe['close'] < dataframe['bb_lowerband']) | ((dataframe['open'] < dataframe['bb_lowerband']) & (dataframe['close'] < dataframe['bb_middleband']))
        dataframe.loc[(dataframe['bb_percent'] > 0.2) & (dataframe['close'] < dataframe['bb_lowerband']) & ((dataframe['HARAMI'] != 0) | (dataframe['SPINNINGTOP'] < 0)) & (dataframe['EWO'] < 0) & (dataframe['EWO'] > -2.0) & (dataframe['rsi'] < 23), 'enter_long'] = 1
        return dataframe

    def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
        dataframe.loc[(dataframe['emao'] > dataframe['emac']) & (dataframe['close'] > dataframe['bb_middleband']), 'exit_long'] = 1
        return dataframe