Skip to content

Commit 49797f7

Browse files
committed
Update
1 parent 887f185 commit 49797f7

File tree

3 files changed

+261
-34
lines changed

3 files changed

+261
-34
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
{
2+
"max_open_trades": 4,
3+
"stake_currency": "BUSD",
4+
"stake_amount" : "unlimited",
5+
"amend_last_stake_amount ": true,
6+
"tradable_balance_ratio": 0.99,
7+
"fiat_display_currency": "USD",
8+
"dry_run": true,
9+
"dry_run_wallet": 65,
10+
"cancel_open_orders_on_exit": false,
11+
"unfilledtimeout": {
12+
"buy": 10,
13+
"sell": 30
14+
},
15+
"order_types": {
16+
"buy": "market",
17+
"sell": "market",
18+
"emergencysell": "market",
19+
"trailing_stop_loss": "market",
20+
"stoploss": "market",
21+
"stoploss_on_exchange": false,
22+
"stoploss_on_exchange_interval": 60
23+
},
24+
"bid_strategy": {
25+
"price_side": "ask",
26+
"ask_last_balance": 0.0,
27+
"use_order_book": false,
28+
"order_book_top": 1,
29+
"check_depth_of_market": {
30+
"enabled": false,
31+
"bids_to_ask_delta": 1
32+
}
33+
},
34+
"ask_strategy": {
35+
"price_side": "bid",
36+
"use_order_book": false,
37+
"order_book_min": 1,
38+
"order_book_max": 1
39+
},
40+
"pairlists": [
41+
{"method": "StaticPairList"},
42+
],
43+
"exchange": {
44+
"name": "binance",
45+
"key": "1",
46+
"secret": "2",
47+
"ccxt_config": {"enableRateLimit": true},
48+
"ccxt_async_config": {
49+
"enableRateLimit": true,
50+
"rateLimit": 200
51+
},
52+
"pair_whitelist": [
53+
"ETH/BUSD",
54+
"BTCST/BUSD",
55+
"AXS/BUSD",
56+
"TLM/BUSD",
57+
"TVK/BUSD",
58+
"DOGE/BUSD",
59+
"SHIB/BUSD",
60+
"XRP/BUSD",
61+
"EOS/BUSD",
62+
"MATIC/BUSD",
63+
"SOL/BUSD",
64+
"BAKE/BUSD",
65+
"AUCTION/BUSD",
66+
"DOT/BUSD",
67+
"CAKE/BUSD",
68+
"DEXE/BUSD",
69+
"FRONT/BUSD",
70+
"LUNA/BUSD",
71+
"AUDIO/BUSD",
72+
"ALICE/BUSD",
73+
"DODO/BUSD",
74+
"SNX/BUSD",
75+
"VET/BUSD",
76+
"ENJ/BUSD",
77+
"SLP/BUSD",
78+
"ICP/BUSD",
79+
"MDX/BUSD",
80+
"AAVE/BUSD",
81+
"SAND/BUSD",
82+
"ETC/BUSD",
83+
"LINA/BUSD",
84+
"DEGO/BUSD",
85+
"LINK/BUSD",
86+
"COMP/BUSD",
87+
"UNI/BUSD",
88+
"WING/BUSD",
89+
"CVP/BUSD",
90+
"NANO/BUSD",
91+
"SXP/BUSD",
92+
"FOR/BUSD",
93+
"ATOM/BUSD",
94+
"MANA/BUSD",
95+
"RUNE/BUSD",
96+
"EPS/BUSD",
97+
"SUPER/BUSD",
98+
"UNFI/BUSD",
99+
"ONE/BUSD",
100+
"ALPHA/BUSD",
101+
"GHST/BUSD",
102+
"EGLD/BUSD",
103+
"SYS/BUSD",
104+
"BCH/BUSD",
105+
"PROM/BUSD",
106+
"SUSHI/BUSD",
107+
"XLM/BUSD",
108+
"IQ/BUSD",
109+
"LIT/BUSD",
110+
"KSM/BUSD",
111+
"GRT/BUSD",
112+
"XTZ/BUSD",
113+
"BAND/BUSD",
114+
"CTSI/BUSD",
115+
"POND/BUSD",
116+
"VIDT/BUSD",
117+
"IDEX/BUSD",
118+
"HEGIC/BUSD",
119+
"UFT/BUSD",
120+
"COVER/BUSD",
121+
"LPT/BUSD",
122+
"XVS/BUSD",
123+
"BCHA/BUSD",
124+
"SC/BUSD",
125+
"MASK/BUSD",
126+
"KEEP/BUSD",
127+
"AERGO/BUSD",
128+
"FIS/BUSD",
129+
"ADA/BUSD",
130+
"DATA/BUSD",
131+
"PERP/BUSD",
132+
"SKL/BUSD",
133+
"XVG/BUSD",
134+
"THETA/BUSD",
135+
"BZRX/BUSD",
136+
"DASH/BUSD",
137+
"CHZ/BUSD",
138+
"SRM/BUSD",
139+
"NEO/BUSD",
140+
"TRX/BUSD",
141+
"REEF/BUSD",
142+
"ZIL/BUSD",
143+
"FTM/BUSD",
144+
"IOST/BUSD",
145+
"JUV/BUSD",
146+
"SFP/BUSD",
147+
"HARD/BUSD",
148+
"BTT/BUSD",
149+
"ICX/BUSD",
150+
"IOTA/BUSD",
151+
"POLS/BUSD",
152+
"BEL/BUSD",
153+
"RSR/BUSD",
154+
"CRV/BUSD",
155+
"HBAR/BUSD",
156+
"ATA/BUSD",
157+
"WRX/BUSD",
158+
"AVAX/BUSD",
159+
"RAMP/BUSD",
160+
"1INCH/BUSD",
161+
"YFI/BUSD",
162+
"KAVA/BUSD",
163+
"ACM/BUSD",
164+
"TKO/BUSD",
165+
"COTI/BUSD",
166+
"ALGO/BUSD",
167+
"KNC/BUSD",
168+
"OCEAN/BUSD",
169+
"FIO/BUSD",
170+
"HOT/BUSD",
171+
"PHA/BUSD",
172+
"WAVES/BUSD",
173+
"IOTX/BUSD",
174+
"AR/BUSD",
175+
"HNT/BUSD",
176+
"MIR/BUSD",
177+
"TWT/BUSD",
178+
"CTK/BUSD"
179+
],
180+
"pair_blacklist": []
181+
},
182+
"edge": {
183+
"enabled": false,
184+
"process_throttle_secs": 3600,
185+
"calculate_since_number_of_days": 7,
186+
"allowed_risk": 0.01,
187+
"stoploss_range_min": -0.01,
188+
"stoploss_range_max": -0.1,
189+
"stoploss_range_step": -0.01,
190+
"minimum_winrate": 0.60,
191+
"minimum_expectancy": 0.10,
192+
"min_trade_number": 10,
193+
"max_trade_duration_minute": 1440,
194+
"remove_pumps": false
195+
},
196+
"api_server": {
197+
"enabled": false,
198+
"listen_ip_address": "0.0.0.0",
199+
"listen_port": 8080,
200+
"verbosity": "error",
201+
"jwt_secret_key": "00",
202+
"CORS_origins": [],
203+
"username": "11",
204+
"password": "22"
205+
},
206+
"bot_name": "freqtrade_bot",
207+
"initial_state": "running",
208+
"forcebuy_enable": false,
209+
"internals": {
210+
"process_throttle_secs": 5
211+
}
212+
}

user_data/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@
9696
},
9797
"db_url": "sqlite:////freqtrade/user_data/tradesv3.sqlite",
9898
"user_data_dir" : "user_data",
99-
"strategy": "SampleStrategy",
99+
"strategy": "MultiMA_TSL",
100100
"strategy_path": "user_data/strategies"
101101
}

user_data/strategies/MultiMA_TSL.py

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from functools import reduce
99
from freqtrade.persistence import Trade
1010
from datetime import datetime, timedelta
11-
from freqtrade.exchange import timeframe_to_prev_date
1211

1312

1413
###########################################################################################################
@@ -55,9 +54,9 @@ class MultiMA_TSL(IStrategy):
5554
high_offset_ema = DecimalParameter(0.99, 1.1, default=1.012, load=True, space='sell', optimize=False)
5655
rsi_buy_ema = IntParameter(30, 70, default=61, space='buy', optimize=False)
5756

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)
6160

6261
# Protection
6362
ewo_low = DecimalParameter(
@@ -72,7 +71,7 @@ class MultiMA_TSL(IStrategy):
7271
# Trailing stoploss (not used)
7372
trailing_stop = False
7473
trailing_only_offset_is_reached = True
75-
trailing_stop_positive = 0.001
74+
trailing_stop_positive = 0.01
7675
trailing_stop_positive_offset = 0.018
7776

7877
use_custom_stoploss = True
@@ -93,6 +92,7 @@ class MultiMA_TSL(IStrategy):
9392

9493
# Optimal timeframe for the strategy.
9594
timeframe = '5m'
95+
informative_timeframe = '1h'
9696

9797
# Run "populate_indicators()" only for new candle.
9898
process_only_new_candles = True
@@ -118,40 +118,19 @@ def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
118118
return 0.02
119119
elif (current_profit > 0.03):
120120
return 0.01
121-
elif (current_profit > 0.018):
121+
elif (current_profit > 0.016):
122122
return 0.005
123123

124124
return 0.99
125125

126126
def get_ticker_indicator(self):
127127
return int(self.timeframe[:-1])
128128

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-
150129
def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str, **kwargs) -> bool:
151130
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
152131
last_candle = dataframe.iloc[-1].squeeze()
153132

154-
if ((rate > last_candle['close'])) : return False
133+
if (rate > (last_candle['close'] * 1)) : return False
155134

156135
return True
157136

@@ -160,7 +139,7 @@ def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: f
160139
current_time: datetime, **kwargs) -> bool:
161140

162141
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)):
164143
# Reject sell signal when trailing stoplosses
165144
return False
166145
return True
@@ -172,20 +151,40 @@ def informative_pairs(self):
172151
informative_pairs = [(pair, '1h') for pair in pairs]
173152
return informative_pairs
174153

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+
175161
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+
176171
# EWO
177172
dataframe['ewo'] = EWO(dataframe, self.fast_ewo.value, self.slow_ewo.value)
178173

179174
# RSI
180175
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)
181178

182179
return dataframe
183180

184181
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
185182
conditions = []
186183

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
189188

190189
dataframe.loc[:, 'buy_tag'] = ''
191190

@@ -220,6 +219,10 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
220219
conditions.append(buy_offset_trima)
221220

222221
add_check = (
222+
(dataframe['rsi_fast'] < 30)
223+
&
224+
(dataframe['close'] < dataframe['ema_offset_sell'])
225+
&
223226
(dataframe['volume'] > 0)
224227
)
225228

@@ -229,10 +232,22 @@ def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
229232
return dataframe
230233

231234
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 = []
232238

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+
)
234245

235-
dataframe.loc[:,'sell'] = 0
246+
if conditions:
247+
dataframe.loc[
248+
reduce(lambda x, y: x | y, conditions),
249+
'sell'
250+
]=1
236251

237252
return dataframe
238253

0 commit comments

Comments
 (0)