8
8
from functools import reduce
9
9
from freqtrade .persistence import Trade
10
10
from datetime import datetime , timedelta
11
- from freqtrade .exchange import timeframe_to_prev_date
12
11
13
12
14
13
###########################################################################################################
@@ -55,9 +54,9 @@ class MultiMA_TSL(IStrategy):
55
54
high_offset_ema = DecimalParameter (0.99 , 1.1 , default = 1.012 , load = True , space = 'sell' , optimize = False )
56
55
rsi_buy_ema = IntParameter (30 , 70 , default = 61 , space = 'buy' , optimize = False )
57
56
58
- base_nb_candles_buy_trima = IntParameter (5 , 80 , default = 20 , load = True , space = 'buy' , optimize = True )
59
- low_offset_trima = DecimalParameter (0.9 , 0.99 , default = 0.958 , load = True , space = 'buy' , optimize = True )
60
- rsi_buy_trima = IntParameter (30 , 70 , default = 61 , space = 'buy' , optimize = True )
57
+ base_nb_candles_buy_trima = IntParameter (5 , 80 , default = 20 , load = True , space = 'buy' , optimize = False )
58
+ low_offset_trima = DecimalParameter (0.9 , 0.99 , default = 0.958 , load = True , space = 'buy' , optimize = False )
59
+ rsi_buy_trima = IntParameter (30 , 70 , default = 61 , space = 'buy' , optimize = False )
61
60
62
61
# Protection
63
62
ewo_low = DecimalParameter (
@@ -72,7 +71,7 @@ class MultiMA_TSL(IStrategy):
72
71
# Trailing stoploss (not used)
73
72
trailing_stop = False
74
73
trailing_only_offset_is_reached = True
75
- trailing_stop_positive = 0.001
74
+ trailing_stop_positive = 0.01
76
75
trailing_stop_positive_offset = 0.018
77
76
78
77
use_custom_stoploss = True
@@ -93,6 +92,7 @@ class MultiMA_TSL(IStrategy):
93
92
94
93
# Optimal timeframe for the strategy.
95
94
timeframe = '5m'
95
+ informative_timeframe = '1h'
96
96
97
97
# Run "populate_indicators()" only for new candle.
98
98
process_only_new_candles = True
@@ -118,40 +118,19 @@ def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
118
118
return 0.02
119
119
elif (current_profit > 0.03 ):
120
120
return 0.01
121
- elif (current_profit > 0.018 ):
121
+ elif (current_profit > 0.016 ):
122
122
return 0.005
123
123
124
124
return 0.99
125
125
126
126
def get_ticker_indicator (self ):
127
127
return int (self .timeframe [:- 1 ])
128
128
129
- def custom_sell (self , pair : str , trade : 'Trade' , current_time : 'datetime' , current_rate : float ,
130
- current_profit : float , ** kwargs ):
131
- dataframe , _ = self .dp .get_analyzed_dataframe (pair , self .timeframe )
132
- buy_tag = 'empty'
133
- if hasattr (trade , 'buy_tag' ) and trade .buy_tag is not None :
134
- buy_tag = trade .buy_tag
135
- else :
136
- trade_open_date = timeframe_to_prev_date (self .timeframe , trade .open_date_utc )
137
- buy_signal = dataframe .loc [dataframe ['date' ] < trade_open_date ]
138
- if not buy_signal .empty :
139
- buy_signal_candle = buy_signal .iloc [- 1 ]
140
- buy_tag = buy_signal_candle ['buy_tag' ] if buy_signal_candle ['buy_tag' ] != '' else 'empty'
141
- buy_tags = buy_tag .split ()
142
-
143
- last_candle = dataframe .iloc [- 1 ].squeeze ()
144
-
145
- if (last_candle ['close' ] > (last_candle ['ema_offset_sell' ])) :
146
- return 'sell signal (' + buy_tag + ')'
147
-
148
- return None
149
-
150
129
def confirm_trade_entry (self , pair : str , order_type : str , amount : float , rate : float , time_in_force : str , ** kwargs ) -> bool :
151
130
dataframe , _ = self .dp .get_analyzed_dataframe (pair , self .timeframe )
152
131
last_candle = dataframe .iloc [- 1 ].squeeze ()
153
132
154
- if (( rate > last_candle ['close' ])) : return False
133
+ if (rate > ( last_candle ['close' ] * 1 )) : return False
155
134
156
135
return True
157
136
@@ -160,7 +139,7 @@ def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: f
160
139
current_time : datetime , ** kwargs ) -> bool :
161
140
162
141
current_profit = trade .calc_profit_ratio (rate )
163
- if (sell_reason . startswith ( 'sell signal (' ) and (current_profit > 0.018 )):
142
+ if (( sell_reason == 'sell_signal' ) and (current_profit > 0.016 )):
164
143
# Reject sell signal when trailing stoplosses
165
144
return False
166
145
return True
@@ -172,20 +151,40 @@ def informative_pairs(self):
172
151
informative_pairs = [(pair , '1h' ) for pair in pairs ]
173
152
return informative_pairs
174
153
154
+ def informative_1h_indicators (self , dataframe : DataFrame , metadata : dict ) -> DataFrame :
155
+ assert self .dp , "DataProvider is required for multiple timeframes."
156
+ # Get the informative pair
157
+ informative_1h = self .dp .get_pair_dataframe (pair = metadata ['pair' ], timeframe = self .informative_timeframe )
158
+
159
+ return informative_1h
160
+
175
161
def populate_indicators (self , dataframe : DataFrame , metadata : dict ) -> DataFrame :
162
+ # The indicators for the 1h informative timeframe
163
+ # informative_1h = self.informative_1h_indicators(dataframe, metadata)
164
+ # dataframe = merge_informative_pair(dataframe, informative_1h, self.timeframe, self.informative_timeframe, ffill=True)
165
+
166
+ if not self .config ['runmode' ].value == 'hyperopt' :
167
+ dataframe ['ema_offset_buy' ] = ta .EMA (dataframe , int (self .base_nb_candles_buy_ema .value )) * self .low_offset_ema .value
168
+ dataframe ['trima_offset_buy' ] = ta .TRIMA (dataframe , int (self .base_nb_candles_buy_trima .value )) * self .low_offset_trima .value
169
+ dataframe ['ema_offset_sell' ] = ta .EMA (dataframe , int (self .base_nb_candles_sell .value )) * self .high_offset_ema .value
170
+
176
171
# EWO
177
172
dataframe ['ewo' ] = EWO (dataframe , self .fast_ewo .value , self .slow_ewo .value )
178
173
179
174
# RSI
180
175
dataframe ['rsi' ] = ta .RSI (dataframe , timeperiod = 14 )
176
+ dataframe ['rsi_fast' ] = ta .RSI (dataframe , timeperiod = 4 )
177
+ # dataframe['rsi_slow'] = ta.RSI(dataframe, timeperiod=20)
181
178
182
179
return dataframe
183
180
184
181
def populate_buy_trend (self , dataframe : DataFrame , metadata : dict ) -> DataFrame :
185
182
conditions = []
186
183
187
- dataframe ['ema_offset_buy' ] = ta .EMA (dataframe , int (self .base_nb_candles_buy_ema .value )) * self .low_offset_ema .value
188
- dataframe ['trima_offset_buy' ] = ta .TRIMA (dataframe , int (self .base_nb_candles_buy_trima .value )) * self .low_offset_trima .value
184
+ if self .config ['runmode' ].value == 'hyperopt' :
185
+ dataframe ['ema_offset_buy' ] = ta .EMA (dataframe , int (self .base_nb_candles_buy_ema .value )) * self .low_offset_ema .value
186
+ dataframe ['trima_offset_buy' ] = ta .TRIMA (dataframe , int (self .base_nb_candles_buy_trima .value )) * self .low_offset_trima .value
187
+ dataframe ['ema_offset_sell' ] = ta .EMA (dataframe , int (self .base_nb_candles_sell .value )) * self .high_offset_ema .value
189
188
190
189
dataframe .loc [:, 'buy_tag' ] = ''
191
190
@@ -220,6 +219,10 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
220
219
conditions .append (buy_offset_trima )
221
220
222
221
add_check = (
222
+ (dataframe ['rsi_fast' ] < 30 )
223
+ &
224
+ (dataframe ['close' ] < dataframe ['ema_offset_sell' ])
225
+ &
223
226
(dataframe ['volume' ] > 0 )
224
227
)
225
228
@@ -229,10 +232,22 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
229
232
return dataframe
230
233
231
234
def populate_sell_trend (self , dataframe : DataFrame , metadata : dict ) -> DataFrame :
235
+ if self .config ['runmode' ].value == 'hyperopt' :
236
+ dataframe ['ema_offset_sell' ] = ta .EMA (dataframe , int (self .base_nb_candles_sell .value )) * self .high_offset_ema .value
237
+ conditions = []
232
238
233
- dataframe ['ema_offset_sell' ] = ta .EMA (dataframe , int (self .base_nb_candles_sell .value )) * self .high_offset_ema .value
239
+ conditions .append (
240
+ (
241
+ (dataframe ['close' ] > dataframe ['ema_offset_sell' ]) &
242
+ (dataframe ['volume' ] > 0 )
243
+ )
244
+ )
234
245
235
- dataframe .loc [:,'sell' ] = 0
246
+ if conditions :
247
+ dataframe .loc [
248
+ reduce (lambda x , y : x | y , conditions ),
249
+ 'sell'
250
+ ]= 1
236
251
237
252
return dataframe
238
253
0 commit comments