Skip to content

Commit 3e21a6a

Browse files
committed
X2: buy 1 - rework (dummy).
1 parent ac3b9ba commit 3e21a6a

1 file changed

Lines changed: 372 additions & 1 deletion

File tree

experimental/NostalgiaForInfinityX2.py

Lines changed: 372 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,380 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
685685
item_buy_logic = []
686686
item_buy_logic.append(reduce(lambda x, y: x & y, item_buy_protection_list))
687687

688-
# Condition #1 - Describe
688+
# Condition #1 -
689+
690+
# Long mode, bear
691+
if all(c in ['11'] for c in buy_tags):
692+
sell, signal_name = self.sell_long_bear(current_profit, max_profit, max_loss, last_candle, previous_candle_1, previous_candle_2, previous_candle_3, previous_candle_4, previous_candle_5, trade, current_time, buy_tag)
693+
if sell and (signal_name is not None):
694+
return f"{signal_name} ( {buy_tag})"
695+
696+
return None
697+
698+
def informative_pairs(self):
699+
# get access to all pairs available in whitelist.
700+
pairs = self.dp.current_whitelist()
701+
# Assign tf to each pair so they can be downloaded and cached for strategy.
702+
informative_pairs = []
703+
for info_timeframe in self.info_timeframes:
704+
informative_pairs.extend([(pair, info_timeframe) for pair in pairs])
705+
706+
if self.config['stake_currency'] in ['USDT','BUSD','USDC','DAI','TUSD','PAX','USD','EUR','GBP']:
707+
btc_info_pair = f"BTC/{self.config['stake_currency']}"
708+
else:
709+
btc_info_pair = "BTC/USDT"
710+
711+
informative_pairs.extend([(btc_info_pair, btc_info_timeframe) for btc_info_timeframe in self.btc_info_timeframes])
712+
713+
return informative_pairs
714+
715+
def informative_1d_indicators(self, metadata: dict, info_timeframe) -> DataFrame:
716+
tik = time.perf_counter()
717+
assert self.dp, "DataProvider is required for multiple timeframes."
718+
# Get the informative pair
719+
informative_1d = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=info_timeframe)
720+
721+
# Indicators
722+
# -----------------------------------------------------------------------------------------
723+
informative_1d['rsi_14'] = ta.RSI(informative_1d, timeperiod=14)
724+
725+
# Performance logging
726+
# -----------------------------------------------------------------------------------------
727+
tok = time.perf_counter()
728+
log.debug(f"[{metadata['pair']}] informative_1d_indicators took: {tok - tik:0.4f} seconds.")
729+
730+
return informative_1d
731+
732+
def informative_4h_indicators(self, metadata: dict, info_timeframe) -> DataFrame:
733+
tik = time.perf_counter()
734+
assert self.dp, "DataProvider is required for multiple timeframes."
735+
# Get the informative pair
736+
informative_4h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=info_timeframe)
737+
738+
# Indicators
739+
# -----------------------------------------------------------------------------------------
740+
# RSI
741+
informative_4h['rsi_14'] = ta.RSI(informative_4h, timeperiod=14, fillna=True)
742+
743+
# SMA
744+
informative_4h['sma_200'] = ta.SMA(informative_4h, timeperiod=200, fillna=True)
745+
746+
# Williams %R
747+
informative_4h['r_14'] = williams_r(informative_4h, period=14)
748+
informative_4h['r_480'] = williams_r(informative_4h, period=480)
749+
750+
# Performance logging
751+
# -----------------------------------------------------------------------------------------
752+
tok = time.perf_counter()
753+
log.debug(f"[{metadata['pair']}] informative_1d_indicators took: {tok - tik:0.4f} seconds.")
754+
755+
return informative_4h
756+
757+
def informative_1h_indicators(self, metadata: dict, info_timeframe) -> DataFrame:
758+
tik = time.perf_counter()
759+
assert self.dp, "DataProvider is required for multiple timeframes."
760+
# Get the informative pair
761+
informative_1h = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=info_timeframe)
762+
763+
# Indicators
764+
# -----------------------------------------------------------------------------------------
765+
# RSI
766+
informative_1h['rsi_14'] = ta.RSI(informative_1h, timeperiod=14)
767+
768+
# SMA
769+
informative_1h['sma_50'] = ta.SMA(informative_1h, timeperiod=50)
770+
informative_1h['sma_100'] = ta.SMA(informative_1h, timeperiod=100)
771+
informative_1h['sma_200'] = ta.SMA(informative_1h, timeperiod=200)
772+
773+
# BB
774+
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(informative_1h), window=20, stds=2)
775+
informative_1h['bb20_2_low'] = bollinger['lower']
776+
informative_1h['bb20_2_mid'] = bollinger['mid']
777+
informative_1h['bb20_2_upp'] = bollinger['upper']
778+
779+
# Williams %R
780+
informative_1h['r_14'] = williams_r(informative_1h, period=14)
781+
informative_1h['r_480'] = williams_r(informative_1h, period=480)
782+
783+
# Performance logging
784+
# -----------------------------------------------------------------------------------------
785+
tok = time.perf_counter()
786+
log.debug(f"[{metadata['pair']}] informative_1h_indicators took: {tok - tik:0.4f} seconds.")
787+
788+
return informative_1h
789+
790+
def informative_15m_indicators(self, metadata: dict, info_timeframe) -> DataFrame:
791+
tik = time.perf_counter()
792+
assert self.dp, "DataProvider is required for multiple timeframes."
793+
794+
# Get the informative pair
795+
informative_15m = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe=info_timeframe)
796+
797+
# Indicators
798+
# -----------------------------------------------------------------------------------------
799+
informative_15m['rsi_14'] = ta.RSI(informative_15m, timeperiod=14)
800+
801+
# Performance logging
802+
# -----------------------------------------------------------------------------------------
803+
tok = time.perf_counter()
804+
log.debug(f"[{metadata['pair']}] informative_15m_indicators took: {tok - tik:0.4f} seconds.")
805+
806+
return informative_15m
807+
808+
# Coin Pair Base Timeframe Indicators
809+
# ---------------------------------------------------------------------------------------------
810+
def base_tf_5m_indicators(self, metadata: dict, dataframe: DataFrame) -> DataFrame:
811+
tik = time.perf_counter()
812+
813+
# Indicators
814+
# -----------------------------------------------------------------------------------------
815+
# RSI
816+
dataframe['rsi_14'] = ta.RSI(dataframe, timeperiod=14)
817+
818+
# EMA
819+
dataframe['ema_12'] = ta.EMA(dataframe, timeperiod=12)
820+
dataframe['ema_26'] = ta.EMA(dataframe, timeperiod=26)
821+
dataframe['ema_50'] = ta.EMA(dataframe, timeperiod=50)
822+
dataframe['ema_200'] = ta.EMA(dataframe, timeperiod=200)
823+
824+
# SMA
825+
dataframe['sma_50'] = ta.SMA(dataframe, timeperiod=50)
826+
dataframe['sma_200'] = ta.SMA(dataframe, timeperiod=200)
827+
828+
# BB 20 - STD2
829+
bb_20_std2 = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
830+
dataframe['bb20_2_low'] = bb_20_std2['lower']
831+
dataframe['bb20_2_mid'] = bb_20_std2['mid']
832+
dataframe['bb20_2_upp'] = bb_20_std2['upper']
833+
834+
# Williams %R
835+
dataframe['r_14'] = williams_r(dataframe, period=14)
836+
dataframe['r_480'] = williams_r(dataframe, period=480)
837+
838+
# For sell checks
839+
dataframe['crossed_below_ema_12_26'] = qtpylib.crossed_below(dataframe['ema_12'], dataframe['ema_26'])
840+
841+
# Global protections
842+
# -----------------------------------------------------------------------------------------
843+
if not self.config['runmode'].value in ('live', 'dry_run'):
844+
# Backtest age filter
845+
dataframe['bt_agefilter_ok'] = False
846+
dataframe.loc[dataframe.index > (12 * 24 * self.bt_min_age_days),'bt_agefilter_ok'] = True
847+
else:
848+
# Exchange downtime protection
849+
dataframe['live_data_ok'] = (dataframe['volume'].rolling(window=72, min_periods=72).min() > 0)
850+
851+
# Performance logging
852+
# -----------------------------------------------------------------------------------------
853+
tok = time.perf_counter()
854+
log.debug(f"[{metadata['pair']}] base_tf_5m_indicators took: {tok - tik:0.4f} seconds.")
855+
856+
return dataframe
857+
858+
# Coin Pair Indicator Switch Case
859+
# ---------------------------------------------------------------------------------------------
860+
def info_switcher(self, metadata: dict, info_timeframe) -> DataFrame:
861+
if info_timeframe == '1d':
862+
return self.informative_1d_indicators(metadata, info_timeframe)
863+
elif info_timeframe == '4h':
864+
return self.informative_4h_indicators(metadata, info_timeframe)
865+
elif info_timeframe == '1h':
866+
return self.informative_1h_indicators(metadata, info_timeframe)
867+
elif info_timeframe == '15m':
868+
return self.informative_15m_indicators(metadata, info_timeframe)
869+
else:
870+
raise RuntimeError(f"{info_timeframe} not supported as informative timeframe for BTC pair.")
871+
872+
# BTC 1D Indicators
873+
# ---------------------------------------------------------------------------------------------
874+
def btc_info_1d_indicators(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
875+
tik = time.perf_counter()
876+
btc_info_1d = self.dp.get_pair_dataframe(btc_info_pair, btc_info_timeframe)
877+
# Indicators
878+
# -----------------------------------------------------------------------------------------
879+
btc_info_1d['rsi_14'] = ta.RSI(btc_info_1d, timeperiod=14)
880+
#btc_info_1d['pivot'], btc_info_1d['res1'], btc_info_1d['res2'], btc_info_1d['res3'], btc_info_1d['sup1'], btc_info_1d['sup2'], btc_info_1d['sup3'] = pivot_points(btc_info_1d, mode='fibonacci')
881+
882+
# Add prefix
883+
# -----------------------------------------------------------------------------------------
884+
ignore_columns = ['date']
885+
btc_info_1d.rename(columns=lambda s: f"btc_{s}" if s not in ignore_columns else s, inplace=True)
886+
887+
tok = time.perf_counter()
888+
log.debug(f"[{metadata['pair']}] btc_info_1d_indicators took: {tok - tik:0.4f} seconds.")
889+
890+
return btc_info_1d
891+
892+
# BTC 4h Indicators
893+
# ---------------------------------------------------------------------------------------------
894+
def btc_info_4h_indicators(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
895+
tik = time.perf_counter()
896+
btc_info_4h = self.dp.get_pair_dataframe(btc_info_pair, btc_info_timeframe)
897+
# Indicators
898+
# -----------------------------------------------------------------------------------------
899+
# RSI
900+
btc_info_4h['rsi_14'] = ta.RSI(btc_info_4h, timeperiod=14)
901+
902+
# SMA
903+
btc_info_4h['sma_200'] = ta.SMA(btc_info_4h, timeperiod=200)
904+
905+
# Add prefix
906+
# -----------------------------------------------------------------------------------------
907+
ignore_columns = ['date']
908+
btc_info_4h.rename(columns=lambda s: f"btc_{s}" if s not in ignore_columns else s, inplace=True)
909+
910+
tok = time.perf_counter()
911+
log.debug(f"[{metadata['pair']}] btc_info_4h_indicators took: {tok - tik:0.4f} seconds.")
912+
913+
return btc_info_4h
914+
915+
# BTC 1h Indicators
916+
# ---------------------------------------------------------------------------------------------
917+
def btc_info_1h_indicators(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
918+
tik = time.perf_counter()
919+
btc_info_1h = self.dp.get_pair_dataframe(btc_info_pair, btc_info_timeframe)
920+
# Indicators
921+
# -----------------------------------------------------------------------------------------
922+
btc_info_1h['rsi_14'] = ta.RSI(btc_info_1h, timeperiod=14)
923+
btc_info_1h['not_downtrend'] = ((btc_info_1h['close'] > btc_info_1h['close'].shift(2)) | (btc_info_1h['rsi_14'] > 50))
924+
925+
# Add prefix
926+
# -----------------------------------------------------------------------------------------
927+
ignore_columns = ['date']
928+
btc_info_1h.rename(columns=lambda s: f"btc_{s}" if s not in ignore_columns else s, inplace=True)
929+
930+
tok = time.perf_counter()
931+
log.debug(f"[{metadata['pair']}] btc_info_1h_indicators took: {tok - tik:0.4f} seconds.")
932+
933+
return btc_info_1h
934+
935+
# BTC 15m Indicators
936+
# ---------------------------------------------------------------------------------------------
937+
def btc_info_15m_indicators(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
938+
tik = time.perf_counter()
939+
btc_info_15m = self.dp.get_pair_dataframe(btc_info_pair, btc_info_timeframe)
940+
# Indicators
941+
# -----------------------------------------------------------------------------------------
942+
btc_info_15m['rsi_14'] = ta.RSI(btc_info_15m, timeperiod=14)
943+
944+
# Add prefix
945+
# -----------------------------------------------------------------------------------------
946+
ignore_columns = ['date']
947+
btc_info_15m.rename(columns=lambda s: f"btc_{s}" if s not in ignore_columns else s, inplace=True)
948+
949+
tok = time.perf_counter()
950+
log.debug(f"[{metadata['pair']}] btc_info_15m_indicators took: {tok - tik:0.4f} seconds.")
951+
952+
return btc_info_15m
953+
954+
# BTC 5m Indicators
955+
# ---------------------------------------------------------------------------------------------
956+
def btc_info_5m_indicators(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
957+
tik = time.perf_counter()
958+
btc_info_5m = self.dp.get_pair_dataframe(btc_info_pair, btc_info_timeframe)
959+
# Indicators
960+
# -----------------------------------------------------------------------------------------
961+
btc_info_5m['rsi_14'] = ta.RSI(btc_info_5m, timeperiod=14)
962+
963+
# Add prefix
964+
# -----------------------------------------------------------------------------------------
965+
ignore_columns = ['date']
966+
btc_info_5m.rename(columns=lambda s: f"btc_{s}" if s not in ignore_columns else s, inplace=True)
967+
968+
tok = time.perf_counter()
969+
log.debug(f"[{metadata['pair']}] btc_info_5m_indicators took: {tok - tik:0.4f} seconds.")
970+
971+
return btc_info_5m
972+
973+
# BTC Indicator Switch Case
974+
# ---------------------------------------------------------------------------------------------
975+
def btc_info_switcher(self, btc_info_pair, btc_info_timeframe, metadata: dict) -> DataFrame:
976+
if btc_info_timeframe == '1d':
977+
return self.btc_info_1d_indicators(btc_info_pair, btc_info_timeframe, metadata)
978+
elif btc_info_timeframe == '4h':
979+
return self.btc_info_4h_indicators(btc_info_pair, btc_info_timeframe, metadata)
980+
elif btc_info_timeframe == '1h':
981+
return self.btc_info_1h_indicators(btc_info_pair, btc_info_timeframe, metadata)
982+
elif btc_info_timeframe == '15m':
983+
return self.btc_info_15m_indicators(btc_info_pair, btc_info_timeframe, metadata)
984+
elif btc_info_timeframe == '5m':
985+
return self.btc_info_5m_indicators(btc_info_pair, btc_info_timeframe, metadata)
986+
else:
987+
raise RuntimeError(f"{btc_info_timeframe} not supported as informative timeframe for BTC pair.")
988+
989+
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
990+
tik = time.perf_counter()
991+
'''
992+
--> BTC informative indicators
993+
___________________________________________________________________________________________
994+
'''
995+
if self.config['stake_currency'] in ['USDT','BUSD','USDC','DAI','TUSD','PAX','USD','EUR','GBP']:
996+
btc_info_pair = f"BTC/{self.config['stake_currency']}"
997+
else:
998+
btc_info_pair = "BTC/USDT"
999+
1000+
for btc_info_timeframe in self.btc_info_timeframes:
1001+
btc_informative = self.btc_info_switcher(btc_info_pair, btc_info_timeframe, metadata)
1002+
dataframe = merge_informative_pair(dataframe, btc_informative, self.timeframe, btc_info_timeframe, ffill=True)
1003+
# Customize what we drop - in case we need to maintain some BTC informative ohlcv data
1004+
# Default drop all
1005+
drop_columns = {
1006+
'1d': [f"btc_{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1007+
'4h': [f"btc_{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1008+
'1h': [f"btc_{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1009+
'15m': [f"btc_{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1010+
'5m': [f"btc_{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1011+
}.get(btc_info_timeframe,[f"{s}_{btc_info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']])
1012+
drop_columns.append(f"date_{btc_info_timeframe}")
1013+
dataframe.drop(columns=dataframe.columns.intersection(drop_columns), inplace=True)
1014+
1015+
'''
1016+
--> Indicators on informative timeframes
1017+
___________________________________________________________________________________________
1018+
'''
1019+
for info_timeframe in self.info_timeframes:
1020+
info_indicators = self.info_switcher(metadata, info_timeframe)
1021+
dataframe = merge_informative_pair(dataframe, info_indicators, self.timeframe, info_timeframe, ffill=True)
1022+
# Customize what we drop - in case we need to maintain some informative timeframe ohlcv data
1023+
# Default drop all except base timeframe ohlcv data
1024+
drop_columns = {
1025+
'1d': [f"{s}_{info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1026+
'4h': [f"{s}_{info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1027+
'1h': [f"{s}_{info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']],
1028+
'15m': [f"{s}_{info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']]
1029+
}.get(info_timeframe,[f"{s}_{info_timeframe}" for s in ['date', 'open', 'high', 'low', 'close', 'volume']])
1030+
dataframe.drop(columns=dataframe.columns.intersection(drop_columns), inplace=True)
1031+
1032+
'''
1033+
--> The indicators for the base timeframe (5m)
1034+
___________________________________________________________________________________________
1035+
'''
1036+
dataframe = self.base_tf_5m_indicators(metadata, dataframe)
1037+
1038+
tok = time.perf_counter()
1039+
log.debug(f"[{metadata['pair']}] Populate indicators took a total of: {tok - tik:0.4f} seconds.")
1040+
1041+
return dataframe
1042+
1043+
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
1044+
conditions = []
1045+
dataframe.loc[:, 'buy_tag'] = ''
1046+
1047+
for buy_enable in self.buy_params:
1048+
index = int(buy_enable.split('_')[2])
1049+
item_buy_protection_list = [True]
1050+
if self.buy_params[f'{buy_enable}']:
1051+
1052+
# Buy conditions
1053+
# -----------------------------------------------------------------------------------------
1054+
item_buy_logic = []
1055+
item_buy_logic.append(reduce(lambda x, y: x & y, item_buy_protection_list))
1056+
1057+
# Condition #1 - Long mode bull. Uptrend.
6891058
if index == 1:
6901059
# Protections
1060+
item_buy_logic.append(dataframe['sma_50'] > dataframe['sma_200'])
1061+
item_buy_logic.append(dataframe['sma_50_1h'] > dataframe['sma_200_1h'])
6911062

6921063
# Logic
6931064
item_buy_logic.append(dataframe['rsi_14'] < 30.0)

0 commit comments

Comments
 (0)