DISCLAIMER
The codes in this post is just for educational purpose, and not to be used on live trading
There are times you might want to use an indicator that might not have been implemented by any of the available technical libraries. You have two options, (if possible) modify existing function/indicator or create one from scratch. In this post, we will see how to use existing functions to create new indicator.
Let’s say I want to calculate EMA of RSI from our example strategy. Instead of supplying close
column to the ema function, you can supply rsi
column instead. The code will look like
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['ema_9'] = ta.EMA(dataframe['close'], 9) dataframe['ema_20'] = ta.EMA(dataframe['close'], 20) dataframe['rsi'] = ta.RSI(dataframe['close'], 14) dataframe['ema_9_rsi'] = ta.EMA(dataframe['rsi'], 9) return dataframe
The full strategy code will look like this
from freqtrade.strategy import IStrategy, informative from pandas import DataFrame import freqtrade.vendor.qtpylib.indicators as qtpylib import talib.abstract as ta from freqtrade.persistence import Trade from datetime import datetime, timedelta from typing import Optional, Union class strat_template (IStrategy): def version(self) -> str: return "template-v1" INTERFACE_VERSION = 3 minimal_roi = { "0": 0.05 } stoploss = -0.05 timeframe = '15m' process_only_new_candles = True startup_candle_count = 999 use_custom_stoploss = True def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> float: sl_new = 1 if (current_time - timedelta(minutes=15) >= trade.open_date_utc): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) current_candle = dataframe.iloc[-1].squeeze() current_profit = trade.calc_profit_ratio(current_candle['close']) if (current_profit >= 0.03): sl_new = 0.01 return sl_new def custom_exit(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, **kwargs) -> Optional[Union[str, bool]]: if ((current_time - timedelta(minutes=15)) >= trade.open_date_utc): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) current_candle = dataframe.iloc[-1].squeeze() current_profit = trade.calc_profit_ratio(current_candle['close']) if (current_profit >= 0): if (current_candle['rsi'] >= 70): return "rsi_overbought" @informative('30m') def populate_indicators_inf1(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe['close'], 14) return dataframe @informative('1h') def populate_indicators_inf2(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = ta.RSI(dataframe['close'], 14) return dataframe def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['ema_9'] = ta.EMA(dataframe['close'], 9) dataframe['ema_20'] = ta.EMA(dataframe['close'], 20) dataframe['rsi'] = ta.RSI(dataframe['close'], 14) dataframe['ema_9_rsi'] = ta.EMA(dataframe['rsi'], 9) return dataframe def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ qtpylib.crossed_above(dataframe['ema_9'], dataframe['ema_20']) & (dataframe['rsi_30m'] < 50) & (dataframe['rsi_1h'] < 30) & (dataframe['ema_9_rsi'] < 70) & (dataframe['volume'] > 0) , ['enter_long', 'enter_tag'] ] = (1, 'golden cross') return dataframe def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ qtpylib.crossed_below(dataframe['ema_9'], dataframe['ema_20']) & (dataframe['volume'] > 0) , ['exit_long', 'exit_tag'] ] = (1, 'death cross') return dataframe
[…] Previous – Using multiple timeframes Next – Custom indicators part 1 […]
[…] Previous – Custom indicators part 1 […]
[…] Custom indicators part 1 […]