def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) dataframe['rmi-slow'] = RMI(dataframe, length=21, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=8, mom=4) dataframe['roc'] = ta.ROC(dataframe, timeperiod=6) dataframe['mp'] = ta.RSI(dataframe['roc'], timeperiod=6) dataframe['rmi-up'] = np.where( dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rsi'] = ta.RSI(informative, timeperiod=14) informative['1d_high'] = informative['close'].rolling(24).max() informative['3d_low'] = informative['close'].rolling(72).min() informative['adr'] = informative['1d_high'] - informative['3d_low'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Misc. calculations regarding existing open positions (reset on every loop iteration) self.custom_trade_info[metadata['pair']] = trade_data = {} trade_data['active_trade'] = trade_data['other_trades'] = False if self.config['runmode'].value in ('live', 'dry_run'): active_trade = Trade.get_trades([Trade.pair == metadata['pair'], Trade.is_open.is_(True),]).all() other_trades = Trade.get_trades([Trade.pair != metadata['pair'], Trade.is_open.is_(True),]).all() if active_trade: current_rate = self.get_current_price(metadata['pair']) active_trade[0].adjust_min_max_rates(current_rate) trade_data['active_trade'] = True trade_data['current_profit'] = active_trade[0].calc_profit_ratio(current_rate) trade_data['peak_profit'] = active_trade[0].calc_profit_ratio(active_trade[0].max_rate) if other_trades: trade_data['other_trades'] = True total_other_profit = tuple(trade.calc_profit_ratio(self.get_current_price(trade.pair)) for trade in other_trades) trade_data['avg_other_profit'] = mean(total_other_profit) self.custom_trade_info[metadata['pair']] = trade_data # Set up other indicators dataframe['volume_mean_slow'] = dataframe['volume'].rolling(window=24).mean() dataframe['rmi-slow'] = RMI(dataframe, length=20, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=9, mom=3) dataframe['sar'] = ta.SAR(dataframe) macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] dataframe['macdhist'] = macd['macdhist'] # Trend calculations dataframe['max'] = dataframe['high'].rolling(12).max() dataframe['min'] = dataframe['low'].rolling(12).min() dataframe['upper'] = np.where(dataframe['max'] > dataframe['max'].shift(),1,0) dataframe['lower'] = np.where(dataframe['min'] < dataframe['min'].shift(),1,0) dataframe['up_trend'] = np.where(dataframe['upper'].rolling(3, min_periods=1).sum() != 0,1,0) dataframe['dn_trend'] = np.where(dataframe['lower'].rolling(3, min_periods=1).sum() != 0,1,0) # Informative Pair Indicators informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['ema3'] = ta.EMA(informative, timeperiod=3) informative['ema12'] = ta.EMA(informative, timeperiod=12) inf_macd = ta.MACD(informative) informative['macd'] = inf_macd['macd'] informative['macdsignal'] = inf_macd['macdsignal'] informative['macdhist'] = inf_macd['macdhist'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Populate/update the trade data if there is any, set trades to false if not live/dry self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) dataframe['rsi'] = np.nan_to_num(ta.RSI(dataframe, timeperiod=5)) dataframe['emarsi'] = np.nan_to_num( ta.EMA(dataframe['rsi'], timeperiod=5)) dataframe['adx'] = np.nan_to_num(ta.ADX(dataframe)) dataframe['minusdi'] = np.nan_to_num(ta.MINUS_DI(dataframe)) dataframe['minusdiema'] = np.nan_to_num( ta.EMA(dataframe['minusdi'], timeperiod=25)) dataframe['plusdi'] = np.nan_to_num(ta.PLUS_DI(dataframe)) dataframe['plusdiema'] = np.nan_to_num( ta.EMA(dataframe['plusdi'], timeperiod=5)) dataframe['lowsma'] = np.nan_to_num(ta.EMA(dataframe, timeperiod=60)) dataframe['highsma'] = np.nan_to_num(ta.EMA(dataframe, timeperiod=120)) dataframe['fastsma'] = np.nan_to_num(ta.SMA(dataframe, timeperiod=120)) dataframe['slowsma'] = np.nan_to_num(ta.SMA(dataframe, timeperiod=240)) dataframe['bigup'] = dataframe['fastsma'].gt(dataframe['slowsma']) & ( (dataframe['fastsma'] - dataframe['slowsma']) > dataframe['close'] / 300) dataframe['bigdown'] = ~dataframe['bigup'] dataframe['trend'] = dataframe['fastsma'] - dataframe['slowsma'] dataframe['preparechangetrend'] = dataframe['trend'].gt( dataframe['trend'].shift()) dataframe['preparechangetrendconfirm'] = dataframe[ 'preparechangetrend'] & dataframe['trend'].shift().gt( dataframe['trend'].shift(2)) dataframe['continueup'] = dataframe['slowsma'].gt( dataframe['slowsma'].shift()) & dataframe['slowsma'].shift().gt( dataframe['slowsma'].shift(2)) dataframe['delta'] = dataframe['fastsma'] - dataframe['fastsma'].shift( ) dataframe['slowingdown'] = dataframe['delta'].lt( dataframe['delta'].shift()) dataframe['rmi-slow'] = RMI(dataframe, length=21, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=8, mom=4) dataframe['rmi-up'] = np.where( dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) # Relative Momentum Index dataframe['rmi-slow'] = RMI(dataframe, length=21, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=8, mom=4) # Momentum Pinball dataframe['roc'] = ta.ROC(dataframe, timeperiod=6) dataframe['mp'] = ta.RSI(dataframe['roc'], timeperiod=6) # Trend Calculations dataframe['rmi-up'] = np.where( dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) # Informative for STAKE/FIAT and COIN/FIAT on default timeframe, only relevant if stake currency is BTC or ETH if self.config['stake_currency'] in ('BTC', 'ETH'): coin, stake = metadata['pair'].split('/') fiat = self.custom_fiat coin_fiat = f"{coin}/{fiat}" stake_fiat = f"{stake}/{fiat}" # COIN/FIAT (e.g. XLM/USD) - timeframe coin_fiat_tf = self.dp.get_pair_dataframe(pair=coin_fiat, timeframe=self.timeframe) dataframe[f"{fiat}_rsi"] = ta.RSI(coin_fiat_tf, timeperiod=14) # STAKE/FIAT (e.g. BTC/USD) - inf_timeframe stake_fiat_tf = self.dp.get_pair_dataframe( pair=stake_fiat, timeframe=self.timeframe) stake_fiat_inf_tf = self.dp.get_pair_dataframe( pair=stake_fiat, timeframe=self.inf_timeframe) dataframe[f"{stake}_rsi"] = ta.RSI(stake_fiat_tf, timeperiod=14) dataframe[f"{stake}_rmi_{self.inf_timeframe}"] = RMI( stake_fiat_inf_tf, length=21, mom=5) # Informative indicators for current pair on inf_timeframe informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rsi'] = ta.RSI(informative, timeperiod=14) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Misc calculations regarding existing open positions self.custom_trade_info[metadata['pair']] = trade_data = {} trade_data['active_trade'] = trade_data['other_trades'] = False if self.config['runmode'].value in ('live', 'dry_run'): active_trade = Trade.get_trades([Trade.pair == metadata['pair'], Trade.is_open.is_(True),]).all() other_trades = Trade.get_trades([Trade.pair != metadata['pair'], Trade.is_open.is_(True),]).all() if active_trade: trade_data['active_trade'] = True trade_data['current_profit'] = active_trade[0].calc_profit_ratio(rate=self.get_current_price(metadata['pair'])) trade_data['peak_profit'] = active_trade[0].calc_profit_ratio(rate=active_trade[0].max_rate) trade_data['current_peak_ratio'] = (trade_data['current_profit'] / trade_data['peak_profit']) if other_trades: trade_data['other_trades'] = True total_other_profit = sum(trade.calc_profit_ratio(rate=self.get_current_price(trade.pair)) for trade in other_trades) trade_data['avg_other_profit'] = total_other_profit / len(other_trades) self.custom_trade_info[metadata['pair']] = trade_data # Set up other indicators dataframe['volume_mean_slow'] = dataframe['volume'].rolling(window=24).mean() dataframe['rmi-slow'] = RMI(dataframe, length=20, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=9, mom=3) dataframe['sar'] = ta.SAR(dataframe) # Trend calculations dataframe['max'] = dataframe['high'].rolling(12).max() dataframe['min'] = dataframe['low'].rolling(12).min() dataframe['upper'] = np.where(dataframe['max'] > dataframe['max'].shift(),1,0) dataframe['lower'] = np.where(dataframe['min'] < dataframe['min'].shift(),1,0) dataframe['up_trend'] = np.where(dataframe['upper'].rolling(3, min_periods=1).sum() != 0,1,0) dataframe['dn_trend'] = np.where(dataframe['lower'].rolling(3, min_periods=1).sum() != 0,1,0) # Consensus dashboard based on default timeframe and informative pair # Example: https://www.tradingview.com/symbols/BTCUSD/technicals/ # Code: https://github.com/freqtrade/technical/blob/master/technical/tradingview/__init__.py consensus = tv.SummaryConsensus(dataframe).score() dataframe['tv-consensus-sell'] = consensus['sell_agreement'] dataframe['tv-consensus-buy'] = consensus['buy_agreement'] informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) consensus_inf = tv.SummaryConsensus(informative).score() informative['tv-consensus-sell'] = consensus_inf['sell_agreement'] informative['tv-consensus-buy'] = consensus_inf['buy_agreement'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) # dataframe.to_csv('user_data/foo.csv') return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: self.custom_trade_info[metadata['pair']] = self.populate_trades(metadata['pair']) # Base timeframe indicators dataframe['rmi-slow'] = RMI(dataframe, length=21, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=8, mom=4) # Momentum Pinball: dataframe['roc'] = ta.ROC(dataframe, timeperiod=6) dataframe['mp'] = ta.RSI(dataframe['roc'], timeperiod=6) # RMI Trends and Peaks dataframe['rmi-up'] = np.where(dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(),1,0) dataframe['rmi-dn'] = np.where(dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(),1,0) dataframe['rmi-up-trend'] = np.where(dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2,1,0) dataframe['rmi-dn-trend'] = np.where(dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2,1,0) dataframe['rmi-max'] = dataframe['rmi-slow'].rolling(10, min_periods=1).max() # See: https://github.com/freqtrade/technical/blob/master/technical/indicators/indicators.py#L1059 # matype = vidya, src = hl2 dataframe = PMAX(dataframe, period=10, multiplier=3, length=10, MAtype=5, src=2) # Other stake specific informative indicators # TODO: Re-evaluate the value of these informative indicators if self.config['stake_currency'] in ('BTC', 'ETH'): coin, stake = metadata['pair'].split('/') fiat = self.custom_fiat coin_fiat = f"{coin}/{fiat}" stake_fiat = f"{stake}/{fiat}" coin_fiat_tf = self.dp.get_pair_dataframe(pair=coin_fiat, timeframe=self.timeframe) dataframe[f"{fiat}_rsi"] = ta.RSI(coin_fiat_tf, timeperiod=14) stake_fiat_tf = self.dp.get_pair_dataframe(pair=stake_fiat, timeframe=self.timeframe) stake_fiat_inf_tf = self.dp.get_pair_dataframe(pair=stake_fiat, timeframe=self.inf_timeframe) dataframe[f"{stake}_rsi"] = ta.RSI(stake_fiat_tf, timeperiod=14) dataframe[f"{stake}_rmi_{self.inf_timeframe}"] = RMI(stake_fiat_inf_tf, length=21, mom=5) # Base pair informative timeframe indicators informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rsi'] = ta.RSI(informative, timeperiod=14) # Get the "average day range" between the 1d high and 3d low to set up guards informative['1d_high'] = informative['close'].rolling(24).max() informative['3d_low'] = informative['close'].rolling(72).min() informative['adr'] = informative['1d_high'] - informative['3d_low'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) dataframe.to_csv('user_data/foo.csv') return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: bollinger = qtpylib.bollinger_bands(dataframe['close'], window=20, stds=2) dataframe['bb_lowerband'] = bollinger['lower'] dataframe['bb_middleband'] = bollinger['mid'] dataframe['bb_upperband'] = bollinger['upper'] dataframe['bb_width'] = ( (dataframe['bb_upperband'] - dataframe['bb_lowerband']) / dataframe['bb_middleband']) dataframe['bb_bottom_cross'] = qtpylib.crossed_below( dataframe['close'], dataframe['bb_lowerband']).astype('int') dataframe['rsi'] = ta.RSI(dataframe, timeperiod=10) dataframe['plus_di'] = ta.PLUS_DI(dataframe) dataframe['minus_di'] = ta.MINUS_DI(dataframe) dataframe['cci'] = ta.CCI(dataframe, 30) dataframe['mfi'] = ta.MFI(dataframe, timeperiod=14) dataframe['cmf'] = chaikin_mf(dataframe) dataframe['rmi'] = RMI(dataframe, length=8, mom=4) stoch = ta.STOCHRSI(dataframe, 15, 20, 2, 2) dataframe['srsi_fk'] = stoch['fastk'] dataframe['srsi_fd'] = stoch['fastd'] dataframe['fastEMA'] = ta.EMA(dataframe['volume'], timeperiod=12) dataframe['slowEMA'] = ta.EMA(dataframe['volume'], timeperiod=26) dataframe['pvo'] = ((dataframe['fastEMA'] - dataframe['slowEMA']) / dataframe['slowEMA']) * 100 dataframe['is_dip'] = ((dataframe['rmi'] < 20) & (dataframe['cci'] <= -150) & (dataframe['srsi_fk'] < 20) # Maybe comment mfi and cmf to make more trades & (dataframe['mfi'] < 25) & (dataframe['cmf'] <= -0.1)).astype('int') dataframe['is_break'] = ( (dataframe['bb_width'] > 0.025) & (dataframe['bb_bottom_cross'].rolling(10).sum() > 1) & (dataframe['close'] < 0.99 * dataframe['bb_lowerband']) ).astype('int') dataframe['buy_signal'] = ((dataframe['is_dip'] > 0) & (dataframe['is_break'] > 0)).astype('int') return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: self.custom_trade_info[metadata['pair']] = self.populate_trades(metadata['pair']) dataframe['rmi-slow'] = RMI(dataframe, length=21, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=8, mom=4) dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14) dataframe['rmi-up'] = np.where(dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(),1,0) dataframe['rmi-dn'] = np.where(dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(),1,0) dataframe['rmi-up-trend'] = np.where(dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2,1,0) dataframe['rmi-dn-trend'] = np.where(dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2,1,0) informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rsi'] = ta.RSI(informative, timeperiod=14) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) dataframe['bull'] = dataframe[f"rsi_{self.inf_timeframe}"].gt(60).astype('int') * 20 return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['sar'] = ta.SAR(dataframe) dataframe['rmi'] = RMI(dataframe) dataframe['kama-3'] = ta.KAMA(dataframe, timeperiod=3) dataframe['kama-21'] = ta.KAMA(dataframe, timeperiod=21) macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] dataframe['macdhist'] = macd['macdhist'] dataframe['volume_ma'] = dataframe['volume'].rolling(window=24).mean() return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['volume_mean_slow'] = dataframe['volume'].rolling(window=24).mean() dataframe['RMI'] = RMI(dataframe) dataframe['sar'] = ta.SAR(dataframe) dataframe['max'] = dataframe['high'].rolling(60).max() dataframe['min'] = dataframe['low'].rolling(60).min() dataframe['upper'] = np.where(dataframe['max'] > dataframe['max'].shift(),1,0) dataframe['lower'] = np.where(dataframe['min'] < dataframe['min'].shift(),1,0) dataframe['up_trend'] = np.where(dataframe['upper'].rolling(10, min_periods=1).sum() != 0,1,0) dataframe['dn_trend'] = np.where(dataframe['lower'].rolling(10, min_periods=1).sum() != 0,1,0) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Populate/update the trade data if there is any, set trades to false if not live/dry self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) # Momentum Pinball dataframe['roc'] = ta.ROC(dataframe, timeperiod=1) dataframe['mp'] = ta.RSI(dataframe['roc'], timeperiod=3) # MA Streak dataframe['mac'] = cta.macross(dataframe, 21, 55) dataframe['streak'] = cta.mastreak(dataframe, period=4) lookup_idxs = dataframe.index.values - ( abs(dataframe['streak'].values) + 1) valid_lookups = lookup_idxs >= 0 dataframe['sbc'] = np.nan dataframe.loc[valid_lookups, 'sbc'] = dataframe['close'].to_numpy()[ lookup_idxs[valid_lookups].astype(int)] dataframe['streak-roc'] = 100 * (dataframe['close'] - dataframe['sbc']) / dataframe['sbc'] # Percent Change Channel upper, mid, lower = cta.pcc(dataframe, period=20, mult=2) dataframe['pcc-lowerband'] = lower dataframe['pcc-upperband'] = upper # RMI Trend Strength dataframe['rmi'] = RMI(dataframe, length=21, mom=5) # RMI Trend Calculations dataframe['rmi-up'] = np.where( dataframe['rmi'] >= dataframe['rmi'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi'] <= dataframe['rmi'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Heikin Ashi Candles heikinashi = qtpylib.heikinashi(dataframe) dataframe['ha_open'] = heikinashi['open'] dataframe['ha_close'] = heikinashi['close'] dataframe['ha_high'] = heikinashi['high'] dataframe['ha_low'] = heikinashi['low'] # Set Up Bollinger Bands upper_bb1, mid_bb1, lower_bb1 = ta.BBANDS(dataframe['ha_close'], timeperiod=40) upper_bb2, mid_bb2, lower_bb2 = ta.BBANDS( qtpylib.typical_price(heikinashi), timeperiod=20) # only putting some bands into dataframe as the others are not used elsewhere in the strategy dataframe['lower-bb1'] = lower_bb1 dataframe['lower-bb2'] = lower_bb2 dataframe['mid-bb2'] = mid_bb2 dataframe['bb1-delta'] = (mid_bb1 - dataframe['lower-bb1']).abs() dataframe['closedelta'] = (dataframe['ha_close'] - dataframe['ha_close'].shift()).abs() dataframe['tail'] = (dataframe['ha_close'] - dataframe['ha_low']).abs() dataframe['ema_slow'] = ta.EMA(dataframe['ha_close'], timeperiod=48) dataframe['volume_mean_slow'] = dataframe['volume'].rolling( window=24).mean() dataframe['rsi'] = ta.RSI(heikinashi, timeperiod=14) dataframe['tema'] = ta.TEMA(heikinashi, timeperiod=9) dataframe['adx'] = ta.ADX(heikinashi) dataframe['rmi'] = RMI(heikinashi) dataframe['sar'] = ta.SAR(heikinashi) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Misc. calculations regarding existing open positions (reset on every loop iteration) self.custom_trade_info[metadata['pair']] = trade_data = {} trade_data['active_trade'] = trade_data['other_trades'] = False if self.config['runmode'].value in ('live', 'dry_run'): active_trade = Trade.get_trades([ Trade.pair == metadata['pair'], Trade.is_open.is_(True), ]).all() other_trades = Trade.get_trades([ Trade.pair != metadata['pair'], Trade.is_open.is_(True), ]).all() if active_trade: current_rate = self.get_current_price(metadata['pair']) active_trade[0].adjust_min_max_rates(current_rate) trade_data['active_trade'] = True trade_data['current_profit'] = active_trade[ 0].calc_profit_ratio(current_rate) trade_data['peak_profit'] = active_trade[0].calc_profit_ratio( active_trade[0].max_rate) if other_trades: trade_data['other_trades'] = True total_other_profit = tuple( trade.calc_profit_ratio(self.get_current_price(trade.pair)) for trade in other_trades) trade_data['avg_other_profit'] = mean(total_other_profit) self.custom_trade_info[metadata['pair']] = trade_data # Set up Bollinger Bands mid, lower = bollinger_bands(dataframe['close'], window_size=40, num_of_std=2) dataframe['lower'] = lower dataframe['bbdelta'] = (mid - dataframe['lower']).abs() dataframe['closedelta'] = (dataframe['close'] - dataframe['close'].shift()).abs() dataframe['tail'] = (dataframe['close'] - dataframe['low']).abs() bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb-lowerband'] = bollinger['lower'] dataframe['bb-middleband'] = bollinger['mid'] # Set up other indicators dataframe['volume-mean-slow'] = dataframe['volume'].rolling( window=24).mean() dataframe['rmi-slow'] = RMI(dataframe, length=20, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=9, mom=3) dataframe['rocr'] = ta.ROCR(dataframe, timeperiod=28) dataframe['ema-slow'] = ta.EMA(dataframe, timeperiod=50) # Trend Calculations dataframe['max'] = dataframe['high'].rolling(12).max() dataframe['min'] = dataframe['low'].rolling(12).min() dataframe['upper'] = np.where( dataframe['max'] > dataframe['max'].shift(), 1, 0) dataframe['lower'] = np.where( dataframe['min'] < dataframe['min'].shift(), 1, 0) dataframe['up_trend'] = np.where( dataframe['upper'].rolling(3, min_periods=1).sum() != 0, 1, 0) dataframe['dn_trend'] = np.where( dataframe['lower'].rolling(3, min_periods=1).sum() != 0, 1, 0) # Informative Pair Indicators informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rocr'] = ta.ROCR(informative, timeperiod=168) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Misc calculations regarding existing open positions if self.config['runmode'].value in ('live', 'dry_run'): self.custom_trade_info[metadata['pair']] = trade_data = {} trade_data['active_trade'] = trade_data['other_trades'] = False active_trade = Trade.get_trades([ Trade.pair == metadata['pair'], Trade.is_open.is_(True), ]).all() other_trades = Trade.get_trades([ Trade.pair != metadata['pair'], Trade.is_open.is_(True), ]).all() if active_trade: trade_data['active_trade'] = True trade_data['current_profit'] = active_trade[ 0].calc_profit_ratio( rate=self.get_current_price(metadata['pair'])) trade_data['peak_profit'] = active_trade[0].calc_profit_ratio( rate=active_trade[0].max_rate) trade_data['current_peak_ratio'] = ( trade_data['current_profit'] / trade_data['peak_profit']) if other_trades: trade_data['other_trades'] = True total_other_profit = sum( trade.calc_profit_ratio( rate=self.get_current_price(trade.pair)) for trade in other_trades) trade_data['avg_other_profit'] = total_other_profit / len( other_trades) self.custom_trade_info[metadata['pair']] = trade_data # Set up other indicators dataframe['volume_mean_slow'] = dataframe['volume'].rolling( window=24).mean() dataframe['rmi-slow'] = RMI(dataframe, length=20, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=9, mom=3) dataframe['sar'] = ta.SAR(dataframe) macd = ta.MACD(dataframe) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] dataframe['macdhist'] = macd['macdhist'] # Trend calculations dataframe['max'] = dataframe['high'].rolling(12).max() dataframe['min'] = dataframe['low'].rolling(12).min() dataframe['upper'] = np.where( dataframe['max'] > dataframe['max'].shift(), 1, 0) dataframe['lower'] = np.where( dataframe['min'] < dataframe['min'].shift(), 1, 0) dataframe['up_trend'] = np.where( dataframe['upper'].rolling(3, min_periods=1).sum() != 0, 1, 0) dataframe['dn_trend'] = np.where( dataframe['lower'].rolling(3, min_periods=1).sum() != 0, 1, 0) # Set Up Bollinger Bands upper_bb, mid_bb, lower_bb = ta.BBANDS(dataframe['close'], timeperiod=20) dataframe['upper-bb'] = upper_bb dataframe['lower-bb'] = lower_bb dataframe['mid-bb'] = mid_bb # did candle low break-out of bottom bband? dataframe['breakout-low'] = np.where( dataframe['low'] <= dataframe['lower-bb'], True, False) last = np.nan for i in range(len(dataframe)): if dataframe.loc[i, 'breakout-low']: last = i dataframe.loc[i, 'breakout-low-last'] = i - last return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Populate/update the trade data if there is any, set trades to false if not live/dry self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) # Momentum Pinball dataframe['roc'] = ta.ROC(dataframe, timeperiod=1) dataframe['mp'] = ta.RSI(dataframe['roc'], timeperiod=3) # MA Streak dataframe['mac'] = ci_mac(dataframe, 20, 50) dataframe['streak'] = ci_mastreak(dataframe, period=4) streak = abs(int(dataframe['streak'].iloc[-1])) streak_back_close = dataframe['close'].shift(streak + 1) dataframe['streak-roc'] = 100 * (dataframe['close'] - streak_back_close) / streak_back_close # Percent Change Channel pcc = ci_pcc(dataframe, period=20, mult=2) dataframe['pcc-lowerband'] = pcc.lowerband dataframe['pcc-upperband'] = pcc.upperband # RMI Trend Strength dataframe['rmi'] = RMI(dataframe, length=21, mom=5) # RMI Trend Calculations dataframe['rmi-up'] = np.where( dataframe['rmi'] >= dataframe['rmi'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi'] <= dataframe['rmi'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) # Informative for STAKE/FIAT and COIN/FIAT on default timeframe, only relevant if stake currency is BTC or ETH if self.config['stake_currency'] in ('BTC', 'ETH'): coin, stake = metadata['pair'].split('/') fiat = self.custom_fiat coin_fiat = f"{coin}/{fiat}" stake_fiat = f"{stake}/{fiat}" # COIN/FIAT (e.g. XLM/USD) - timeframe coin_fiat_tf = self.dp.get_pair_dataframe(pair=coin_fiat, timeframe=self.timeframe) dataframe[f"{fiat}_rsi"] = ta.RSI(coin_fiat_tf, timeperiod=14) # STAKE/FIAT (e.g. BTC/USD) - inf_timeframe stake_fiat_tf = self.dp.get_pair_dataframe( pair=stake_fiat, timeframe=self.timeframe) stake_fiat_inf_tf = self.dp.get_pair_dataframe( pair=stake_fiat, timeframe=self.inf_timeframe) dataframe[f"{stake}_rsi"] = ta.RSI(stake_fiat_tf, timeperiod=14) dataframe[f"{stake}_rmi_{self.inf_timeframe}"] = RMI( stake_fiat_inf_tf, length=21, mom=5) # Informative indicators for current pair on inf_timeframe informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) informative['rsi'] = ta.RSI(informative, timeperiod=14) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Populate/update the trade data if there is any, set trades to false if not live/dry self.custom_trade_info[metadata['pair']] = self.populate_trades( metadata['pair']) # Set up primary indicators dataframe['rmi-slow'] = RMI(dataframe, length=20, mom=5) dataframe['rmi-fast'] = RMI(dataframe, length=9, mom=3) dataframe['vidya'] = VIDYA(dataframe) macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9) dataframe['macd'] = macd['macd'] dataframe['macdsignal'] = macd['macdsignal'] dataframe['macdhist'] = macd['macdhist'] dataframe['kama-fast'] = ta.KAMA(dataframe, timeperiod=5) dataframe['kama-slow'] = ta.KAMA(dataframe, timeperiod=13) # Trend Calculations dataframe['rmi-up'] = np.where( dataframe['rmi-slow'] >= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-dn'] = np.where( dataframe['rmi-slow'] <= dataframe['rmi-slow'].shift(), 1, 0) dataframe['rmi-up-trend'] = np.where( dataframe['rmi-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['rmi-dn-trend'] = np.where( dataframe['rmi-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['vdy-up'] = np.where( dataframe['vidya'] >= dataframe['vidya'].shift(), 1, 0) dataframe['vdy-dn'] = np.where( dataframe['vidya'] <= dataframe['vidya'].shift(), 1, 0) dataframe['vdy-up-trend'] = np.where( dataframe['vdy-up'].rolling(3, min_periods=1).sum() >= 2, 1, 0) dataframe['vdy-dn-trend'] = np.where( dataframe['vdy-dn'].rolling(3, min_periods=1).sum() >= 2, 1, 0) # Informative for STAKE/FIAT and COIN/FIAT on default timeframe, only relevant if stake currency is BTC or ETH if self.config['stake_currency'] in ('BTC', 'ETH'): coin, stake = metadata['pair'].split('/') coin_fiat = f"{coin}/{self.custom_fiat}" stake_fiat = f"{self.config['stake_currency']}/{self.custom_fiat}" coin_fiat_inf = self.dp.get_pair_dataframe( pair=coin_fiat, timeframe=self.timeframe) stake_fiat_inf = self.dp.get_pair_dataframe( pair=stake_fiat, timeframe=self.timeframe) dataframe[f"{self.custom_fiat}_rmi-slow"] = RMI(coin_fiat_inf, length=20, mom=5) dataframe[f"{self.config['stake_currency']}_rmi-slow"] = RMI( stake_fiat_inf, length=20, mom=5) # Informative for current pair on inf_timeframe informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=self.inf_timeframe) inf_macd = ta.MACD(informative, fastperiod=12, slowperiod=26, signalperiod=9) informative['macd'] = inf_macd['macd'] informative['macdsignal'] = inf_macd['macdsignal'] informative['macdhist'] = inf_macd['macdhist'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, self.inf_timeframe, ffill=True) return dataframe