first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:01:43 +01:00
commit 7c239227d8
558 changed files with 108235 additions and 0 deletions

453
StrategyPierrick41221.py Normal file
View File

@@ -0,0 +1,453 @@
# pr#agma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# isort: skip_file
# --- Do not remove these libs ---
from datetime import datetime
import numpy
import numpy as np # noqa
import pandas as pd # noqa
from freqtrade.strategy.parameters import DecimalParameter, BooleanParameter, IntParameter
from pandas import DataFrame
import math
from functools import reduce
from freqtrade.strategy.interface import IStrategy
# --------------------------------
# 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
# This class is a sample. Feel free to customize it.
class StrategyPierrick41221(IStrategy):
# Strategy interface version - allow new iterations of the strategy interface.
# Check the documentation or the Sample strategy to get the latest version.
INTERFACE_VERSION = 2
# valeur de bbwidth pour démarrer
buy_bollinger = DecimalParameter(0.00, 0.18, decimals=2, default=0.075, space="buy")
# Valeur de la deuxième condition bollinger avec condition sma200
# buy_bollinger_2 = DecimalParameter(0.0, 0.08, decimals=2, default=0.04, space="buy")
# buy_min = DecimalParameter(1, 1.1, decimals=2, default=1.01, space="buy")
# buy_percent = DecimalParameter(1, 1.1, decimals=2, default=1.01, space="buy")
# volume à atteindre
buy_volume = DecimalParameter(0, 50, decimals=1, default=18, space="buy")
buy_step = IntParameter(1, 8, default=3, space="buy")
buy_rolling = IntParameter(-20, 0, default=-6, space="buy")
# buy_rsi = IntParameter(20, 40, default=30, space="buy")
# buy_adx_enabled = BooleanParameter(default=True, space="buy")
# buy_rsi_enabled = CategoricalParameter([True, False], default=False, space="buy")
# buy_trigger = CategoricalParameter(["bb_lower", "macd_cross_signal"], default="bb_lower", space="buy")
# ROI table:
minimal_roi = {
"0": 100
# "0": 0.015,
# "5": 0.01,
# "10": 0.005,
}
# Stoploss:
stoploss = -1
trailing_stop = True
trailing_stop_positive = 0.02
trailing_stop_positive_offset = 0.0275 # 0.015
trailing_only_offset_is_reached = True
# max_open_trades = 3
# Optimal ticker interval for the strategy.
timeframe = '1m'
# Run "populate_indicators()" only for new candle.
process_only_new_candles = False
# These values can be overridden in the "ask_strategy" section in the config.
use_sell_signal = True
sell_profit_only = False
ignore_roi_if_buy_signal = False
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 30
# Optional order type mapping.
order_types = {
'buy': 'limit',
'sell': 'limit',
'stoploss': 'market',
'stoploss_on_exchange': False
}
# Optional order time in force.
order_time_in_force = {
'buy': 'gtc',
'sell': 'gtc'
}
plot_config = {
# Main plot indicators (Moving averages, ...)
'main_plot': {
'bb_lowerband': {'color': 'red'},
'bb_upperband': {'color': 'green'},
'sma100': {'color': 'blue'},
'sma10': {'color': 'yellow'},
'min': {'color': 'white'},
'max': {'color': 'white'},
'sma20': {'color': 'cyan'}
},
'subplots': {
# Subplots - each dict defines one additional plot
"BB": {
'bb_width': {'color': 'green'},
'bb_min': {'color': 'red'},
},
"Volume": {
'volume5': {'color': 'yellow'},
},
"Rsi": {
'rsi': {'color': 'pink'},
},
"rolling": {
'bb_rolling': {'color': '#87e470'},
"bb_rolling_min": {'color': '#ac3e2a'}
},
"percent": {
"percent": {'color': 'green'},
"percent5": {'color': 'red'}
}
}
}
trades = list()
# buy_base = DecimalParameter(0, 0.2, decimals=2, default=0.10, space='buy')
# buy_diff = DecimalParameter(0, 0.2, decimals=2, default=0.20, space='buy')
#
# buy_rsi = IntParameter(20, 80, default=42, space='buy')
# buy_rsi_max = IntParameter(60, 90, default=60, space='buy')
#
# buy_rsi_1h = IntParameter(20, 80, default=72, space='buy')
# buy_rsi_max_1h = IntParameter(60, 80, default=72, space='buy')
#
# buy_min_horizon = IntParameter(50, 200, default=72, 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_0_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_decalage_deb_0 = IntParameter(0, 3, default=5, space='buy')
# buy_decalage_deb_2 = IntParameter(0, 3, default=5, space='buy')
# buy_decalage_deb_3 = IntParameter(0, 3, default=5, space='buy')
#
# buy_real_num0 = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy')
# buy_real_num1 = DecimalParameter(0, 1, decimals=2, default=0.67, space='buy')
# buy_real_num2 = DecimalParameter(0, 2, decimals=2, default=0.67, space='buy')
#
# buy_decalage0 = IntParameter(buy_decalage_deb_0.value + 1, 8, default=5, space='buy')
# buy_decalage2 = IntParameter(buy_decalage_deb_2.value + 1, 8, default=5, space='buy')
# buy_decalage3 = IntParameter(buy_decalage_deb_3.value + 1, 8, default=5, space='buy')
#
# buy_1_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
# buy_2_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
# buy_3_bb_lower_5 = DecimalParameter(0, 0.6, decimals=2, default=0.7, space='buy')
#
# buy_b_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.11908, space='buy')
# buy_b_cat = CategoricalParameter([">R", "=R", "<R"], default='<R', space='buy')
# buy_b_pct = DecimalParameter(0.001, 0.02, decimals=3, default=0.005, space='buy')
# buy_b_pct_1 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_b_pct_3 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_b_pct_5 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_b_bb_lowerband = DecimalParameter(1, 1.05, default=1, decimals=2, space='buy')
# buy_b_bb_width = DecimalParameter(0.01, 0.15, default=0.065, decimals=2, space='buy')
#
# decalage_h = IntParameter(0, 3, default=0, space='buy')
# decalage_b = IntParameter(0, 3, default=0, space='buy')
#
# buy_h_real = DecimalParameter(0.001, 0.999, decimals=4, default=0.11908, space='buy')
# buy_h_cat = CategoricalParameter([">R", "=R", "<R"], default='<R', space='buy')
# buy_h_pct = DecimalParameter(0.001, 0.02, decimals=3, default=0.005, space='buy')
# buy_h_pct_1 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_h_pct_3 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_h_pct_5 = DecimalParameter(-0.2, 0.2, decimals=2, default=0.005, space='buy')
# buy_h_bb_lowerband = DecimalParameter(1, 1.05, default=1, decimals=2, space='buy')
# buy_h_bb_width = DecimalParameter(0.01, 0.15, default=0.065, decimals=2, space='buy')
#
# buy_h_sma = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma10_1d', space='buy')
# buy_b_sma = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma10_1d', space='buy')
# buy_h_sma_close = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma3_1d', space='buy')
# buy_b_sma_close = CategoricalParameter(["sma3_1d", "sma5_1d", "sma10_1d"], default='sma3_1d', 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')
# sell_h_expected_profit = DecimalParameter(0, 0.01, decimals=3, default=0.01, space='sell')
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()
expected_profit = 0.01
#print(last_candle['buy_tag'])
days = (current_time - trade.open_date_utc).days
######
if True:
if (current_profit > 0.015) & ((last_candle['percent'] < -0.005) | (last_candle['percent3'] < -0.005) | (last_candle['percent5'] < -0.005)):
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 >= 0.015) & (last_candle['percent3'] < -0.005):
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 > last_candle['bb_width'] / 1.3) \
& (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'
def informative_pairs(self):
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# MACD
# macd = ta.MACD(dataframe)
# dataframe['macd'] = macd['macd']
# dataframe['macdsignal'] = macd['macdsignal']
# dataframe['macdhist'] = macd['macdhist']
# # # Plus Directional Indicator / Movement
# dataframe['plus_dm'] = ta.PLUS_DM(dataframe)
# dataframe['plus_di'] = ta.PLUS_DI(dataframe)
#
# # Minus Directional Indicator / Movement
# dataframe['adx'] = ta.ADX(dataframe)
# dataframe['minus_dm'] = ta.MINUS_DM(dataframe)
# dataframe['minus_di'] = ta.MINUS_DI(dataframe)
# dataframe['min'] = ta.MIN(dataframe)
# dataframe['max'] = ta.MAX(dataframe)
# # Aroon, Aroon Oscillator
# aroon = ta.AROON(dataframe)
# dataframe['aroonup'] = aroon['aroonup']
# dataframe['aroondown'] = aroon['aroondown']
# dataframe['aroonosc'] = ta.AROONOSC(dataframe)
# RSI
dataframe['rsi'] = talib.RSI(dataframe)
dataframe['rsi5'] = talib.RSI(dataframe, timeperiod=5)
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['min200_5'] = 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_max200_5'] = (dataframe['min200'] * (1 + dataframe['min_max200'] / 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["volume10"] = dataframe["volume"].rolling(10).mean()
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['volume5'] = dataframe["volume"].rolling(5).mean()
return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# conditions = [
# dataframe['bb_width'] >= self.buy_bollinger.value,
# (dataframe['close'] < dataframe['bb_lowerband']),
# (dataframe['close'] < dataframe['sma100'] * 0.99) #self.buy_sma_percent.value)
# ]
conditions_vol = []
conditions_vol.append(dataframe['percent5'] > 0) #self.buy_bollinger.value,
conditions_vol.append(dataframe['percent'].shift(1) > 0)
conditions_vol.append(dataframe['percent'] > 2 * dataframe['percent'].shift(1))
conditions_vol.append(dataframe['close'] > dataframe['open'])
# conditions_vol.append(dataframe['bb_width'] > dataframe['bb_width'].shift(3) * 2)
for decalage in range(5, 10):
conditions_vol.append(dataframe['bb_width'].shift(decalage) <= dataframe['bb_width'].shift(decalage - 1))
# conditions_vol.append(-0.002 <= dataframe['percent'].shift(decalage))
# conditions_vol.append(dataframe['percent'].shift(decalage) <= 0.002)
for decalage in range(2, 5):
conditions_vol.append(dataframe['volume5'].shift(decalage) <= dataframe['volume5'].shift(decalage - 1))
conditions_vol.append(dataframe['percent'].shift(decalage) <= dataframe['percent'].shift(decalage - 1))
# GUARDS AND TRENDS
dataframe.loc[
(
# (reduce(lambda x, y: x & y, conditions))
(reduce(lambda x, y: x & y, conditions_vol))
)
,
'buy'] = 1
return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# dataframe.loc[
# (
# (dataframe['close'] < dataframe['open']) &
# (dataframe['close'].shift(1) < dataframe['open'].shift(1)) &
# (dataframe['close'].shift(2) < dataframe['open'].shift(2)) &
# (dataframe['close'] < dataframe['bb_lowerband']) &
# (((dataframe['bb_lowerband'].shift(2) - dataframe['bb_lowerband']) / dataframe['bb_lowerband']) >= 0.02) &
# (((dataframe['close'].shift(1) - dataframe['close']) / dataframe['close']) >= 0.025)
# ), 'sell'] = 1
return dataframe