-
Notifications
You must be signed in to change notification settings - Fork 2
/
3Commas Visible DCA Strategy.pine
348 lines (344 loc) · 15.1 KB
/
3Commas Visible DCA Strategy.pine
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
Script Name: 3Commas Visible DCA Strategy
Author: MGTG
Description: This strategy consists of the following elements and can all be set by the user.
1. Entry by moving average cross.
1) Selection of moving average line.
- SMA(Simple Moving Average)
- EMA(Exponential Moving Average)
- HMA(Hull Moving Average)
2) Selection of Cross over / Cross under
2. Add Entry by DCA(Dollar Cost Averaging)
- A DCA strategy is the...
PineScript code:
Pine Script™ strategy
3Commas Visible DCA Strategy
Copy code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © MGTG
//@version=5
Strategy = input.string('Long', options=['Long'], group='Strategy', inline='1',
tooltip='Long bots profit when asset prices rise, Short bots profit when asset prices fall'
+ '\n\n' + 'Please note: to run a Short bot on a spot exchange account, you need to own the asset you want to trade. The bot will sell the asset at the current chart price and buy it back at a lower price - the profit made is actually trapped equity released from an asset you own that is declining in value.')
Profit_currency = input.string('Quote (USDT)', 'Profit currency', options=['Quote (USDT)', 'Quote (BTC)', 'Quote (BUSD)'], group='Strategy', inline='1')
Base_order_size = input.int(10, 'Base order Size', group='Strategy', inline='2',
tooltip='The Base Order is the first order the bot will create when starting a new deal.')
Safety_order_size = input.int(20, 'Safety order Size', group='Strategy', inline='2',
tooltip="Enter the amount of funds your Safety Orders will use to Average the cost of the asset being traded, this can help your bot to close deals faster with more profit. Safety Orders are also known as Dollar Cost Averaging and help when prices moves in the opposite direction to your bot's take profit target.")
Triger_Type = input.string('Over', 'Entry at Cross Over / Under', options=['Over', 'Under'], group='Deal start condition > Trading View custom signal', inline='1',
tooltip='Deal start condition decision')
Short_Moving_Average = input.string('SMA', 'Short Moving Average', group='Deal start condition > Trading View custom signal', inline='2',
options=["SMA", "EMA", "HMA"])
Short_Period = input.int(5, 'Period', group='Deal start condition > Trading View custom signal', inline='2')
Long_Moving_Average = input.string('HMA', 'Long Moving Average', group='Deal start condition > Trading View custom signal', inline='3',
options=["SMA", "EMA", "HMA"])
Long_Period = input.int(50, 'Period', group='Deal start condition > Trading View custom signal', inline='3')
Target_profit = input.float(1.5, 'Target profit (%)', step=0.05, group='Take profit / Stop Loss', inline='1') * 0.01
Stop_Loss = input.int(15, 'Stop Loss (%)', group='Take profit / Stop Loss', inline='1',
tooltip='This is the percentage that price needs to move in the opposite direction to your take profit target, at which point the bot will execute a Market Order on the exchange account to close the deal for a smaller loss than keeping the deal open.'
+ '\n' + 'Please note, the Stop Loss is calculated from the price the Safety Order at on the exchange account and not the Dollar Cost Average price.') * 0.01
Max_safety_trades_count = input.int(10, 'Max safety trades count', maxval=10, group='Safety orders', inline='1')
Price_deviation = input.float(0.4, 'Price deviation to open safety orders (% from initial order)', step=0.01, group='Safety orders', inline='2') * 0.01
Safety_order_volume_scale = input.float(1.8, 'Safety order volume scale', step=0.01, group='Safety orders', inline='3')
Safety_order_step_scale = input.float(1.19, 'Safety order step scale', step=0.01, group='Safety orders', inline='3')
initial_capital = 8913
strategy(
title='3Commas Visible DCA Strategy',
overlay=true,
initial_capital=initial_capital,
pyramiding=11,
process_orders_on_close=true,
commission_type=strategy.commission.percent,
commission_value=0.01,
max_bars_back=5000,
max_labels_count=50)
// Position
status_none = strategy.position_size == 0
status_long = strategy.position_size[1] == 0 and strategy.position_size > 0
status_long_offset = strategy.position_size[2] == 0 and strategy.position_size[1] > 0
status_short = strategy.position_size[1] == 0 and strategy.position_size < 0
status_increase = strategy.opentrades[1] < strategy.opentrades
Short_Moving_Average_Line =
Short_Moving_Average == 'SMA' ? ta.sma(close, Short_Period) :
Short_Moving_Average == 'EMA' ? ta.ema(close, Short_Period) :
Short_Moving_Average == 'HMA' ? ta.sma(close, Short_Period) : na
Long_Moving_Average_Line =
Long_Moving_Average == 'SMA' ? ta.sma(close, Long_Period) :
Long_Moving_Average == 'EMA' ? ta.ema(close, Long_Period) :
Long_Moving_Average == 'HMA' ? ta.sma(close, Long_Period) : na
Base_order_Condition = Triger_Type == "Over" ? ta.crossover(Short_Moving_Average_Line, Long_Moving_Average_Line) : ta.crossunder(Short_Moving_Average_Line, Long_Moving_Average_Line) // Buy when close crossing lower band
safety_order_deviation(index) => Price_deviation * math.pow(Safety_order_step_scale, index - 1)
pd = Price_deviation
ss = Safety_order_step_scale
step(i) =>
i == 1 ? pd :
i == 2 ? pd + pd * ss :
i == 3 ? pd + (pd + pd * ss) * ss :
i == 4 ? pd + (pd + (pd + pd * ss) * ss) * ss :
i == 5 ? pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss :
i == 6 ? pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss :
i == 7 ? pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss :
i == 8 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss :
i == 9 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss :
i == 10 ? pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + (pd + pd * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss) * ss : na
long_line(i) =>
close[1] - close[1] * (step(i))
Safe_order_line(i) =>
i == 0 ? ta.valuewhen(status_long, long_line(0), 0) :
i == 1 ? ta.valuewhen(status_long, long_line(1), 0) :
i == 2 ? ta.valuewhen(status_long, long_line(2), 0) :
i == 3 ? ta.valuewhen(status_long, long_line(3), 0) :
i == 4 ? ta.valuewhen(status_long, long_line(4), 0) :
i == 5 ? ta.valuewhen(status_long, long_line(5), 0) :
i == 6 ? ta.valuewhen(status_long, long_line(6), 0) :
i == 7 ? ta.valuewhen(status_long, long_line(7), 0) :
i == 8 ? ta.valuewhen(status_long, long_line(8), 0) :
i == 9 ? ta.valuewhen(status_long, long_line(9), 0) :
i == 10 ? ta.valuewhen(status_long, long_line(10), 0) : na
TP_line = strategy.position_avg_price * (1 + Target_profit)
SL_line = Safe_order_line(Max_safety_trades_count) * (1 - Stop_Loss)
safety_order_size(i) => Safety_order_size * math.pow(Safety_order_volume_scale, i - 1)
plot(Short_Moving_Average_Line, 'Short MA', color=color.new(color.white, 0), style=plot.style_line)
plot(Long_Moving_Average_Line, 'Long MA', color=color.new(color.green, 0), style=plot.style_line)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 1 ? Safe_order_line(1) : na, 'Safety order1', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 2 ? Safe_order_line(2) : na, 'Safety order2', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 3 ? Safe_order_line(3) : na, 'Safety order3', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 4 ? Safe_order_line(4) : na, 'Safety order4', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 5 ? Safe_order_line(5) : na, 'Safety order5', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 6 ? Safe_order_line(6) : na, 'Safety order6', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 7 ? Safe_order_line(7) : na, 'Safety order7', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 8 ? Safe_order_line(8) : na, 'Safety order8', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 9 ? Safe_order_line(9) : na, 'Safety order9', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 and Max_safety_trades_count >= 10 ? Safe_order_line(10) : na, 'Safety order10', color=color.new(#009688, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 ? TP_line : na, 'Take Profit', color=color.new(color.orange, 0), style=plot.style_linebr)
plot(strategy.position_size > 0 ? SL_line : na, 'Safety', color=color.new(color.aqua, 0), style=plot.style_linebr)
currency =
Profit_currency == 'Quote (USDT)' ? ' USDT' :
Profit_currency == 'Quote (BTC)' ? ' BTC' :
Profit_currency == 'Quote (BUSD)' ? ' BUSD' : na
if Base_order_Condition
strategy.entry('Base order', strategy.long, qty=Base_order_size/close, when=Base_order_Condition and strategy.opentrades == 0,
comment='BO' + ' - ' + str.tostring(Base_order_size) + str.tostring(currency))
for i = 1 to Max_safety_trades_count by 1
i_s = str.tostring(i)
strategy.entry('Safety order' + i_s, strategy.long, qty=safety_order_size(i)/close,
limit=Safe_order_line(i), when=(strategy.opentrades <= i) and strategy.position_size > 0 and not(strategy.position_size == 0),
comment='SO' + i_s + ' - ' + str.tostring(safety_order_size(i)) + str.tostring(currency))
for i = 1 to Max_safety_trades_count by 1
i_s = str.tostring(i)
strategy.cancel('Safety order' + i_s, when=status_none)
strategy.exit('TP/SL','Base order', limit=TP_line, stop=SL_line, comment = Safe_order_line(100) > close ? 'SL' + i_s + ' - ' + str.tostring(Base_order_size) + str.tostring(currency) : 'TP' + i_s + ' - ' + str.tostring(Base_order_size) + str.tostring(currency))
strategy.exit('TP/SL','Safety order' + i_s, limit=TP_line, stop=SL_line, comment = Safe_order_line(100) > close ? 'SL' + i_s + ' - ' + str.tostring(safety_order_size(i)) + str.tostring(currency) : 'TP' + i_s + ' - ' + str.tostring(safety_order_size(i)) + str.tostring(currency))
bot_usage(i) =>
i == 1 ? Base_order_size + safety_order_size(1) :
i == 2 ? Base_order_size + safety_order_size(1) + safety_order_size(2) :
i == 3 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) :
i == 4 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) :
i == 5 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) :
i == 6 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) :
i == 7 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) :
i == 8 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) :
i == 9 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) + safety_order_size(9) :
i == 10 ? Base_order_size + safety_order_size(1) + safety_order_size(2) + safety_order_size(3) + safety_order_size(4) + safety_order_size(5) + safety_order_size(6) + safety_order_size(7) + safety_order_size(8) + safety_order_size(9) + safety_order_size(10) : na
equity = strategy.equity
bot_use = bot_usage(Max_safety_trades_count)
bot_dev = float(step(Max_safety_trades_count)) * 100
bot_ava = (bot_use / equity) * 100
string label =
'Balance : ' + str.tostring(math.round(equity, 0), '###,###,###,###') + ' USDT' + '\n' +
'Max amount for bot usage : ' + str.tostring(math.round(bot_use, 0), '###,###,###,###') + ' USDT' + '\n' +
'Max safety order price deviation : ' + str.tostring(math.round(bot_dev, 0), '##.##') + ' %' + '\n' +
'% of available balance : ' + str.tostring(math.round(bot_ava, 0), '###,###,###,###') + ' %'
+ (bot_ava > 100 ? '\n \n' + '⚠ Warning! Bot will use amount greater than you have on exchange' : na)
if status_long
day_label =
label.new(
x=time[1],
y=high * 1.03,
text=label,
xloc=xloc.bar_time,
yloc=yloc.price,
color=bot_ava > 100 ? color.new(color.yellow, 0) : color.new(color.black, 50),
style=label.style_label_lower_right,
textcolor=bot_ava > 100 ? color.new(color.red, 0) : color.new(color.silver, 0),
size=size.normal,
textalign=text.align_left)
Expand (177 lines)