# GodStraNew Strategy # Author: @Mablue (Masoud Azizi) # github: https://github.com/mablue/ # freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces buy roi trailing sell --strategy GodStraNew # --- Do not remove these libs --- from datetime import timedelta, datetime from typing import Optional from freqtrade import data from freqtrade.persistence import Trade from freqtrade.strategy.parameters import CategoricalParameter, DecimalParameter, IntParameter, BooleanParameter from numpy.lib import math from freqtrade.strategy.interface import IStrategy import pandas from pandas import DataFrame import time import calendar from freqtrade.loggers import setup_logging from technical.indicators import cmf # -------------------------------- # Add your lib to import here # TODO: talib is fast but have not more indicators import talib.abstract as ta import freqtrade.vendor.qtpylib.indicators as qtpylib from functools import reduce import numpy as np from random import shuffle operators = [ "D", # Disabled gene ">", # Indicator, bigger than cross indicator "<", # Indicator, smaller than cross indicator "=", # Indicator, equal with cross indicator "C", # Indicator, crossed the cross indicator "CA", # Indicator, crossed above the cross indicator "CB", # Indicator, crossed below the cross indicator ">R", # Normalized indicator, bigger than real number "=R", # Normalized indicator, equal with real number "R", # Normalized indicator devided to cross indicator, bigger than real number "/=R", # Normalized indicator devided to cross indicator, equal with real number "/ 10) # TODO : it ill callculated in populate indicators. dataframe[indicator] = gene_calculator(dataframe, indicator) dataframe[crossed_indicator] = gene_calculator(dataframe, crossed_indicator) indicator_trend_sma = f"{indicator}-SMA-{TREND_CHECK_CANDLES}" if operator in ["UT", "DT", "OT", "CUT", "CDT", "COT"]: dataframe[indicator_trend_sma] = gene_calculator(dataframe, indicator_trend_sma) if operator == ">": condition = (dataframe[indicator].shift(decalage) > dataframe[crossed_indicator].shift(decalage)) elif operator == "=": condition = (np.isclose(dataframe[indicator].shift(decalage), dataframe[crossed_indicator].shift(decalage))) elif operator == "<": condition = (dataframe[indicator].shift(decalage) < dataframe[crossed_indicator].shift(decalage)) elif operator == "C": condition = ( (qtpylib.crossed_below(dataframe[indicator].shift(decalage), dataframe[crossed_indicator].shift(decalage))) | (qtpylib.crossed_above(dataframe[indicator].shift(decalage), dataframe[crossed_indicator].shift(decalage))) ) elif operator == "CA": condition = (qtpylib.crossed_above(dataframe[indicator].shift(decalage), dataframe[crossed_indicator].shift(decalage))) elif operator == "CB": condition = (qtpylib.crossed_below(dataframe[indicator].shift(decalage), dataframe[crossed_indicator].shift(decalage))) elif operator == ">R": condition = (dataframe[indicator].shift(decalage) > real_num) elif operator == "=R": condition = (np.isclose(dataframe[indicator].shift(decalage), real_num)) elif operator == "R": condition = (dataframe[indicator].shift(decalage).div(dataframe[crossed_indicator].shift(decalage)) > real_num) elif operator == "/=R": condition = (np.isclose(dataframe[indicator].shift(decalage).div(dataframe[crossed_indicator].shift(decalage)), real_num)) elif operator == "/ dataframe[indicator_trend_sma].shift(decalage)) elif operator == "DT": condition = (dataframe[indicator].shift(decalage) < dataframe[indicator_trend_sma].shift(decalage)) elif operator == "OT": condition = (np.isclose(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage))) elif operator == "CUT": condition = ( ( qtpylib.crossed_above(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage)) ) & ( dataframe[indicator].shift(decalage) > dataframe[indicator_trend_sma].shift(decalage) ) ) elif operator == "CDT": condition = ( ( qtpylib.crossed_below(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage)) ) & ( dataframe[indicator].shift(decalage) < dataframe[indicator_trend_sma].shift(decalage) ) ) elif operator == "COT": condition = ( ( ( qtpylib.crossed_below(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage)) ) | ( qtpylib.crossed_above(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage)) ) ) & ( np.isclose(dataframe[indicator].shift(decalage), dataframe[indicator_trend_sma].shift(decalage)) ) ) return condition, dataframe class GodStraJD3_7_5_4(IStrategy): # #################### RESULTS PASTE PLACE #################### # ROI table: minimal_roi = { "0": 10, # "600": 0.12, # "1200": 0.08, # "2400": 0.06, # "3600": 0.04, # "7289": 0 } # Stoploss: stoploss = -1 # Buy hypers timeframe = '5m' # Trailing stoploss trailing_stop = False trailing_stop_positive = 0.15 trailing_stop_positive_offset = 0.20 trailing_only_offset_is_reached = True plot_config = { # Main plot indicators (Moving averages, ...) 'main_plot': { 'bb_lowerband': {'color': 'red'}, 'bb_upperband': {'color': 'green'}, 'sma100': {'color': 'blue'}, 'sma10': {'color': 'yellow'}, 'min20': {'color': '#87e470'}, 'min50': {'color': '#ac3e2a'}, "min1.1": {'color': 'yellow'}, 'sma20': {'color': 'cyan'} }, 'subplots': { # Subplots - each dict defines one additional plot "BB": { 'bb_width': {'color': 'white'} }, # "Ind0": { # buy_crossed_indicator0: {'color': 'green'}, # buy_indicator0: {'color': 'red'} # }, "Cond": { 'cond1': {'color': 'yellow'}, }, # "Ind1": { # buy_indicator1: {'color': 'yellow'}, # buy_crossed_indicator1: {'color': 'pink'} # }, # "Ind2": { # buy_indicator2: {'color': 'cyan'}, # buy_crossed_indicator2: {'color': 'blue'}, # }, "Rsi": { 'rsi': {'color': 'pink'}, }, "Ecart": { 'normal_var_20': {'color': 'red'}, 'normal_var_50': {'color': 'yellow'}, }, # "rolling": { # 'bb_rolling': {'color': '#87e470'}, # "bb_rolling_min": {'color': '#ac3e2a'} # }, "percent": { "percent": {'color': 'green'}, "percent3": {'color': 'blue'}, "percent5": {'color': 'red'}, "distance_min": {'color': 'white'} } } } # #################### END OF RESULT PLACE #################### profit_no_change = False profit_old_sma10 = False profit_over_rsi = True profit_quick_gain = True profit_quick_gain_3 = True profit_quick_lost = False profit_short_loss = False profit_sma10 = True profit_sma20 = True profit_very_old_sma10 = False trades = list() # profit_no_change = BooleanParameter(default=True, space="buy") # profit_quick_lost = BooleanParameter(default=True, space="buy") # profit_sma10 = BooleanParameter(default=True, space="buy") # profit_sma20 = BooleanParameter(default=True, space="buy") # profit_quick_gain = BooleanParameter(default=True, space="buy") # profit_quick_gain_3 = BooleanParameter(default=True, space="buy") # profit_old_sma10 = BooleanParameter(default=True, space="buy") # profit_very_old_sma10 = BooleanParameter(default=True, space="buy") # profit_over_rsi = BooleanParameter(default=True, space="buy") # profit_short_loss = BooleanParameter(default=True, space="buy") # buy_signal_bb_width = DecimalParameter(0.06, 0.15, decimals=2, default=0.065, space='buy') buy_1_real_num = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy') buy_2_real_num = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy') buy_3_real_num = DecimalParameter(0, 2, decimals=2, default=0.67, space='buy') buy_min_horizon = IntParameter(50, 200, default=72, space='buy') buy_0 = BooleanParameter(default=True, space="buy") buy_2 = BooleanParameter(default=True, space="buy") buy_3 = BooleanParameter(default=True, space="buy") buy_0_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy') buy_2_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy') buy_3_percent20 = DecimalParameter(-0.1, 0.1, decimals=2, default=-0.02, space='buy') buy_1_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy') buy_2_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy') buy_3_distance = DecimalParameter(-0.1, 0.1, decimals=2, default=0.02, space='buy') buy_1_min = DecimalParameter(1, 1.03, decimals=3, default=1.02, space='buy') buy_2_min = DecimalParameter(1, 1.03, decimals=3, default=1.02, space='buy') buy_3_min = DecimalParameter(1, 1.03, decimals=3, default=1.02, space='buy') buy_1_normal_var = DecimalParameter(0, 5, decimals=1, default=0, space='buy') buy_2_normal_var = DecimalParameter(0, 5, decimals=1, default=0, space='buy') buy_3_normal_var = DecimalParameter(0, 5, decimals=1, default=0, space='buy') buy_1_decalage_deb = IntParameter(1, 3, default=5, space='buy') buy_2_decalage_deb = IntParameter(1, 3, default=5, space='buy') buy_3_decalage_deb = IntParameter(1, 3, default=5, space='buy') buy_1_decalage = IntParameter(buy_1_decalage_deb.value + 1, 8, default=5, space='buy') buy_2_decalage = IntParameter(buy_2_decalage_deb.value + 1, 8, default=5, space='buy') buy_3_decalage = IntParameter(buy_3_decalage_deb.value + 1, 8, default=5, space='buy') buy_1_volume = IntParameter(0, 100, default=10, space='buy') buy_2_volume = IntParameter(0, 100, default=10, space='buy') buy_3_volume = IntParameter(0, 100, default=10, space='buy') protection_max_allowed_dd = DecimalParameter(0, 1, decimals=DECIMALS, default=0.04, space='protection') protection_stop = IntParameter(1, 100, default=48, space='protection') protection_stoploss_stop = IntParameter(1, 100, default=48, space='protection') lookback = IntParameter(1, 200, default=48, space='protection') trade_limit = IntParameter(1, 10, default=2, space='protection') def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float, proposed_stake: float, min_stake: float, max_stake: float, **kwargs) -> float: dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) current_candle = dataframe.iloc[-1].squeeze() # for decalage in range(self.buy_3_decalage_deb.value, self.buy_3_decalage.value): # decalage_candle = dataframe.iloc[- decalage].squeeze() # # if (decalage_candle['normal_var_20'] >= 0.6): # amount = 10 * (- decalage_candle['percent20'] * 100) # print("use more stake", pair, " ", amount) # return min(max_stake, amount) # print("proposed_stake=", proposed_stake, " max_stake=", max_stake) # if current_candle['bb_width'] > 0.05: # print("use more stake", pair, " ", proposed_stake * 2) # return min(max_stake, proposed_stake * 2) # # if current_candle['bb_width'] > 0.035: # print("use more stake", pair, " ", proposed_stake * 1.5) # return min(max_stake, proposed_stake * 1.5) # if current_candle['bb_width'] < 0.020: # print("use less stake", pair, " ", proposed_stake / 2) # return min(max_stake, proposed_stake / 2) # if self.config['stake_amount'] == 'unlimited': # # Use entire available wallet during favorable conditions when in compounding mode. # return max_stake # else: # # Compound profits during favorable conditions instead of using a static stake. # return self.wallets.get_total_stake_amount() / self.config['max_open_trades'] # Use default stake amount. return proposed_stake def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str, current_time: datetime, entry_tag: Optional[str], **kwargs) -> bool: # {'symbol': 'FTM/USDT', 'timestamp': 1646494199570, 'datetime': '2022-03-05T15:29:59.570Z', 'high': 1.7489, # 'low': 1.6084, 'bid': 1.6505, 'bidVolume': 2135.0, 'ask': 1.6508, 'askVolume': 2815.0, 'vwap': 1.66852198, # 'open': 1.7313, 'close': 1.6505, 'last': 1.6505, 'previousClose': '1.73170000', 'change': -0.0808, # 'percentage': -4.667, 'average': 1.6909, 'baseVolume': 124656725.0, 'quoteVolume': 207992485.7799, # 'info': # {'symbol': 'FTMUSDT', 'priceChange': '-0.08080000', 'priceChangePercent': '-4.667', # 'weightedAvgPrice': '1.66852198', 'prevClosePrice': '1.73170000', 'lastPrice': '1.65050000', # 'lastQty': '143.00000000', 'bidPrice': '1.65050000', 'bidQty': '2135.00000000', # 'askPrice': '1.65080000', 'askQty': '2815.00000000', 'openPrice': '1.73130000', # 'highPrice': '1.74890000', 'lowPrice': '1.60840000', 'volume': '124656725.00000000', # 'quoteVolume': '207992485.77990000', 'openTime': '1646407799570', 'closeTime': '1646494199570', # 'firstId': '137149614', 'lastId': '137450289', 'count': '300676'}} - 0.9817468621938484 allow_to_buy = True max_gain = -100 sum_gain = 0 max_time = 0 if self.dp: if self.dp.runmode.value in ('live', 'dry_run'): if len(self.trades) == 0: print('search') self.trades = Trade.get_open_trades() if len(self.trades) >= self.config['max_open_trades'] / 2: for trade in self.trades: ticker = self.dp.ticker(trade.pair) last_price = ticker['last'] gain = (last_price - trade.open_rate) / trade.open_rate max_gain = max(max_gain, gain) sum_gain += gain max_time = max(max_time, datetime.timestamp(trade.open_date)) print(trade.pair, ticker['datetime'], ticker['timestamp'] / 1000, datetime.timestamp(trade.open_date), datetime.timestamp(trade.open_date) - int(ticker['timestamp'] / 1000)) now = datetime.now() diff = (datetime.timestamp(now) - max_time / 3600) if (max_gain <= -0.05) & (len(self.trades) >= self.config['max_open_trades'] / 2) & (diff < 6): print("allow_to_buy=false") allow_to_buy = False print(pair, allow_to_buy, len(self.trades), "max gain=", max_gain, "sum_gain=", sum_gain, "now=", now, "max=", max_time, "diff=", datetime.timestamp(now) - max_time) if allow_to_buy: self.trades = list() return allow_to_buy @property def protections(self): return [ { "method": "CooldownPeriod", "stop_duration_candles": 10 }, { "method": "MaxDrawdown", "lookback_period_candles": self.lookback.value, "trade_limit": self.trade_limit.value, "stop_duration_candles": self.protection_stop.value, "max_allowed_drawdown": self.protection_max_allowed_dd.value, "only_per_pair": False }, { "method": "StoplossGuard", "lookback_period_candles": 24, "trade_limit": 4, "stop_duration_candles": self.protection_stoploss_stop.value, "only_per_pair": False } ] def custom_sell(self, pair: str, trade: 'Trade', current_time: 'datetime', current_rate: float, current_profit: float, **kwargs): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = dataframe.iloc[-1].squeeze() previous_last_candle = dataframe.iloc[-2].squeeze() previous_5_candle = dataframe.iloc[-5].squeeze() # if (0 < current_profit) & ((current_time - trade.open_date_utc).seconds > 3600) \ # & (last_candle['percent10'] < 0.001): # return 'small_profit' # # if (current_profit > 0.01) \ # & ((previous_last_candle['sma10'] - last_candle['sma10']) / previous_last_candle['sma10'] > 0.003): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'sma10_quick' if (current_profit >= -0.01) & ((current_time - trade.open_date_utc).days >= 5)\ & ((current_time - trade.open_date_utc).days < 10)\ & (previous_last_candle['sma20'] > last_candle['sma20']): return "too_old_0.01" if (current_profit >= -0.02) & ((current_time - trade.open_date_utc).days >= 10)\ & ((current_time - trade.open_date_utc).days < 15) \ & (previous_last_candle['sma20'] > last_candle['sma20']): return "too_old_0.02" if (current_profit >= -0.03) & ((current_time - trade.open_date_utc).days >= 15) \ & (previous_last_candle['sma20'] > last_candle['sma20']): return "too_old_0.03" if self.profit_quick_lost: if (current_profit >= 0) & (last_candle['percent3'] < -0.015): return "quick_lost" if self.profit_no_change: if (current_profit > 0.005) & (last_candle['percent10'] < 0.001) & (last_candle['percent5'] < 0) & ((current_time - trade.open_date_utc).seconds >= 3600): return "no_change" if (current_profit > 0.005) & (last_candle['normal_var_20'] < 0.008): return "no_change_20" if (current_profit > 0.01) & (last_candle['normal_var_10'] < 0.008): return "no_change_10" if (current_profit > 0.01) & (last_candle['normal_var_5'] < 0.005): return "no_change_5" #if (current_profit > 0.01) & (last_candle['rsi'] < 30): # return "small_rsi" if self.profit_quick_gain_3: if (current_profit >= 0.03) & (last_candle['percent3'] < 0) & ((current_time - trade.open_date_utc).seconds <= 3600): return "quick_gain_3" if self.profit_quick_gain: if (0.01 < current_profit < 0.03) & (last_candle['percent3'] < 0) & ((current_time - trade.open_date_utc).seconds <= 3600): return "quick_gain" if self.profit_sma10: if (current_profit > 0.01) \ & ((previous_5_candle['sma10'] > last_candle['sma10']) \ | (last_candle['percent3'] < -0.01) | (last_candle['percent5'] < -0.01)) \ & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) return 'sma10' if self.profit_sma20: if (current_profit > 0.005) \ & (previous_last_candle['sma10'] > last_candle['sma10']) \ & ((current_time - trade.open_date_utc).seconds >= 3600) \ & ((previous_last_candle['sma20'] > last_candle['sma20']) & ((last_candle['percent5'] < 0) | (last_candle['percent10'] < 0) | (last_candle['percent20'] < 0))): # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) return 'sma20' # if self.profit_old_sma10: # if (current_profit > 0) \ # & ((current_time - trade.open_date_utc).days >= 3) \ # & ((previous_5_candle['sma10'] > last_candle['sma10']) | (last_candle['percent3'] < -0.005) | (last_candle['percent5'] < -0.005)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'old_sma10' # if self.profit_very_old_sma10: # if (current_profit > -0.01) \ # & ((current_time - trade.open_date_utc).days >= 6) \ # & ((previous_5_candle['sma10'] > last_candle['sma10']) | (last_candle['percent3'] < 0) | (last_candle['percent5'] < 0)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'very_old_sma10' if self.profit_over_rsi: if (current_profit > 0) & (last_candle['rsi'] > 88): # & (last_candle['percent'] < 0): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) return 'over_rsi' if (current_profit > 0) & (previous_last_candle['rsi'] > 82) & (last_candle['percent'] < -0.02): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) return 'over_rsi_2' if self.profit_short_loss: if (current_profit > -0.01) & (previous_last_candle['percent10'] > 0.04) & (last_candle['percent'] < 0)\ & ((current_time - trade.open_date_utc).days >= 1): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) return 'short_lost' # if (current_profit > 0) \ # & (last_candle['rsi'] > 82) & (previous_last_candle['rsi'] > 75): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'over_rsi_2' def informative_pairs(self): return [] def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # dataframe['profit'] = 0 # RSI dataframe['rsi'] = ta.RSI(dataframe) dataframe['sma10'] = ta.SMA(dataframe, timeperiod=10) dataframe['sma20'] = ta.SMA(dataframe, timeperiod=20) dataframe['sma50'] = ta.SMA(dataframe, timeperiod=50) dataframe['sma100'] = ta.SMA(dataframe, timeperiod=100) dataframe["percent"] = (dataframe["close"] - dataframe["open"]) / dataframe["open"] dataframe["percent5"] = dataframe["percent"].rolling(5).sum() dataframe["percent3"] = dataframe["percent"].rolling(3).sum() dataframe["percent10"] = dataframe["percent"].rolling(10).sum() dataframe["percent20"] = dataframe["percent"].rolling(20).sum() dataframe["percent50"] = dataframe["percent"].rolling(50).sum() # if (dataframe["percent50"] < -0.03) & (dataframe['sma10'] > dataframe['sma10'].shift(2)): # dataframe["percent_ok"] = new dataframe() # else: # dataframe["percent_ok"] = 0 dataframe['ecart_20'] = dataframe['close'].rolling(20).var() / dataframe['close'] dataframe['ecart_50'] = dataframe['close'].rolling(50).var() / dataframe['close'] dataframe['min'] = ta.MIN(dataframe['close'], timeperiod=self.buy_min_horizon.value) dataframe['min10'] = ta.MIN(dataframe['close'], timeperiod=10) dataframe['min20'] = ta.MIN(dataframe['close'], timeperiod=20) dataframe['min50'] = ta.MIN(dataframe['close'], timeperiod=50) dataframe['min200'] = ta.MIN(dataframe['close'], timeperiod=200) dataframe["volume10"] = dataframe["volume"].rolling(10).mean() dataframe['max'] = ta.MAX(dataframe['close'], timeperiod=200) dataframe['max_min'] = dataframe['max'] / dataframe['min'] # Bollinger Bands bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2) dataframe['bb_lowerband'] = bollinger['lower'] dataframe['bb_middleband'] = bollinger['mid'] dataframe['bb_upperband'] = bollinger['upper'] dataframe["bb_percent"] = ( (dataframe["close"] - dataframe["bb_lowerband"]) / (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) ) dataframe["bb_width"] = ( (dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_middleband"] ) # dataframe['bb_min'] = ta.MIN(dataframe['bb_lowerband'], timeperiod=36) dataframe['distance_min'] = (dataframe['close'] - dataframe['min']) / dataframe['close'] dataframe['min1.1'] = 1.01 * dataframe['min'] dataframe['normal'] = 100 * (dataframe['close'] / dataframe['close'].rolling(200).mean()) dataframe['normal_var_5'] = dataframe['normal'].rolling(5).var() dataframe['normal_var_10'] = dataframe['normal'].rolling(10).var() dataframe['normal_var_20'] = dataframe['normal'].rolling(20).var() dataframe['normal_var_50'] = dataframe['normal'].rolling(50).var() # Bollinger Bands - Weighted (EMA based instead of SMA) # weighted_bollinger = qtpylib.weighted_bollinger_bands( # qtpylib.typical_price(dataframe), window=20, stds=2 # ) # dataframe["wbb_upperband"] = weighted_bollinger["upper"] # dataframe["wbb_lowerband"] = weighted_bollinger["lower"] # dataframe["wbb_middleband"] = weighted_bollinger["mid"] # dataframe["wbb_percent"] = ( # (dataframe["close"] - dataframe["wbb_lowerband"]) / # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) # ) # dataframe["wbb_width"] = ( # (dataframe["wbb_upperband"] - dataframe["wbb_lowerband"]) / dataframe["wbb_middleband"] # ) dataframe[buy_crossed_indicator0] = gene_calculator(dataframe, buy_crossed_indicator0) dataframe[buy_crossed_indicator1] = gene_calculator(dataframe, buy_crossed_indicator1) dataframe[buy_crossed_indicator2] = gene_calculator(dataframe, buy_crossed_indicator2) dataframe[buy_indicator0] = gene_calculator(dataframe, buy_indicator0) dataframe[buy_indicator1] = gene_calculator(dataframe, buy_indicator1) dataframe[buy_indicator2] = gene_calculator(dataframe, buy_indicator2) dataframe["cond1"] = dataframe[buy_indicator0].div(dataframe[buy_crossed_indicator0]) dataframe['cmf20'] = cmf(dataframe, 20) dataframe['cmf50'] = cmf(dataframe, 50) dataframe['cmf100'] = cmf(dataframe, 100) # dataframe["dist_min_50"] = dataframe['close'] - dataframe['min50'] # dataframe["dist_min_20"] = dataframe['close'] - dataframe['min20'] # # EMA - Exponential Moving Average # dataframe['ema3'] = ta.EMA(dataframe, timeperiod=3) return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # pandas.set_option('display.max_rows', dataframe.shape[0] + 1) # pandas.set_option('display.max_columns', 50) # # allow_to_buy = True # max_gain = -100 # trades = Trade.get_open_trades() # # if self.dp: # if self.dp.runmode.value in ('live', 'dry_run'): # pairs = self.dp.current_whitelist() # pairs_len = len(pairs) # pair_index = pairs.index(metadata['pair']) # # # print(pair_index, " ", metadata['pair']) # # # ob = self.dp.orderbook(metadata['pair'], 1) # # dataframe['best_bid'] = ob['bids'][0][0] # # dataframe['best_ask'] = ob['asks'][0][0] # # print(ob) # # for trade in trades: # # if (metadata['pair'] == trade.pair): # ticker = self.dp.ticker(trade.pair) #metadata['pair']) # last_price = ticker['last'] # # dataframe['volume24h'] = ticker['quoteVolume'] # # dataframe['vwap'] = ticker['vwap'] # # d = dataframe.tail(1) # # print(dataframe) # gain = (last_price - trade.open_rate) / trade.open_rate # # # print("Found open trade: ", trade, " ", ticker['last'], " ", trade.open_rate, gain) # max_gain = max(max_gain, gain) # # if max_gain > - 0.05: # allow_to_buy = False # # # print(metadata['pair'], max_gain, allow_to_buy, len(trades)) for decalage in range(self.buy_1_decalage_deb.value, self.buy_1_decalage.value): if self.buy_0.value: conditions = list() condition1, dataframe = condition_generator( dataframe, buy_operator0, buy_indicator0, buy_crossed_indicator0, self.buy_1_real_num.value, self.buy_1_decalage.value ) conditions.append(condition1) dataframe.loc[ ( reduce(lambda x, y: x & y, conditions) & (dataframe['volume10'].shift(decalage) * dataframe['close'].shift(decalage) / 1000 >= self.buy_1_volume.value) & (dataframe['sma10'].shift(1) <= dataframe['sma10']) & (dataframe['close'] < dataframe['bb_middleband']) & (dataframe['open'] < dataframe['sma10']) & (dataframe['open'] < dataframe['sma100']) & (dataframe['min50'].shift(decalage) == dataframe['min50']) & (dataframe['open'] <= dataframe['min200'] * self.buy_1_min.value) & (dataframe['percent20'].shift(decalage) <= self.buy_0_percent20.value) # & (dataframe['min20'] == dataframe['min50']) & (dataframe['distance_min'] <= self.buy_1_distance.value) & (dataframe['normal_var_20'] >= self.buy_1_normal_var.value) ), ['buy', 'buy_tag']] = (1, 'buy_1_' + str(decalage)) for decalage in range(self.buy_2_decalage_deb.value, self.buy_2_decalage.value): if self.buy_2.value: dataframe.loc[ ( (dataframe['cond1'].shift(decalage) <= 0.45) #self.buy_1_real_num.value / 2) & (dataframe['volume10'].shift(decalage) * dataframe['close'].shift(decalage) / 1000 >= self.buy_2_volume.value) # & (dataframe['sma10'].shift(1) <= dataframe['sma10']) & (dataframe['close'] < dataframe['sma10']) & (dataframe['open'] < dataframe['sma100']) & (dataframe['open'] < dataframe['sma10']) & (dataframe['min50'].shift(decalage) == dataframe['min50']) & (dataframe['open'] <= dataframe['min200'] * self.buy_2_min.value) & (dataframe['percent20'].shift(decalage) <= self.buy_2_percent20.value) # & (dataframe['min20'] == dataframe['min50']) & (dataframe['distance_min'] <= self.buy_2_distance.value) & (dataframe['normal_var_20'] >= self.buy_2_normal_var.value) ), ['buy', 'buy_tag']] = (1, 'buy_2_' + str(decalage)) for decalage in range(self.buy_3_decalage_deb.value, self.buy_3_decalage.value): if self.buy_3.value: dataframe.loc[ ( (dataframe['cond1'].shift(decalage) <= 0.2) & (dataframe['volume10'].shift(decalage) * dataframe['close'].shift(decalage) / 1000 >= self.buy_3_volume.value) # & (dataframe['sma10'].shift(1) <= dataframe['sma10']) & (dataframe['close'] < dataframe['sma10']) & (dataframe['open'] < dataframe['sma100']) & (dataframe['open'] < dataframe['sma10']) & (dataframe['min50'].shift(decalage) == dataframe['min50']) & (dataframe['open'] <= dataframe['min200'] * self.buy_3_min.value) & (dataframe['percent20'].shift(decalage) <= self.buy_3_percent20.value) & (dataframe['distance_min'] <= self.buy_3_distance.value) & (dataframe['normal_var_20'] >= self.buy_3_normal_var.value) ), ['buy', 'buy_tag']] = (1, 'buy_3_' + str(decalage)) # pair = metadata['pair'] # allow_to_buy = True # max_gain = -100 # sum_gain = 0 # max_time = 0 # if len(self.trades) == 0: # print('search') # self.trades = Trade.get_open_trades() # # # if self.dp: # # if self.dp.runmode.value in ('live', 'dry_run'): # if len(self.trades) >= self.config['max_open_trades'] / 2: # for trade in self.trades: # ticker = self.dp.ticker(trade.pair) # last_price = ticker['last'] # gain = (last_price - trade.open_rate) / trade.open_rate # max_gain = max(max_gain, gain) # sum_gain += gain # max_time = max(max_time, datetime.timestamp(trade.open_date)) # print(trade.pair, ticker['datetime'], ticker['timestamp'] / 1000, datetime.timestamp(trade.open_date), # datetime.timestamp(trade.open_date) - int(ticker['timestamp'] / 1000)) # now = datetime.now() # diff = (datetime.timestamp(now) - max_time / 3600) # if (max_gain >= -0.05) & (len(self.trades) >= self.config['max_open_trades'] / 2) & (diff < 6): # print("allow_to_buy=false") # allow_to_buy = False # print(pair, allow_to_buy, len(self.trades), # "max gain=", max_gain, # "sum_gain=", sum_gain, # "now=", now, # "max=", max_time, # "diff=", datetime.timestamp(now) - max_time) # # if allow_to_buy: # self.trades = list() # print(condition1) return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: return dataframe