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 […]