# 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__)
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 Zeus_8_3_2_B_3(IStrategy):
# * 1/43: 86 trades. 72/6/8 Wins/Draws/Losses. Avg profit 12.66%. Median profit 11.99%. Total profit 0.10894395 BTC ( 108.94Σ%). Avg duration 3 days, 0:31:00 min. Objective: -48.48793
# "max_open_trades": 10,
# "stake_currency": "BTC",
# "stake_amount": 0.01,
# "tradable_balance_ratio": 0.99,
# "timeframe": "4h",
# "dry_run_wallet": 0.1,
# Buy hyperspace params:
buy_b_params = {
"buy_b_cat": "R", "=R", "R", "=R", " 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)\
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0) \
& (last_candle['echange*pct12'] < 0.0005):
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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0)\
& (last_candle['echange*pct12'] < 0.0005):
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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0)\
& (last_candle['echange*pct12'] < 0.0005):
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 > max_profit) and (last_candle['echange*pct5'] < 0.0005):
return "b_nochange_pct"
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) \
& ((last_candle['sma5_s5'] > 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) \
& ((last_candle['sma10_s5'] > 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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) \
& ((current_time - trade.open_date_utc).seconds >= 3600) \
& ((last_candle['sma20_s2'] > 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) & (last_candle['rsi_s2'] > self.sell_b_RSI.value): # & (last_candle['percent'] < 0): #| (last_candle['rsi_s2'] > 75 & last_candle['rsi'] < 70)):
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
return 'b_over_rsi'
if (current_profit > 0) & (last_candle['rsi_s2'] > self.sell_b_RSI2.value) & \
(last_candle[
'percent'] < - self.sell_b_RSI2_percent.value): # | (last_candle['rsi_s2'] > 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) & (last_candle['rsi_s2'] > self.sell_b_RSI3.value) & \
(last_candle['close'] >= last_candle['max200']) & (last_candle[
'percent'] < - self.sell_b_RSI2_percent.value): # | (last_candle['rsi_s2'] > 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) & (last_candle['percent10_s2'] > 0.04) & (
last_candle['percent'] < 0) \
& (days >= 1): #| (last_candle['rsi_s2'] > 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)\
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0)\
& (last_candle['echange*pct12'] < 0.001):
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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0)\
& (last_candle['echange*pct12'] < 0.001):
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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) & (last_candle['percent3'] < 0)\
& (last_candle['echange*pct12'] < 0.001):
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 > max_profit) and (last_candle['echange*pct12'] < 0.001):
return "h_nochange_pct"
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) \
& ((last_candle['sma5_s5'] > 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) \
& ((last_candle['sma10_s5'] > 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) \
& (last_candle['sma10_s2'] > last_candle['sma10']) \
& ((current_time - trade.open_date_utc).seconds >= 3600) \
& ((last_candle['sma20_s2'] > last_candle['sma20']) &
((last_candle['percent'] < 0) & (last_candle['percent5'] < 0) & (last_candle['percent10'] < 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) & (last_candle['rsi_s2'] > self.sell_h_RSI.value):
# & (last_candle['percent'] < 0): #| (last_candle['rsi_s2'] > 75 & last_candle['rsi'] < 70)):
# print("over_rsi", pair, trade, " profit=", current_profit, " rate=", current_rate)
return 'h_over_rsi'
if (current_profit > 0) & (last_candle['rsi_s2'] > self.sell_h_RSI2.value) & \
(last_candle[
'percent'] < - self.sell_h_RSI2_percent.value): # | (last_candle['rsi_s2'] > 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) & (last_candle['rsi_s2'] > self.sell_h_RSI3.value) & \
(last_candle['close'] >= last_candle[
'max200']): # | (last_candle['rsi_s2'] > 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) & (last_candle['percent10_s2'] > 0.04) & (
last_candle['percent'] < 0) \
& (days >= 1): #| (last_candle['rsi_s2'] > 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['trend_ichimoku_base'] = ta.trend.ichimoku_base_line(
dataframe['high'],
dataframe['low'],
window1=9,
window2=26,
visual=False,
fillna=False
)
KST = ta.trend.KSTIndicator(
close=dataframe['close'],
roc1=10,
roc2=15,
roc3=20,
roc4=30,
window1=10,
window2=10,
window3=10,
window4=15,
nsig=9,
fillna=False
)
dataframe['trend_kst_diff'] = KST.kst_diff()
dataframe['pct_change'] = dataframe['close'].pct_change(5)
dataframe['min'] = talib.MIN(dataframe['close'], timeperiod=200)
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['min50_005'] = dataframe['min50'] * 1.005
dataframe['min200_005'] = dataframe['min200'] * 1.005
dataframe['moy200_12'] = dataframe['min200'].rolling(12).mean()
dataframe['mean10'] = dataframe['close'].rolling(10).mean()
dataframe['mean20'] = dataframe['close'].rolling(20).mean()
dataframe['mean50'] = dataframe['close'].rolling(50).mean()
dataframe['mean100'] = dataframe['close'].rolling(100).mean()
dataframe['max50'] = talib.MAX(dataframe['close'], timeperiod=50)
dataframe['min_max_50'] = (dataframe['max50'] - dataframe['min50']) / dataframe['min50']
dataframe['max200'] = talib.MAX(dataframe['close'], timeperiod=200)
dataframe['min_max200'] = (dataframe['max200'] - dataframe['min200']) / dataframe['min200']
dataframe['rsi'] = talib.RSI(dataframe)
dataframe['rsi_pente'] = dataframe['rsi'].pct_change(1)
dataframe['rsi_acc'] = dataframe['rsi_pente'].pct_change(1)
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["volume5"] = dataframe["volume"].rolling(5).sum()
dataframe["volume10"] = dataframe["volume"].rolling(10).sum()
dataframe['sma5_s2'] = dataframe['sma5'].shift(1)
dataframe['sma10_s2'] = dataframe['sma10'].shift(1)
dataframe['sma20_s2'] = dataframe['sma20'].shift(1)
dataframe['percent10_s2'] = dataframe['percent10'].shift(1)
dataframe['rsi_s2'] = dataframe['rsi'].shift(1)
dataframe['sma5_s5'] = dataframe['sma5'].shift(4)
dataframe['sma10_s5'] = dataframe['sma10'].shift(4)
dataframe['sma20_s5'] = dataframe['sma20'].shift(4)
# print(metadata['pair'])
# print(circulation[metadata['pair']])
if circulation[metadata['pair']]:
dataframe["echange"] = 10000 * dataframe["volume"] / circulation[metadata['pair']]
dataframe["echange*pct"] = dataframe["echange"] * dataframe["percent"]
dataframe["echange5"] = 10000 * dataframe["volume5"] / circulation[metadata['pair']]
dataframe["echange*pct5"] = dataframe["echange5"] * dataframe["percent5"]
dataframe["pct_echange5"] = dataframe["echange5"].pct_change()
dataframe["acc_echange5"] = dataframe["echange*pct5"] / dataframe["echange*pct5"].shift(1)
for i in range(1, 4):
n = i * 12
dataframe["echange*pct" + str(n)] = 10000 * dataframe["volume"].rolling(n).sum() / circulation[metadata['pair']] \
* dataframe["percent"].rolling(n).sum()
dataframe["pente20"] = (dataframe["close"] - dataframe['close'].shift(20)) / dataframe["close"]
# 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_ecart"] = ((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["bb_pente"] = (dataframe["bb_lowerband"] - dataframe['bb_lowerband'].shift(3)) / dataframe["bb_lowerband"]
dataframe["bb_pente_inv"] = (dataframe["bb_pente"].shift(2) > dataframe["bb_pente"].shift(1)) & \
(dataframe["bb_pente"] > dataframe["bb_pente"].shift(1))
dataframe["bb_max_width"] = (dataframe["bb_ecart"].shift(2) < dataframe["bb_ecart"].shift(1)) & \
(dataframe["bb_ecart"] < dataframe["bb_ecart"].shift(1))
dataframe["bb_tag"] = dataframe["bb_pente_inv"] & dataframe["bb_max_width"]
# dataframe['bb_min'] = talib.MIN(dataframe['bb_lowerband'], timeperiod=36)
dataframe['distance_min'] = (dataframe['close'] - dataframe['min']) / dataframe['close']
dataframe['min50_1.01'] = 1.01 * dataframe['min50']
dataframe['min50_1.02'] = 1.02 * dataframe['min50']
dataframe['min50_1.03'] = 1.03 * dataframe['min50']
dataframe['normal'] = 100 * (dataframe['close'] / dataframe['close'].rolling(200).mean())
# dataframe['normal_var_20'] = dataframe['normal'].rolling(20).var()
# dataframe['normal_var_50'] = dataframe['normal'].rolling(50).var()
dataframe['min_max_close'] = (
(dataframe['max200'] - dataframe['close']) / (dataframe['close'] - dataframe['min200']))
dataframe['sar'] = talib.SAR(dataframe)
# Normalization
tib = dataframe['trend_ichimoku_base']
dataframe['trend_ichimoku_base'] = normalize(tib) #(tib-tib.min())/(tib.max()-tib.min())
dataframe["trend_ichimoku_pente"] = (dataframe["trend_ichimoku_base"] - dataframe['trend_ichimoku_base'].shift(3)) / dataframe["trend_ichimoku_base"]
tkd = dataframe['trend_kst_diff']
dataframe['trend_kst_diff'] = normalize(tkd) #(tkd-tkd.min())/(tkd.max()-tkd.min())
# dataframe['trend_ichimoku_base_50'] = talib.MIN(dataframe['trend_ichimoku_base'], timeperiod=50)
# dataframe['trend_ichimoku_base_5'] = talib.MIN(dataframe['trend_ichimoku_base'], timeperiod=5)
# dataframe['trend_ichimoku_base_sma5'] = talib.SMA(dataframe['trend_ichimoku_base'], timeperiod=5)
# dataframe['trend_ichimoku_base_pct'] = dataframe['trend_ichimoku_base'].pct_change(3)
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['cond_50'] = talib.MIN(dataframe['cond1'], timeperiod=50)
dataframe['cond_5'] = talib.MIN(dataframe['cond1'], timeperiod=5)
dataframe['cond_sma5'] = talib.SMA(dataframe['cond1'], timeperiod=5)
dataframe['cond_pct'] = dataframe['cond1'].pct_change(3)
dataframe['atr'] = talib.ATR(dataframe, timeperiod=14)
#FreqAI / Rewards
# dataframe["%-raw_close"] = dataframe["close"]
# dataframe["%-raw_open"] = dataframe["open"]
# dataframe["%-raw_high"] = dataframe["high"]
# dataframe["%-raw_low"] = dataframe["low"]
################### INFORMATIVE 1D
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d")
informative["rsi"] = talib.RSI(informative)
informative["max3"] = talib.MAX(informative['close'], timeperiod=3)
informative["min3"] = talib.MIN(informative['close'], timeperiod=3)
informative['min5'] = talib.MIN(informative['close'], timeperiod=5)
informative['max3'] = talib.MAX(informative['close'], timeperiod=3)
informative['max5'] = talib.MAX(informative['close'], timeperiod=5)
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["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)
informative['min3'] = talib.MIN(informative['close'], timeperiod=3)
informative['min5'] = talib.MIN(informative['close'], timeperiod=5)
informative['rsi_pente'] = informative['rsi'].pct_change(1)
informative['rsi_acc'] = informative['rsi_pente'].pct_change(1)
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1h", ffill=True)
# dataframe['support'] = min(dataframe['close_1d'], dataframe['sma3_1d'], dataframe['sma3_1d'])
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# enter_long_conditions = [dataframe["do_predict"] == 1] #, dataframe["&-s_close"] > dataframe["target_roi"]]
#
# if enter_long_conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, enter_long_conditions), ["enter_long", "enter_tag"]
# ] = (1, "long")
base = 0.33 #self.buy_base.value
# base = base / dataframe[self.buy_rsi_ichimoku.value] * self.buy_rsi_divisor.value
base = base / dataframe['rsi'] * 52
decalage = 3
dataframe.loc[
(
# (reduce(lambda x, y: x & y, enter_long_conditions))
(dataframe['trend_ichimoku_base'].shift(decalage) <= base)
# & (dataframe['close'] > dataframe['close_1d'])
& (dataframe['rsi'].shift(decalage) < 60)
& (dataframe['close'].shift(decalage) < dataframe['sma10'].shift(decalage))
& (dataframe['close'].shift(decalage) < dataframe['bb_middleband'].shift(decalage))
& (dataframe['bb_width'].shift(decalage) > 0.003)
# & (dataframe['close'].shift(decalage) < dataframe['bb_lower_width_5'].shift(decalage))
& ((dataframe['close'].shift(decalage) <= dataframe['min50'].shift(decalage) * 1.002) |
(dataframe['pct_change_1_1h'].shift(decalage) > - 0.002)
)
# & (dataframe['close'] <= dataframe['bb_upperband'])
# & (dataframe['close'] <= dataframe['min_200_001'])
& (dataframe['close'].shift(decalage) <= dataframe['close_1h'].shift(decalage))
& ((dataframe['close'].shift(decalage) < dataframe['bb_lowerband'].shift(decalage)) |
(dataframe['pct_change_1_1h'].shift(decalage) > - 0.002)
)
& (dataframe['close'] < dataframe['bb_upperband'])
& (dataframe['open'] < dataframe['bb_upperband'])
& ((dataframe['bb_pente_inv'] == 1) | (dataframe['bb_pente_inv'].shift(1) == 1) | (dataframe['bb_pente_inv'].shift(2) == 1)
| (dataframe['bb_pente_inv'].shift(3) == 1))
), ['buy', 'enter_tag']] = (1, 'buy_ichimoku')
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
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
# print(dataframe)
last_candle = dataframe.iloc[-1].squeeze()
# last_candle_5 = dataframe.iloc[-3].squeeze()
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 = (last_candle['cond1'] <= 0.75) & (last_candle['bb_width'] > 0.018) & (
# last_candle['rsi'] < 72) & (last_candle['close'] < last_candle['min50'] * 1.006)# & (last_candle['min_max_close'] > 2)
condition = (last_candle['enter_long'] == 1) # & (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]
# self.protection_nb_buy_lost.value
if (0 < count_of_buys <= 2) \
& (current_profit < - (percents[count_of_buys - 1] / 100)) & (condition):
try:
p = self.config['stake_amount']
if last_candle['close'] < last_candle['min5_1h']:
factors = [1.5 * p, 1.75 * p, 2 * p, 2 * p, 3 * p, 4 * p, 5 * p, 6 * p]
else:
if last_candle['close'] < last_candle['min3_1h']:
factors = [1.25 * p, 1.5 * p, 2 * p, 2 * p, 3 * p, 4 * p, 5 * p, 6 * p]
else:
factors = [1 * p, 1.25 * p, 2 * p, 2 * p, 3 * 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
# stake_amount = stake_amount * pow(1.5, count_of_buys)
# print("-----------" + trade.pair + " " + str(current_profit) + " " + str(count_of_buys) + " " + str(stake_amount) + "---------------------")
return stake_amount
except Exception as exception:
print(exception)
return None
return None