# --- Do not remove these libs --- from freqtrade.strategy.interface import IStrategy from pandas import DataFrame import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib from freqtrade.persistence import Trade from datetime import timedelta, datetime, timezone #from freqtrade.strategy.strategy_helper import merge_informative_pair from typing import Dict, List import numpy as np # -------------------------------- # 11-Aug-20 - seems to be good making a few trades 5 days 33 wins 7 losses AVE 0.41% tot ROI 17.14% class cryptohassle(IStrategy): INTERFACE_VERSION = 3 '\n\n author@: Sp0ngeB0bUK\n Title: Crypto Hassle \n Version: 0.1\n\n Heikin Ashi Candles - SSL Channel, Momentum cross supported by MACD\n \n ' #"192": -1 minimal_roi = {'0': 0.5} # Stoploss: stoploss = -0.2 # Trailing stop: trailing_stop = True trailing_stop_positive = 0.01 trailing_stop_positive_offset = 0.07 trailing_only_offset_is_reached = True # Optimal ticker interval for the strategy timeframe = '1h' # Optional order type mapping. order_types = {'entry': 'market', 'exit': 'market', 'stoploss': 'market', 'stoploss_on_exchange': True} # Configuration for main plot indicators. # Specifies `ema10` to be red, and `ema50` to be a shade of gray # Additional subplot RSI plot_config = {'main_plot': {'ha_ema9': {'color': 'green'}, 'ha_ema20': {'color': 'red'}}, 'subplots': {'ADX': {'ha_adx': {'color': 'blue'}}}} def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # # Heikin Ashi Strategy heikinashi = qtpylib.heikinashi(dataframe) # Heikinashi EMA #dataframe['ha_ema9'] = ta.EMA(heikinashi, timeperiod=9) #dataframe['ha_ema20'] = ta.EMA(heikinashi, timeperiod=20) # Heikinashi ADX #dataframe['ha_adx'] = ta.ADX(heikinashi) # HeikinAshi EMA cross to ADX cross rolling delta #dataframe['ha_adx_cross'] = qtpylib.crossed_above(dataframe['ha_adx'],25) # HeikinAhi EMA9 crossed above EMA20 #dataframe['ha_ema_cross_above'] = qtpylib.crossed_above(dataframe['ha_ema9'],dataframe['ha_ema20']) # HeikinAhi EMA9 crossed below EMA20 #dataframe['ha_ema_cross_below'] = qtpylib.crossed_below(dataframe['ha_ema9'],dataframe['ha_ema20']) # Heikin Ashi Momentum #Momentum dataframe['ha_mom'] = ta.MOM(heikinashi, timeperiod=14) dataframe['ha_mom_cross_above'] = qtpylib.crossed_above(dataframe['ha_mom'], 0) # Heikin Ashi Candles dataframe['ha_open'] = heikinashi['open'] dataframe['ha_close'] = heikinashi['close'] dataframe['ha_high'] = heikinashi['high'] dataframe['ha_low'] = heikinashi['low'] # Heikin Ashi MACD macd = ta.MACD(heikinashi) dataframe['ha_macd'] = macd['macd'] dataframe['ha_macdsignal'] = macd['macdsignal'] dataframe['ha_macdhist'] = macd['macdhist'] dataframe['ha_macd_cross_above'] = qtpylib.crossed_above(dataframe['ha_macd'], dataframe['ha_macdsignal']) # Heikin Ashi SSl Channels def SSLChannels(dataframe, length=10, mode='sma'): """ Source: https://www.tradingview.com/script/xzIoaIJC-SSL-channel/ Author: xmatthias Pinescript Author: ErwinBeckers SSL Channels. Average over highs and lows form a channel - lines "flip" when close crosses either of the 2 lines. Trading ideas: * Channel cross * as confirmation based on up > down for long MC - MODIFIED FOR HA CANDLES """ if mode not in 'sma': raise ValueError(f'Mode {mode} not supported yet') df = dataframe.copy() if mode == 'sma': df['smaHigh'] = df['ha_high'].rolling(length).mean() df['smaLow'] = df['ha_low'].rolling(length).mean() df['hlv'] = np.where(df['ha_close'] > df['smaHigh'], 1, np.where(df['ha_close'] < df['smaLow'], -1, np.NAN)) df['hlv'] = df['hlv'].ffill() df['ha_sslDown'] = np.where(df['hlv'] < 0, df['smaHigh'], df['smaLow']) df['ha_sslUp'] = np.where(df['hlv'] < 0, df['smaLow'], df['smaHigh']) return (df['ha_sslDown'], df['ha_sslUp']) ssl = SSLChannels(dataframe, 10) dataframe['ha_sslDown'] = ssl[0] dataframe['ha_sslUp'] = ssl[1] dataframe['ha_ssl_cross_above'] = qtpylib.crossed_above(dataframe['ha_sslUp'], dataframe['ha_sslDown']) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Heikin Ashi SSL Channels # Momentum # Heikin Ashi MacD # Volume dataframe.loc[(dataframe['ha_ssl_cross_above'].rolling(5).apply(lambda x: x.any(), raw=False) == 1) & (dataframe['ha_mom_cross_above'].rolling(5).apply(lambda x: x.any(), raw=False) == 1) & (dataframe['ha_macd_cross_above'].rolling(5).apply(lambda x: x.any(), raw=False) == 1) & (dataframe['volume'] > 1000), 'entry'] = 1 return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[qtpylib.crossed_below(dataframe['ha_sslUp'], dataframe['ha_sslDown']) & (dataframe['volume'] > 0), 'exit'] = 1 return dataframe