# Zeus Strategy: First Generation of GodStra Strategy with maximum # AVG/MID profit in USDT # Author: @Mablue (Masoud Azizi) # github: https://github.com/mablue/ # IMPORTANT: INSTALL TA BEFOUR RUN(pip install ta) # freqtrade hyperopt --hyperopt-loss SharpeHyperOptLoss --spaces buy sell roi --strategy Zeus # --- 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 logging import calendar from freqtrade.loggers import setup_logging from freqtrade.strategy.strategy_helper import merge_informative_pair # -------------------------------- # Add your lib to import here import ta from functools import reduce import numpy as np import talib.abstract as talib from freqtrade.strategy.strategy_helper import merge_informative_pair import freqtrade.vendor.qtpylib.indicators as qtpylib from random import shuffle logger = logging.getLogger(__name__) class Zeus_8_3_3_3(IStrategy): # ROI table: minimal_roi = { "0": 0.564, "567": 0.273, "2814": 0.12, "7675": 0 } # Stoploss: stoploss = -1 #0.256 # Buy hypers timeframe = '5m' market_overview = {'up': 0, 'down': 0} market_overview_pct5 = 0 market_overview_pct1 = 0 max_open_trades = 5 max_amount = 40 stop_buy_for_all = False stop_buying = {} # DCA config position_adjustment_enable = True #max_dca_orders = 2 # n - 1 max_dca_multiplier = 7 # (2^n - 1) dca_trigger = 0 plot_config = { "main_plot": { "min200": { "color": "#86c932" }, "min50": { "color": "white" }, # "max200": { # "color": "yellow" # }, "sma3_1d": { "color": "pink" }, "sma5_1d": { "color": "blue" }, "sma10_1d": { "color": "orange" }, "close_1d": { "color": "#73e233", }, "low": { "color": "cyan", }, "bb_lowerband": { "color": "#da59a6"}, "bb_upperband": { "color": "#da59a6", } }, "subplots": { # "Ind": { # "trend_ichimoku_base": { # "color": "#dd1384" # }, # "trend_kst_diff": { # "color": "#850678" # } # }, # "BB": { # "bb_width": { # "color": "white" # }, # "bb_lower_5": { # "color": "yellow" # } # }, "Rsi": { "rsi_1d": { "color": "pink" }, # "rsi_1h": { # "color": "green" # }, "rsi5": { "color": "yellow" }, "rsi3_1d": { "color": "red" } }, # "Percent": { # "pct_change_1_1d": { # "color": "green" # }, # "pct_change_3_1d": { # "color": "orange" # }, # "pct_change_5_1d": { # "color": "red" # } # } } } trades = list() buy_min_horizon = IntParameter(50, 200, default=72, space='buy') buy_rsi = IntParameter(20, 90, default=72, space='buy') buy_bb_width_n = DecimalParameter(1, 10, decimals=1, default=5, space='buy') buy_min_max_nh = IntParameter(1, 48, default=24, space='buy') buy_min_max_n = DecimalParameter(0, 0.2, decimals=2, default=0.05, space='buy') buy_min_max_rsi = IntParameter(50, 90, default=72, space='buy') buy_min_max_coef = DecimalParameter(1, 1.01, decimals=3, default=1.002, space='buy') buy_min_max_decalage = IntParameter(2, 10, default=2, space='buy') profit_b_no_change = BooleanParameter(default=True, space="sell") profit_b_quick_lost = BooleanParameter(default=True, space="sell") profit_b_sma5 = BooleanParameter(default=True, space="sell") profit_b_sma10 = BooleanParameter(default=True, space="sell") profit_b_sma20 = BooleanParameter(default=True, space="sell") profit_b_quick_gain = BooleanParameter(default=True, space="sell") profit_b_quick_gain_3 = BooleanParameter(default=True, space="sell") profit_b_old_sma10 = BooleanParameter(default=True, space="sell") profit_b_very_old_sma10 = BooleanParameter(default=True, space="sell") profit_b_over_rsi = BooleanParameter(default=True, space="sell") profit_b_short_loss = BooleanParameter(default=True, space="sell") sell_b_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_b_percent3 = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_b_candels = IntParameter(0, 48, default=12, space='sell') sell_b_too_old_day = IntParameter(0, 10, default=5, space='sell') sell_b_too_old_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_b_profit_no_change = DecimalParameter(0, 0.02, decimals=3, default=0.005, space='sell') sell_b_profit_percent10 = DecimalParameter(0, 0.002, decimals=4, default=0.001, space='sell') sell_b_RSI = IntParameter(70, 98, default=88, space='sell') sell_b_RSI2 = IntParameter(70, 98, default=88, space='sell') sell_b_RSI3 = IntParameter(70, 98, default=80, space='sell') sell_b_RSI2_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') # sell_b_expected_profit = DecimalParameter(0, 0.01, decimals=3, default=0.01, space='sell') profit_h_no_change = BooleanParameter(default=True, space="sell") profit_h_quick_lost = BooleanParameter(default=True, space="sell") profit_h_sma5 = BooleanParameter(default=True, space="sell") profit_h_sma10 = BooleanParameter(default=True, space="sell") profit_h_sma20 = BooleanParameter(default=True, space="sell") profit_h_quick_gain = BooleanParameter(default=True, space="sell") profit_h_quick_gain_3 = BooleanParameter(default=True, space="sell") profit_h_old_sma10 = BooleanParameter(default=True, space="sell") profit_h_very_old_sma10 = BooleanParameter(default=True, space="sell") profit_h_over_rsi = BooleanParameter(default=True, space="sell") profit_h_short_loss = BooleanParameter(default=True, space="sell") sell_h_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_h_percent3 = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_h_candels = IntParameter(0, 48, default=12, space='sell') sell_h_too_old_day = IntParameter(0, 10, default=5, space='sell') sell_h_too_old_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') sell_h_profit_no_change = DecimalParameter(0, 0.02, decimals=3, default=0.005, space='sell') sell_h_profit_percent10 = DecimalParameter(0, 0.002, decimals=4, default=0.001, space='sell') sell_h_RSI = IntParameter(70, 98, default=88, space='sell') sell_h_RSI2 = IntParameter(70, 98, default=88, space='sell') sell_h_RSI3 = IntParameter(70, 98, default=80, space='sell') sell_h_RSI2_percent = DecimalParameter(0, 0.02, decimals=3, default=0.01, space='sell') protection_percent_buy_lost = IntParameter(1, 30, default=3, space='protection') protection_nb_buy_lost = IntParameter(1, 3, default=3, space='protection') def calc_profit(self, price: float, current: float) -> float: fee = 1.0007 profit = ((current*fee) - (price*fee)) return float(f"{profit:.8f}") 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: allow_to_buy = True # info_previous_last_candle = informative.iloc[-2].squeeze() if self.stop_buying.get(pair, None) is None: print("enable buying tag", pair) self.stop_buying[pair] = False informative, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) info_last_candle = informative.iloc[-1].squeeze() if ((info_last_candle['rsi_1h'] >= 76) & (info_last_candle['close_1h'] >= info_last_candle['bb_upperband_1h'])) \ & (self.stop_buying[pair] is False): logger.info("1 - Disable buying %s date %s", pair, info_last_candle['date']) self.stop_buying[pair] = True if self.stop_buying[pair] is True: if ((info_last_candle['rsi_1h'] <= 35) | (info_last_candle['close_1h'] < info_last_candle['bb_lowerband_1h'])): logger.info("2 - Enable buying %s date %s", pair, info_last_candle['date']) self.stop_buying[pair] = False if self.stop_buying[pair]: allow_to_buy = False logger.info("3 - cancel buying %s date %s", pair, info_last_candle['date']) else: logger.info("3 - accept buying %s date %s", pair, info_last_candle['date']) return allow_to_buy 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_previous_last_candle = dataframe.iloc[-2].squeeze() previous_5_candle = dataframe.iloc[-5].squeeze() return (previous_last_candle['rsi5'] > 60) \ & (previous_last_candle['rsi5'] >= last_candle['rsi5']) \ & (previous_last_candle['rsi5'] >= previous_previous_last_candle['rsi5']) \ & (last_candle['close'] > last_candle['close_1d']) & (last_candle['percent'] < 0) # expected_profit = 0.01 # #print(last_candle['buy_tag']) # # days = (current_time - trade.open_date_utc).days # ###### # # if (last_candle['mrsi3_1h'] < previous_last_candle['mrsi3_1h']): #(self.market_overview_pct5 < 0) | (last_candle['pct_change_1_4h'] < 0): # max_percent = 0.004 # last_candle['bb_width'] / 3.5 # 0.005 # max_profit = 0.004 # last_candle['bb_width'] * 3 / 4 # 0.015 # # if (current_profit > 0.01) & \ # (last_candle['percent10'] < -0.005) & ((current_time - trade.open_date_utc).seconds >= 3600): # return 'b_percent10' # if (current_profit > max_profit) & \ # ((last_candle['percent'] < - max_percent) | (last_candle['percent3'] < -max_percent) | ( # last_candle['percent5'] < -max_percent)): # return 'b_percent_quick' # # if (current_profit >= - self.sell_b_too_old_percent.value) & (days >= self.sell_b_too_old_day.value)\ # & (days < self.sell_b_too_old_day.value * 2)\ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "b_too_old_0.01" # if (current_profit >= - self.sell_b_too_old_percent.value * 2) & (days >= self.sell_b_too_old_day.value * 2)\ # & (days < self.sell_b_too_old_day.value * 3) \ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "b_too_old_0.02" # if (current_profit >= - self.sell_b_too_old_percent.value * 3) & (days >= self.sell_b_too_old_day.value * 3) \ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "b_too_old_0.03" # # if self.profit_b_quick_lost.value and (current_profit >= max_profit) & ( # last_candle['percent3'] < -max_percent): # return "b_quick_lost" # # if self.profit_b_no_change.value and (current_profit > self.sell_b_profit_no_change.value) \ # & (last_candle['percent10'] < self.sell_b_profit_percent10.value) & (last_candle['percent5'] < 0) \ # & ((current_time - trade.open_date_utc).seconds >= 3600): # return "b_no_change" # # if (current_profit > self.sell_b_percent.value) & (last_candle['percent3'] < - self.sell_b_percent3.value) \ # & ((current_time - trade.open_date_utc).seconds <= 300 * self.sell_b_candels.value): # return "b_quick_gain_param" # # if self.profit_b_sma5.value: # if (current_profit > expected_profit) \ # & ((previous_5_candle['sma5'] > last_candle['sma5']) \ # | (last_candle['percent3'] < -expected_profit) | ( # last_candle['percent5'] < -expected_profit)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'b_sma5' # # if self.profit_b_sma10.value: # if (current_profit > expected_profit) \ # & ((previous_5_candle['sma10'] > last_candle['sma10']) \ # | (last_candle['percent3'] < -expected_profit) | ( # last_candle['percent5'] < -expected_profit)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'b_sma10' # # if self.profit_b_sma20.value: # if (current_profit > max_percent) \ # & (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 'b_sma20' # # if self.profit_b_over_rsi.value: # if (current_profit > 0) & (previous_last_candle[ # 'rsi'] > self.sell_b_RSI.value): # & (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 'b_over_rsi' # # if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_b_RSI2.value) & \ # (last_candle[ # 'percent'] < - self.sell_b_RSI2_percent.value): # | (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'b_over_rsi_2' # # if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_b_RSI3.value) & \ # (last_candle['close'] >= last_candle['max200']) & (last_candle[ # 'percent'] < - self.sell_b_RSI2_percent.value): # | (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'b_over_rsi_max' # # if self.profit_b_short_loss.value: # if (current_profit > -expected_profit) & (previous_last_candle['percent10'] > 0.04) & ( # last_candle['percent'] < 0) \ # & (days >= 1): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'b_short_lost' # else: # max_percent = 0.005 # last_candle['bb_width'] / 3.5 # 0.005 # max_profit = 0.01 # last_candle['bb_width'] * 3 / 4 # 0.015 # # if (current_profit > max_profit) & ( # (last_candle['percent'] < -max_percent) | (last_candle['percent3'] < -max_percent) | ( # last_candle['percent5'] < -max_percent)): # return 'h_percent_quick' # # # if (last_candle['bb_width'] < 0.02) & (current_profit > 0) & (last_candle['close'] > bb_width_up) & \ # # ((last_candle['percent'] < - bb_width_lim) | (last_candle['percent3'] < - bb_width_lim) | (last_candle['percent5'] < - bb_width_lim)): # # return 'h_bb_width_max' # # if (current_profit >= - self.sell_h_too_old_percent.value) & (days >= self.sell_h_too_old_day.value)\ # & (days < self.sell_h_too_old_day.value * 2)\ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "h_too_old_0.01" # if (current_profit >= - self.sell_h_too_old_percent.value * 2) & (days >= self.sell_h_too_old_day.value * 2)\ # & (days < self.sell_h_too_old_day.value * 3) \ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "h_too_old_0.02" # if (current_profit >= - self.sell_h_too_old_percent.value * 3) & (days >= self.sell_h_too_old_day.value * 3) \ # & (previous_last_candle['sma10'] > last_candle['sma10']) & (last_candle['percent3'] < 0): # return "h_too_old_0.03" # # if self.profit_h_quick_lost.value and (current_profit >= max_profit) & ( # last_candle['percent3'] < -max_percent): # return "h_quick_lost" # # if self.profit_h_no_change.value and (current_profit > self.sell_h_profit_no_change.value) \ # & (last_candle['percent10'] < self.sell_h_profit_percent10.value) & (last_candle['percent5'] < 0) \ # & ((current_time - trade.open_date_utc).seconds >= 3600): # return "h_no_change" # # if (current_profit > self.sell_h_percent.value) & (last_candle['percent3'] < - self.sell_h_percent3.value) \ # & ((current_time - trade.open_date_utc).seconds <= 300 * self.sell_h_candels.value): # return "h_quick_gain_param" # # if self.profit_h_sma5.value: # if (current_profit > expected_profit) \ # & ((previous_5_candle['sma5'] > last_candle['sma5']) \ # | (last_candle['percent3'] < -expected_profit) | ( # last_candle['percent5'] < -expected_profit)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'h_sma5' # # if self.profit_h_sma10.value: # if (current_profit > expected_profit) \ # & ((previous_5_candle['sma10'] > last_candle['sma10']) \ # | (last_candle['percent3'] < -expected_profit) | ( # last_candle['percent5'] < -expected_profit)) \ # & ((last_candle['percent'] < 0) & (last_candle['percent3'] < 0)): # # print("over_bb_band_sma10_desc", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'h_sma10' # # if self.profit_h_sma20.value: # if (current_profit > max_percent) \ # & (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 'h_sma20' # # if self.profit_h_over_rsi.value: # if (current_profit > 0) & (previous_last_candle[ # 'rsi'] > self.sell_h_RSI.value): # & (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 'h_over_rsi' # # if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_h_RSI2.value) & \ # (last_candle[ # 'percent'] < - self.sell_h_RSI2_percent.value): # | (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'h_over_rsi_2' # # if (current_profit > 0) & (previous_last_candle['rsi'] > self.sell_h_RSI3.value) & \ # (last_candle['close'] >= last_candle[ # 'max200']): # | (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'h_over_rsi_max' # # if self.profit_h_short_loss.value: # if (current_profit > -expected_profit) & (previous_last_candle['percent10'] > 0.04) & ( # last_candle['percent'] < 0) \ # & (days >= 1): #| (previous_last_candle['rsi'] > 75 & last_candle['rsi'] < 70)): # # print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate) # return 'h_short_lost' def informative_pairs(self): # get access to all pairs available in whitelist. pairs = self.dp.current_whitelist() informative_pairs = [(pair, '1d') for pair in pairs] # informative_pairs += [(pair, '4h') for pair in pairs] informative_pairs += [(pair, '1h') for pair in pairs] return informative_pairs def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Add all ta features dataframe['pct_change'] = dataframe['close'].pct_change(5) dataframe['min'] = talib.MIN(dataframe['close'], timeperiod=self.buy_min_horizon.value) dataframe['min10'] = talib.MIN(dataframe['close'], timeperiod=10) dataframe['min20'] = talib.MIN(dataframe['close'], timeperiod=20) dataframe['min50'] = talib.MIN(dataframe['close'], timeperiod=50) dataframe['min200'] = talib.MIN(dataframe['close'], timeperiod=200) dataframe['min200_1'] = dataframe['min200'] * 1.005 dataframe['moy200_12'] = dataframe['min200'].rolling(12).mean() dataframe['max50'] = talib.MAX(dataframe['close'], timeperiod=50) dataframe['max200'] = talib.MAX(dataframe['close'], timeperiod=200) dataframe['min_max200'] = (dataframe['max200'] - dataframe['min200']) / dataframe['min200'] dataframe['min_n'] = talib.MIN(dataframe['close'], timeperiod=12 * self.buy_min_max_nh.value) dataframe['max_n'] = talib.MAX(dataframe['close'], timeperiod=12 * self.buy_min_max_nh.value) dataframe['min_max_n'] = (dataframe['max_n'] - dataframe['min_n']) / dataframe['min_n'] dataframe['rsi'] = talib.RSI(dataframe) dataframe['rsi5'] = talib.RSI(dataframe, timeperiod=5) dataframe['sma5'] = talib.SMA(dataframe, timeperiod=5) dataframe['sma10'] = talib.SMA(dataframe, timeperiod=10) dataframe['sma20'] = talib.SMA(dataframe, timeperiod=20) dataframe['sma50'] = talib.SMA(dataframe, timeperiod=50) dataframe['sma100'] = talib.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() # dataframe['percent_lost_n'] = dataframe["percent"].rolling(self.protection_lost_candles.value).sum() dataframe["volume10"] = dataframe["volume"].rolling(10).mean() # 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_lower_var_5'] = (dataframe['bb_lowerband'] - dataframe['min50']).rolling(5).var() dataframe['bb_lower_5'] = 100 * ((dataframe['bb_lowerband'].rolling(5).mean() / dataframe['bb_lowerband']) - 1) dataframe['bb_lower_width_5'] = (dataframe['bb_lowerband'] * (1 + dataframe['bb_width'] / self.buy_bb_width_n.value)) 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['min_max_close'] = ( (dataframe['max200'] - dataframe['close']) / (dataframe['close'] - dataframe['min200'])) # profit = False # profit_percent = False # percent_lower = False # current_price = dataframe['close'].iloc[-1] # # dataframe['should_sell'] = False # dataframe['should_buy'] = False # # # Get the previous trade # trade = Trade.get_trades_proxy(is_open=False, pair=metadata['pair']) # if trade: # trade = trade[-1] # lsp = trade.close_rate # if lsp: # percent_lower = self.calc_percentage_lower(price=lsp, current=current_price) # # Found a bug? When force selling it doesnt close it # else: # lsp = trade.open_rate # if lsp: # percent_lower = self.calc_percentage_lower(price=lsp, current=current_price) # else: # lsp = 0.00 # # # Get the current Trade # trade = Trade.get_trades_proxy(is_open=True, pair=metadata['pair']) # if trade: # trade = trade[-1] # lbp = trade.open_rate # open_trade = True # profit = self.calc_profit(price=lbp, current=current_price) # profit_percent = (profit/lbp)*100 # else: # lbp = 0.00 # open_trade = False # profit = False # profit_percent = False # # print("------------") # # print("Last Sold For:", lsp) # # if open_trade: # print("Bought for: ", lbp) # print("Current Price: ", current_price) # if profit: # print("Current Profit: ", profit, " ", float(f"{profit_percent:.8f}"), "%") # if percent_lower and not open_trade: # print("Percent Lower: ", float(f"{percent_lower:.8f}"), "%") # # # Should we Sell? # if profit_percent: # if profit_percent > 1: # dataframe['should_sell'] = True # # # Should we buy? # if not open_trade: # if (lsp == 0.00 ) & (lbp == 0.00): # dataframe['should_buy'] = True # # Is the percentage of what we sold for and the current price 2% lower # if percent_lower > 2: # dataframe['should_buy'] = True # # dataframe['last_sell_price'] = lsp # dataframe['last_buy_price'] = lbp ################### INFORMATIVE 1D informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d") informative["rsi"] = talib.RSI(informative) informative["rsi3"] = talib.RSI(informative, 3) informative["mrsi3"] = informative["rsi"].rolling(3).mean() informative["max3"] = talib.MAX(informative['close'], timeperiod=3) informative["min3"] = talib.MIN(informative['close'], timeperiod=3) informative['pct_change_1'] = informative['close'].pct_change(1) informative['pct_change_3'] = informative['close'].pct_change(3) informative['pct_change_5'] = informative['close'].pct_change(5) informative['sma3'] = talib.SMA(informative, timeperiod=3) informative['sma5'] = talib.SMA(informative, timeperiod=5) informative['sma10'] = talib.SMA(informative, timeperiod=10) informative['sar'] = talib.SAR(informative) bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(informative), window=20, stds=2) informative['bb_lowerband'] = bollinger['lower'] informative['bb_middleband'] = bollinger['mid'] informative['bb_upperband'] = bollinger['upper'] informative["bb_percent"] = ( (informative["close"] - informative["bb_lowerband"]) / (informative["bb_upperband"] - informative["bb_lowerband"]) ) informative["bb_width"] = ( (informative["bb_upperband"] - informative["bb_lowerband"]) / informative["bb_middleband"] ) dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True) # ######################## INFORMATIVE 4h # informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="4h") # informative["rsi"] = talib.RSI(informative) # informative['pct_change_1'] = informative['close'].pct_change(1) # informative['pct_change_3'] = informative['close'].pct_change(3) # informative['pct_change_5'] = informative['close'].pct_change(5) # informative['sma3'] = talib.SMA(informative, timeperiod=3) # informative['sma5'] = talib.SMA(informative, timeperiod=5) # informative['sma10'] = talib.SMA(informative, timeperiod=10) # dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "4h", ffill=True) ######################## INFORMATIVE 1h informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1h") informative["rsi"] = talib.RSI(informative) informative["rsi3"] = talib.RSI(informative, 3) informative["mrsi3"] = informative["rsi"].rolling(3).mean() informative['pct_change_1'] = informative['close'].pct_change(1) informative['pct_change_3'] = informative['close'].pct_change(3) informative['pct_change_5'] = informative['close'].pct_change(5) informative['sma3'] = talib.SMA(informative, timeperiod=3) informative['sma5'] = talib.SMA(informative, timeperiod=5) informative['sma10'] = talib.SMA(informative, timeperiod=10) bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(informative), window=20, stds=2) informative['bb_lowerband'] = bollinger['lower'] informative['bb_middleband'] = bollinger['mid'] informative['bb_upperband'] = bollinger['upper'] dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1h", ffill=True) return dataframe def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( # (dataframe['min_max_n'] >= self.buy_min_max_n.value) (dataframe['rsi5'].shift(1) < 12) & (dataframe['rsi5'].shift(1) < dataframe['rsi5']) & (dataframe['rsi5'].shift(1) < dataframe['rsi5'].shift(2)) # & (dataframe['close'] < dataframe['min_n'] * self.buy_min_max_coef.value) #& (dataframe['min_n'].shift(self.buy_min_max_decalage.value) == dataframe['min_n']) # & (dataframe['pct_change_1_1d'] > 0) & (dataframe['close'] <= dataframe['close_1d']) & (dataframe['close_1d'] <= dataframe['sma3_1d']) & (dataframe['close_1d'] <= dataframe['sma5_1d']) & (dataframe['close_1d'] <= dataframe['sma10_1d']) & (dataframe['low'] <= dataframe['min200']) & (dataframe['min'].shift(2) == dataframe['min50']) # & (dataframe['rsi3_1d'].shift(288) <= dataframe['rsi3_1d']) ), ['buy', 'buy_tag']] = (1, 'buy_rsi5') return dataframe # def bot_loop_start(self, **kwargs) -> None: # pairs = self.dp.current_whitelist() # print("Calcul des pairs informatives") # for pairname in pairs: # self.stop_buying[pairname] = True # print("Fin Calcul des pairs informatives") def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # dataframe.loc[ # ( # (dataframe['rsi5'].shift(1) > 60) # & (dataframe['rsi5'].shift(1) >= dataframe['rsi5']) # & (dataframe['rsi5'].shift(1) >= dataframe['rsi5'].shift(2)) # & (dataframe['close'] > dataframe['close_1d']) # # & (dataframe['close_1d'] > dataframe['sma3_1d']) # # & (dataframe['close_1d'] > dataframe['sma5_1d']) # # & (dataframe['close_1d'] > dataframe['sma10_1d']) # # & (dataframe['close'] < dataframe['min_n'] * self.buy_min_max_coef.value) # # # & (dataframe['rsi3_1d'].shift(288) > dataframe['rsi3_1d']) # # (dataframe['close_1d'] > dataframe['sma3_1d']) # # & (dataframe['rsi3_1d'] > 72) # #& (dataframe['last_buy_price'] < (dataframe['close'])) # #& (dataframe['should_sell'] == True) # ), ['sell', 'sell_tag']] = (1, 'sell_close_1d') # print("dans sell" + metadata['pair']) return dataframe def adjust_trade_position(self, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, min_stake: float, max_stake: float, **kwargs): dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe) if (len(dataframe) < 1): return None # dataframe = self.populate_buy_trend(dataframe, {'pair': trade.pair}) # if not (self.populate_buy_trend(dataframe, {'pair': trade.pair})): # return None if (self.stop_buying.get(trade.pair, None) == None): print("-----------" + trade.pair + " Init stop buying " + str(current_profit) + " " + str(current_time) + "---------------------") self.stop_buying[trade.pair] = True if (self.stop_buying[trade.pair] == True): print("-----------" + trade.pair + " Canceled " + str(current_profit) + " " + str(current_time) + "---------------------") return None last_candle = dataframe.iloc[-1].squeeze() previous_last_candle = dataframe.iloc[-2].squeeze() previous_previous_last_candle = dataframe.iloc[-3].squeeze() # last_candle_5 = dataframe.iloc[-3].squeeze() # last_candle_decalage = dataframe.iloc[- self.buy_min_max_decalage.value].squeeze() # print(last_candle['buy']) condition = ( # (last_candle['min_max_n'] >= self.buy_min_max_n.value) (previous_last_candle['rsi5'] < 12) & (previous_last_candle['rsi5'] < last_candle['rsi5']) & (previous_last_candle['rsi5'] < previous_previous_last_candle['rsi5']) # & (last_candle['close'] < last_candle['min_n'] * self.buy_min_max_coef.value) & (last_candle['close'] <= last_candle['close_1d']) & (last_candle['close_1d'] <= last_candle['sma3_1d']) & (last_candle['close_1d'] <= last_candle['sma5_1d']) & (last_candle['close_1d'] <= last_candle['sma10_1d']) # & (dataframe['close'] < dataframe['min_n'] * self.buy_min_max_coef.value) ) if not (condition): return None # min_d = min(last_candle['sma3_4h'], last_candle['close_1d']) filled_buys = trade.select_filled_orders('buy') count_of_buys = len(filled_buys) # days = (current_time - trade.open_date_utc).days # minutes = (current_time - trade.open_date_utc).seconds / 60 # condition = condition & ((last_candle['min50'] == last_candle_5['min50']) & (last_candle['close'] <= last_candle['close_1h'])) p = self.protection_percent_buy_lost.value percents = [p, p * 2, p * 3, p * 4, p * 5, p * 6, p * 7, p * 8, p * 9] if (0 < count_of_buys <= self.protection_nb_buy_lost.value) \ & (current_profit < - (percents[count_of_buys - 1] / 100)) & (condition): try: p = self.config['stake_amount'] factors = [p, p, p, p, 2 * p, 4 * p, 5 * p, 6 * p] stake_amount = factors[count_of_buys - 1]# filled_buys[0].cost # This then calculates current safety order size print("-----------" + trade.pair + " " + str(current_profit) + " " + str(count_of_buys) + " " + str(stake_amount) + " " + str(current_time) + "---------------------") return stake_amount except Exception as exception: print(exception) return None return None