Files
Freqtrade/Zeus.py
Jérôme Delacotte 7c239227d8 first commit
2025-03-06 11:01:43 +01:00

217 lines
7.9 KiB
Python

# 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 freqtrade.strategy.parameters import CategoricalParameter, DecimalParameter
from freqtrade.strategy.interface import IStrategy
from pandas import DataFrame
# --------------------------------
# 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
class Zeus(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_params = {
"buy_cat": "<R",
"buy_real": 0.0128,
}
# Sell hyperspace params:
sell_params = {
"sell_cat": "=R",
"sell_real": 0.9455,
}
# ROI table:
minimal_roi = {
"0": 0.564,
"567": 0.273,
"2814": 0.12,
"7675": 0
}
# Stoploss:
stoploss = -0.256
buy_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.11908, space='buy')
buy_cat = CategoricalParameter([">R", "=R", "<R"], default='<R', space='buy')
buy_pct = DecimalParameter(0.001, 0.02, decimals=3, default=0.005, space='buy')
buy_pct_1 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
buy_pct_3 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
buy_pct_5 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
buy_bb_lowerband = DecimalParameter(1, 1.05, default=1, decimals=2, space='buy')
buy_bb_width = DecimalParameter(0.01, 0.15, default=0.065, decimals=2, space='buy')
# sell_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.59608, space='sell')
# sell_cat = CategoricalParameter([">R", "=R", "<R"], default='>R', space='sell')
# Buy hypers
timeframe = '4h'
plot_config = {
"main_plot": {
"min200": {
"color": "#86c932",
}
},
"subplots": {
"Ind": {
"trend_ichimoku_base": {
"color": "#dd1384",
},
"trend_kst_diff": {
"color": "#850678",
},
},
"Percent": {
"max_min": {
"color": "#74effc",
}
}
}
}
def informative_pairs(self):
# get access to all pairs available in whitelist.
pairs = self.dp.current_whitelist()
# Assign tf to each pair so they can be downloaded and cached for strategy.
# informative_pairs = [(pair, "5m") for pair in pairs]
informative_pairs = [(pair, '1d') for pair in pairs]
# informative_pairs += [(pair, '1w') for pair in pairs]
# Optionally Add additional "static" pairs
# informative_pairs = [("BTC/USDT", "1w"), ("BTC/USDT", "1d"), ("BTC/USDT", "5m")]
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['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)
# Normalization
tib = dataframe['trend_ichimoku_base']
dataframe['trend_ichimoku_base'] = (tib-tib.min())/(tib.max()-tib.min())
tkd = dataframe['trend_kst_diff']
dataframe['trend_kst_diff'] = (tkd-tkd.min())/(tkd.max()-tkd.min())
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['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)
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)
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions = []
IND = 'trend_ichimoku_base'
REAL = self.buy_real.value
OPR = self.buy_cat.value
DFIND = dataframe[IND]
# print(DFIND.mean())
if OPR == ">R":
conditions.append(DFIND > REAL)
elif OPR == "=R":
conditions.append(np.isclose(DFIND, REAL))
elif OPR == "<R":
conditions.append(DFIND < REAL)
if conditions:
dataframe.loc[
(reduce(lambda x, y: x & y, conditions))
& (dataframe['pct_change'] < - self.buy_pct.value)
& (dataframe['close'] <= dataframe['min50'] * 1.002)
& (dataframe['pct_change_1_1d'] > self.buy_pct_1.value)
& (dataframe['pct_change_3_1d'] > self.buy_pct_3.value)
& (dataframe['pct_change_5_1d'] > self.buy_pct_5.value)
#& (dataframe['close_1d'] < dataframe['bb_lowerband_1d'] * self.buy_bb_lowerband.value)
& (dataframe['bb_width_1d'] >= self.buy_bb_width.value)
,
'buy'] = 1
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# conditions = []
# IND = 'trend_kst_diff'
# REAL = self.sell_real.value
# OPR = self.sell_cat.value
# DFIND = dataframe[IND]
# # print(DFIND.mean())
#
# if OPR == ">R":
# conditions.append(DFIND > REAL)
# elif OPR == "=R":
# conditions.append(np.isclose(DFIND, REAL))
# elif OPR == "<R":
# conditions.append(DFIND < REAL)
#
# if conditions:
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# 'sell'] = 1
return dataframe