-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy path5min Williams Fractals scalping (3commas).pine
More file actions
414 lines (412 loc) · 17.6 KB
/
5min Williams Fractals scalping (3commas).pine
File metadata and controls
414 lines (412 loc) · 17.6 KB
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
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
Script Name: 5min Williams Fractals scalping (3commas)
Author: Zippy111
Description: Another strategy I'm learning Pine Script on. It is inspired by a MoneyZG youtube strategy called "Easy 5 Minute Scalping Strategy (Simple to Follow Scalping Trading Strategy)".
Again this is a one order per trade strategy compatible with the 3commas bot (works also with the free 3commas subscription). This strategy is based on the signals from Williams Fractals,...
PineScript code:
Pine Script™ strategy
5min Williams Fractals scalping (3commas)
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
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
//@version=5
strategy("5min Williams Fractals scalping (3commas)", shorttitle="5min WF scalp", format=format.price, precision=0, overlay=true)
// Define "n" as the number of periods and keep a minimum value of 2 for error handling.
import ZenAndTheArtOfTrading/ZenLibrary/2 as l_zen
var g_strategy = "Strategy"
i_chkLong = input.bool(true, title = 'Long', inline = '1', group = g_strategy)
i_chkShort = input.bool(true, title = 'Short', inline = '1', group = g_strategy)
i_startTime = input.time(title = 'Start Date', defval = timestamp('01 Jan 2020 00:00 +0100'), group = g_strategy, tooltip = 'Date & time to begin trading from')
i_endTime = input.time(title = 'End Date', defval = timestamp('1 Jan 2099 00:00 +0100'), group = g_strategy, tooltip = 'Date & time to stop trading')
i_longProfitPerc = input.float(title ='Long Target Profit R:R', minval = 1.1, step = 0.1, defval = 1.5, inline ='2', group = g_strategy, tooltip = "Times the Stop Loss which is always the current Ema slow value")
i_shortProfitPerc = input.float(title = 'Short Target Profit R:R', minval = 1.1, step = 0.1, defval = 1.5, inline = '3', group = g_strategy, tooltip = "Times the Stop Loss which is always the current Ema slow value")
i_tradeDontClose = input.int(title = "Stop loss not sooner than", defval = 0, minval = 0, group = g_strategy, tooltip = "If an open trade hits the Stop loss sooner than the expected amount of bars have passed, then SL will not trigger (eg. for thight stop losses)")
var g_wf = "Williams Fractals"
i_wf = input.int(title="Periods", defval=2, minval=2, group = g_wf)
i_wfBarsBack = input.bool(defval = true, title = "Evaluate WF bar", group = g_wf, tooltip = "By default it evaluates the bar for which the WF signal triggers so when turned off it evaluates the current bar")
var g_ema = "EMA trend"
i_emaFast = input.int(title = "Ema fast lenght", defval = 20, step = 1, group = g_ema)
i_emaSlow = input.int(title = "Ema slow lenght", defval = 50, step = 1, group = g_ema)
i_emaGapUse = input.bool(title = "Use Ema Gap", defval = false, group = g_ema, tooltip = "Gap between Emas must be greater than % of the whole security price,\neg. 0.1 = 0.1% of the security price which is the minimum gap tolerated for an entry")
i_emaGap = input.float(title = "Ema Gap %", defval = 0.2, step = 0.05, group = g_ema)
var g_rsi = "RSI filter"
i_rsiChk = input.bool(false, "Use RSI Filter", group = g_rsi)
i_rsiRes = input.timeframe("", "TimeFrame", group = g_rsi)
i_rsiLen = input.int(14, "Lenght", group = g_rsi)
i_rsiMinLong = input.float(0.0, "Min for Long", minval = 0.0, maxval = 100.0, step = 0.5, group = g_rsi, inline = "4")
i_rsiMaxLong = input.float(70.0, "Max for Long", minval = 0.0, maxval = 100.0, step = 0.5, group = g_rsi, inline = "4")
i_rsiMinShort = input.float(30.0, "Min for Short", minval = 0.0, maxval = 100.0, step = 0.5, group = g_rsi, inline = "5")
i_rsiMaxShort = input.float(100.0, "Max for Short", minval = 0.0, maxval = 100.0, step = 0.5, group = g_rsi, inline = "5")
i_rsiDirectChk = input.bool(false, "RSI direction confirmation", group = g_rsi, tooltip = "Long only if its supported by rising RSI and Short only if its supported by falling RSI\nWorks only if Use RSI is ON")
i_rsiDirectLen = input.int(1, "Bars back for direction", minval = 1, group = g_rsi, tooltip = "Lookback period for RSI values")
var g_additional = "Pullback filter"
i_usePullbackChk = input.bool(false, title = 'Use Pullback', group = g_additional, tooltip = "Checks if the amount of oposite candles (bearish when long) in the lookback period (counts from second history candle)is smaller than the NOT bigger count and vice versa")
i_pullbackCount = input.int(title="Lookback period", defval=2, minval = 1, group = g_additional)
i_pullbackNotBigger = input.int(title="NOT bigger than", defval=1, minval = 0, group = g_additional)
var g_tester = 'Back tester table'
i_drawTester = input.bool(title='Show back tester', defval=true, group=g_tester, tooltip='Turn on/off inbuilt backtester display', inline = "backtester1")
i_testerPosition = input.string(title='', defval="Top right", options = ["Top right", "Top left", "Bottom right", "Bottom left"], group=g_tester, tooltip='Position of the backtester table', inline = "backtester1")
i_rr = input.float(title='R:R', defval=1.0, group=g_tester, tooltip='Risk:Reward profile')
startBalance = input.float(title='Starting Balance', defval=100.0, group=g_tester, tooltip='Your starting balance for the custom inbuilt tester system')
riskPerTrade = input.float(title='Risk Per Trade', defval=1.0, group=g_tester, tooltip='Your desired % risk per trade (as a whole number)')
var i_3Commas = '3Commas bot settings'
i_useComments = input.bool(false, "Show 3Commas bot comments", group = i_3Commas)
i_botIDLong = input(title="Long Bot ID", defval="", group = i_3Commas)
i_botIDShort = input(title="Short Bot ID", defval="", group = i_3Commas)
i_tokenID = input(title="Email Token", defval="", group = i_3Commas)
// Get strategy direction and set time
strategy.risk.allow_entry_in(i_chkLong and i_chkShort ? strategy.direction.all : i_chkLong ? strategy.direction.long : strategy.direction.short)
c_dateFilter = time >= i_startTime and time <= i_endTime // See if this bar's time happened within date filter
// Get Ema trend and conditions
c_emaFast = ta.ema(close[barstate.isrealtime ? 1 : 0], i_emaFast)
c_emaSlow = ta.ema(close[barstate.isrealtime ? 1 : 0], i_emaSlow)
c_emaCrossBull = c_emaFast >= c_emaSlow
c_emaCrossBear = c_emaFast < c_emaSlow
c_emaLong = i_wfBarsBack ?
close[i_wf] < c_emaFast[i_wf] and close[i_wf] > c_emaSlow[i_wf] :
close[barstate.isrealtime ? 1 : 0] < c_emaFast and close[barstate.isrealtime ? 1 : 0] > c_emaSlow
c_emaShort = i_wfBarsBack ?
(close[i_wf] > c_emaFast[i_wf] and close[i_wf] < c_emaSlow[i_wf]) :
close[barstate.isrealtime ? 1 : 0] > c_emaFast and close[barstate.isrealtime ? 1 : 0] < c_emaSlow
c_emaGap = math.abs(c_emaFast - c_emaSlow) >= ((close[barstate.isrealtime ? 1 : 0] / 100) * i_emaGap)
c_tradesOpen = ta.barssince(strategy.opentrades != 0)
// Get RSI values
f_rpSecurity(_symbol, _res, _src) =>
request.security(_symbol, _res, _src[barstate.isrealtime ? 1 : 0])
c_rsiSrc = f_rpSecurity("", i_rsiRes, close)
c_rsi = ta.rsi(c_rsiSrc, i_rsiLen)
c_rsiRising = ta.rising(c_rsi, i_rsiDirectLen)
c_rsiFalling = ta.falling(c_rsi, i_rsiDirectLen)
// Get pullback filter
c_pullbackCountGreen = l_zen.getPullbackBarCount(i_pullbackCount, 1)
c_pullbackCountRed = l_zen.getPullbackBarCount(i_pullbackCount, -1)
// Get Williams Fractals
bool c_upflagDownFrontier = true
bool c_upflagUpFrontier0 = true
bool c_upflagUpFrontier1 = true
bool c_upflagUpFrontier2 = true
bool c_upflagUpFrontier3 = true
bool c_upflagUpFrontier4 = true
for i = 1 to i_wf
c_upflagDownFrontier := c_upflagDownFrontier and (high[i_wf - i] < high[i_wf])
c_upflagUpFrontier0 := c_upflagUpFrontier0 and (high[i_wf + i] < high[i_wf])
c_upflagUpFrontier1 := c_upflagUpFrontier1 and (high[i_wf + 1] <= high[i_wf] and high[i_wf+i + 1] < high[i_wf])
c_upflagUpFrontier2 := c_upflagUpFrontier2 and (high[i_wf + 1] <= high[i_wf] and high[i_wf + 2] <= high[i_wf] and high[i_wf + i + 2] < high[i_wf])
c_upflagUpFrontier3 := c_upflagUpFrontier3 and (high[i_wf + 1] <= high[i_wf] and high[i_wf + 2] <= high[i_wf] and high[i_wf + 3] <= high[i_wf] and high[i_wf + i + 3] < high[i_wf])
c_upflagUpFrontier4 := c_upflagUpFrontier4 and (high[i_wf + 1] <= high[i_wf] and high[i_wf + 2] <= high[i_wf] and high[i_wf + 3] <= high[i_wf] and high[i_wf + 4] <= high[i_wf] and high[i_wf+i + 4] < high[i_wf])
c_flagUpFrontier = c_upflagUpFrontier0 or c_upflagUpFrontier1 or c_upflagUpFrontier2 or c_upflagUpFrontier3 or c_upflagUpFrontier4
c_upFractal = (c_upflagDownFrontier and c_flagUpFrontier)
bool c_downflagDownFrontier = true
bool c_downflagUpFrontier0 = true
bool c_downflagUpFrontier1 = true
bool c_downflagUpFrontier2 = true
bool c_downflagUpFrontier3 = true
bool c_downflagUpFrontier4 = true
for i = 1 to i_wf
c_downflagDownFrontier := c_downflagDownFrontier and (low[i_wf - i] > low[i_wf])
c_downflagUpFrontier0 := c_downflagUpFrontier0 and (low[i_wf + i] > low[i_wf])
c_downflagUpFrontier1 := c_downflagUpFrontier1 and (low[i_wf + 1] >= low[i_wf] and low[i_wf+i + 1] > low[i_wf])
c_downflagUpFrontier2 := c_downflagUpFrontier2 and (low[i_wf + 1] >= low[i_wf] and low[i_wf + 2] >= low[i_wf] and low[i_wf + i + 2] > low[i_wf])
c_downflagUpFrontier3 := c_downflagUpFrontier3 and (low[i_wf + 1] >= low[i_wf] and low[i_wf + 2] >= low[i_wf] and low[i_wf + 3] >= low[i_wf] and low[i_wf+i + 3] > low[i_wf])
c_downflagUpFrontier4 := c_downflagUpFrontier4 and (low[i_wf + 1] >= low[i_wf] and low[i_wf + 2] >= low[i_wf] and low[i_wf + 3] >= low[i_wf] and low[i_wf + 4] >= low[i_wf] and low[i_wf+i + 4] > low[i_wf])
c_flagDownFrontier = c_downflagUpFrontier0 or c_downflagUpFrontier1 or c_downflagUpFrontier2 or c_downflagUpFrontier3 or c_downflagUpFrontier4
c_downFractal = (c_downflagDownFrontier and c_flagDownFrontier)
c_sinceLastTrade = ta.barssince(strategy.closedtrades > strategy.closedtrades[1])
c_sinceLastLossTrade = ta.barssince(strategy.losstrades > strategy.losstrades[1])
var float c_longExitPrice = 0.0
var float c_shortExitPrice = 0.0
var float c_longStopPrice = 0.0
var float c_shortStopPrice = 0.0
c_longCondition = c_dateFilter and (c_downFractal) and
c_emaLong and c_emaCrossBull and (i_emaGapUse ? c_emaGap : true) and
(i_rsiChk ? (c_rsi >= i_rsiMinLong and c_rsi <= i_rsiMaxLong and (i_rsiDirectChk ? c_rsiRising : true)) : true) and
(i_usePullbackChk ? c_pullbackCountGreen : true)
c_shortCondition = c_dateFilter and (c_upFractal) and
c_emaShort and c_emaCrossBear and (i_emaGapUse ? c_emaGap : true) and
(i_rsiChk ? (c_rsi >= i_rsiMinShort and c_rsi <= i_rsiMaxShort and (i_rsiDirectChk ? c_rsiFalling : true)) : true) and
(i_usePullbackChk ? c_pullbackCountRed : true)
if c_longCondition and strategy.opentrades == 0
strategy.entry(
id = "LONG open",
direction = strategy.long,
comment = i_useComments ? '{\n "action": "start_bot_and_start_deal",\n "message_type": "bot",\n "bot_id": ' + str.tostring(i_botIDLong) + ',\n "email_token": "' + str.tostring(i_tokenID) + '",\n "delay_seconds": 0}' : na)
c_longStopPrice := c_emaSlow
c_longExitPrice := close + ((close - c_emaSlow) * i_longProfitPerc)
if ta.barssince(strategy.opentrades == 0) >= i_tradeDontClose
strategy.exit(
id = "Long close",
from_entry = "LONG open",
limit = c_longExitPrice,
stop = c_longStopPrice,
comment = i_useComments ? '{\n "action": "close_at_market_price_all_and_stop_bot",\n "message_type": "bot",\n "bot_id": ' + str.tostring(i_botIDLong) + ',\n "email_token": "' + str.tostring(i_tokenID) + '",\n "delay_seconds": 0}' : na)
if c_shortCondition and strategy.opentrades == 0
strategy.entry(
id = "SHORT open",
direction = strategy.short,
comment = i_useComments ? '{\n "action": "start_bot_and_start_deal",\n "message_type": "bot",\n "bot_id": ' + str.tostring(i_botIDShort) + ',\n "email_token": "' + str.tostring(i_tokenID) + '",\n "delay_seconds": 0}' : na)
c_shortStopPrice := c_emaSlow
c_shortExitPrice := close - ((c_emaSlow - close) * i_shortProfitPerc)
if ta.barssince(strategy.opentrades == 0) >= i_tradeDontClose
strategy.exit(
id = "Short close",
from_entry = "SHORT open",
limit = c_shortExitPrice,
stop = c_shortStopPrice,
comment = i_useComments ? '{\n "action": "close_at_market_price_all_and_stop_bot",\n "message_type": "bot",\n "bot_id": ' + str.tostring(i_botIDShort) + ',\n "email_token": "' + str.tostring(i_tokenID) + '",\n "delay_seconds": 0}' : na)
// Plot
plot(c_emaFast, "Ema fast", color = color.new(#4db6ac, 40), linewidth = 2, display = display.none)
plot(c_emaSlow, "Ema slow", color = color.new(#f57c00, 40), linewidth = 2, display = display.none)
plotshape(c_downFractal, title = "Long shape", style=shape.triangleup, location=location.belowbar, offset=-i_wf, color=#009688, size = size.tiny, display = display.none)
plotshape(c_upFractal, title = "Short shape", style=shape.triangledown, location=location.abovebar, offset=-i_wf, color=#F44336, size = size.tiny, display = display.none)
// --- BEGIN TESTER CODE --- //
// Declare performance tracking variables
var balance = startBalance
var maxBalance = 0.0
var totalWins = 0
var totalLoss = 0
// Detect winning trades
if strategy.wintrades != strategy.wintrades[1]
balance := balance + riskPerTrade / 100 * balance * i_rr
totalWins := totalWins + 1
if balance > maxBalance
maxBalance := balance
maxBalance
// Detect losing trades
if strategy.losstrades != strategy.losstrades[1]
balance := balance - riskPerTrade / 100 * balance
totalLoss := totalLoss + 1
// Prepare stats table
var table testTable = table.new(i_testerPosition == "Top right" ? position.top_right : i_testerPosition == "Top left" ? position.top_left : i_testerPosition == "Bottom right" ? position.bottom_right :position.bottom_left, 5, 2, border_width=2)
f_fillCell(_table, _column, _row, _title, _value, _bgcolor, _txtcolor) =>
_cellText = _title + '\n' + _value
table.cell(_table, _column, _row, _cellText, bgcolor=_bgcolor, text_color=_txtcolor)
// Draw stats table
var bgcolor = color.new(color.black, 0)
if i_drawTester
if barstate.islastconfirmedhistory
// Update table
dollarReturn = balance - startBalance
f_fillCell(testTable, 0, 0, 'Total Trades:', str.tostring(strategy.closedtrades), bgcolor, color.white)
f_fillCell(testTable, 0, 1, 'Win Rate:', str.tostring(l_zen.truncate(strategy.wintrades / strategy.closedtrades * 100, 2)) + '%', (strategy.wintrades / strategy.closedtrades * 100) >= 50 ? color.green : bgcolor, color.white)
f_fillCell(testTable, 1, 0, 'Starting:', '$' + str.tostring(startBalance), bgcolor, color.white)
f_fillCell(testTable, 1, 1, 'Ending:', '$' + str.tostring(l_zen.truncate(balance, 2)), balance > startBalance ? color.green : bgcolor, color.white)
// --- END BACKTESTER CODE --- //
Expand (219 lines)