-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathEzAlgo_V9.pine.txt
More file actions
executable file
·1232 lines (1050 loc) · 56.8 KB
/
EzAlgo_V9.pine.txt
File metadata and controls
executable file
·1232 lines (1050 loc) · 56.8 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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//@version=5
indicator("EzAlgo V9", overlay=true, max_labels_count=500, max_lines_count=500, max_boxes_count=500, max_bars_back=5000)
// User Input
showReversal = input(true, "Buy/Sell", group="REVERSAL INDICATORS", inline = 'rev1', tooltip = "use ONLY in confluence with any of the price action tools listed below")
colorBuy = input.color(#00dbff99, '', group="REVERSAL INDICATORS", inline= 'rev1')
colorSell = input.color(#e91e6399, '', group="REVERSAL INDICATORS", inline= 'rev1')
obos = input(true, "O.S/O.B", group="REVERSAL INDICATORS", inline = 'rev2', tooltip = "Oversold/Overbought Conditions. Bigger Reversals usually happen after these conditions, however a market can stay in these conditions for a long time. Oversold & Overbought is not a reversal signal in itself however when used in confluence with S/R and other momentum signals can be powerful")
colorOs = input.color(#00dbff48, '', group="REVERSAL INDICATORS", inline= 'rev2')
colorOb = input.color(#e91e6348, '', group="REVERSAL INDICATORS", inline= 'rev2')
showRibbon = input(true, "Trend Ribbon", group="REVERSAL INDICATORS", tooltip = "Change in Ribbon Color signals a shift in trend. Best used in trending markets to spot early signs of reversals")
uptrend = input(#00dbff66, "Uptrend", group="REVERSAL INDICATORS")
downtrend = input(#e91e6366, "Downtrend", group="REVERSAL INDICATORS")
showRevBands = input(false, "Reversal Bands", group="REVERSAL INDICATORS", tooltip = "Plots the average upper and lower bounds of price movement. Price could see a reversal when it approaches these boundaries. Use in confluence with other Support & Resistance")
colorupperband = input(#e91e6333, "Upper Bands", group="REVERSAL INDICATORS")
colorlowerband = input(#00dbff33, "Lower Bands", group="REVERSAL INDICATORS")
showEmas = input(false, "Moving Average S/R", group="SUPPORT & RESISTANCE", tooltip = "Three powerful Moving Averages. Price tends to respect these MAs making them invaluable as they act as S/R & help in identifying trend shifts")
colorEma1 = input(#eaeaea40, "Moving Average 1", group="SUPPORT & RESISTANCE")
colorEma2 = input(#00dbff40, "Moving Average 2", group="SUPPORT & RESISTANCE")
colorEma3 = input(#e91e6340, "Moving Average 3", group="SUPPORT & RESISTANCE")
currentTF = input.bool(false, title = "Liquidity Levels", group="SUPPORT & RESISTANCE", tooltip = "Zones of high volume activity before price moves in one direction. Price usually comes back to these levels to 'sweep' the liquidity by triggering stop losses to gather the fuel to propel itself back into the opposite direction. If price is approaching down to a liquidity zone, it tends to go slightly below the zone before quickly reversing back to the upside and vice versa for a bearish move. A common zone where swing failure pattern occurs. However it is highly risky to place limit orders at these zones as the price may not respect it at all and pass through with no resistance. Use ONLY in confluence with other S/R tools")
lowLineColorHTF = input.color(#efd09e50, "Bullish", group="SUPPORT & RESISTANCE")
highLineColorHTF = input.color(#ff7f5050, "Bearish", group="SUPPORT & RESISTANCE")
htfTF = input.timeframe("240", title = "Timeframe", group="SUPPORT & RESISTANCE")
show_fvg = input(false, 'Fair Value Gaps', group="SUPPORT & RESISTANCE", tooltip = "Fair Value Gaps occur when a Price leaves a specific level where there's less trading activity seen and only has a one-directional price movement. Typically these occur during aggressive trends where the the orders of the market makers do not get filled. Similar to order blocks price tends to re visit these zones at a later time")
i_mtfbearishfvgcolor = input.color(#226f54, "Bullish", group="SUPPORT & RESISTANCE")
i_mtfbullishfvgcolor = input.color(#f1abb9, "Bearish", group="SUPPORT & RESISTANCE")
i_tf = input.timeframe("240", "Timeframe", group="SUPPORT & RESISTANCE")
autofib = input(true, "Auto Golden Pocket", group="SUPPORT & RESISTANCE", tooltip = "The 0.5 and 0.618-65 Fibonacci Ratio often acts as a balancing point in the market. Finding consecutive candle closes above the 0.5-0.65 is a sign of strength, and finding consecutive candle closes under the 0.5-0.65 is a sign of weakness")
colorAll = input.color(#D1B000, "Color", group="SUPPORT & RESISTANCE")
timeframe = input.timeframe(defval = '240', group="SUPPORT & RESISTANCE")
showVP = input(true, "Volume Profile", group="SUPPORT & RESISTANCE", tooltip = "Volume profile scans a range of price action by looking back at previous price action to determine the level at which the highest Volume has been traded. This level is called the Point of Control which acts as a magnet attracting the price. When tested from the underside it can be a strong resistance and when tested from above it can be a strong support")
vp_bar_color = input(defval=color.new(color.gray, 60), title='Volume Bars')
vp_poc_color = input(defval=#eaeaea, title='Point of Control')
showms = input(false,title="ChoCH & BoS", group = "MARKET STRUCTURE", tooltip = "Change of character means, the market has changed its trend or order flow over a period of time. “Break of Structure” is used to describe a significant price movement that surpasses a crucial level of support or resistance on a chart.")
bosColor1 = input.color(#0097a7 , 'Bullish', group = "MARKET STRUCTURE")
bosColor2 = input.color(#c2185b , 'Bearish', group = "MARKET STRUCTURE")
showGann = input(false, 'Gann Swing (One Bar Key Pivot Points)', group = "MARKET STRUCTURE", tooltip = "The core technique used by the legendary trader W.D Gann. A simple yet powerful tool that tracks the 'swing' of the price, clearly showing the key pivot points. An excellent tool to track market structure, breakouts, swing failure patterns & setting stop losses. A close above a key swing high is considered bullish and close below a key swing low is bearish")
colorGann = input(#ff7f50, 'Swing Line', group = "MARKET STRUCTURE")
showDashboard = input(true, "Enable", group = "TREND DASHBOARD")
tableTextColor = input(color.white, "Text", group = "TREND DASHBOARD")
tableBgColor = input(#13172232, "Background", group = "TREND DASHBOARD")
// Functions
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x[1]), t)
smoothrng = ta.ema(avrng, wper) * m
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
percWidth(len, perc) => (ta.highest(len) - ta.lowest(len)) * perc / 100
securityNoRep(sym, res, src) => request.security(sym, res, src, barmerge.gaps_off, barmerge.lookahead_on)
f_chartTfInMinutes() =>
float _resInMinutes = timeframe.multiplier * (
timeframe.isseconds ? 1 :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 60. * 24 :
timeframe.isweekly ? 60. * 24 * 7 :
timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
f_kc(src, len, sensitivity) =>
basis = ta.sma(src, len)
span = ta.atr(len)
[basis + span * sensitivity, basis - span * sensitivity]
wavetrend(src, chlLen, avgLen) =>
esa = ta.ema(src, chlLen)
d = ta.ema(math.abs(src - esa), chlLen)
ci = (src - esa) / (0.015 * d)
wt1 = ta.ema(ci, avgLen)
wt2 = ta.sma(wt1, 3)
[wt1, wt2]
// Get components
source = close
smrng1 = smoothrng(source, 27, 1.5)
smrng = (smrng1)
filt = rngfilt(source, smrng)
up = 0.0, up := filt > filt[1] ? nz(up[1]) + 1 : filt < filt[1] ? 0 : nz(up[1])
dn = 0.0, dn := filt < filt[1] ? nz(dn[1]) + 1 : filt > filt[1] ? 0 : nz(dn[1])
bullCond = bool(na), bullCond := source > filt and source > source[1] and up > 0 or source > filt and source < source[1] and up > 0
bearCond = bool(na), bearCond := source < filt and source < source[1] and dn > 0 or source < filt and source > source[1] and dn > 0
lastCond = 0, lastCond := bullCond ? 1 : bearCond ? -1 : lastCond[1]
bull = bullCond and lastCond[1] == -1
bear = bearCond and lastCond[1] == 1
countBull = ta.barssince(bull)
countBear = ta.barssince(bear)
trigger = nz(countBull, bar_index) < nz(countBear, bar_index) ? 1 : 0
ribbon1 = ta.ema(hlc3, 8)
ribbon2 = ta.ema(hlc3, 13)
rsi = ta.rsi(hlc3, 21)
rsiOb = rsi > 70 and rsi > ta.ema(rsi, 13)
rsiOs = rsi < 30 and rsi < ta.ema(rsi, 13)
ema1 = ta.ema(hlc3, 21)
ema2 = ta.ema(hlc3, 34)
ema3 = ta.ema(hlc3, 55)
ema = ta.ema(hlc3, 21)
emaBull = close > ema
[diplus, diminus, adx] = ta.dmi(21, 13)
adxstrong= adx > 21
equal_tf(res) => str.tonumber(res) == f_chartTfInMinutes() and not timeframe.isseconds
higher_tf(res) => str.tonumber(res) > f_chartTfInMinutes() or timeframe.isseconds
too_small_tf(res) => (timeframe.isweekly and res=="1") or (timeframe.ismonthly and str.tonumber(res) < 10)
securityNoRep1(sym, res, src) =>
bool bull_ = na
bull_ := equal_tf(res) ? src : bull_
bull_ := higher_tf(res) ? request.security(sym, res, src, barmerge.gaps_off, barmerge.lookahead_on) : bull_
bull_array = request.security_lower_tf(syminfo.tickerid, higher_tf(res) ? str.tostring(f_chartTfInMinutes()) + (timeframe.isseconds ? "S" : "") : too_small_tf(res) ? (timeframe.isweekly ? "3" : "10") : res, src)
if array.size(bull_array) > 1 and not equal_tf(res) and not higher_tf(res)
bull_ := array.pop(bull_array)
array.clear(bull_array)
bull_
TF5Bull = securityNoRep1(syminfo.tickerid, "5" , emaBull)
TF15Bull = securityNoRep1(syminfo.tickerid, "15" , emaBull)
TF30Bull = securityNoRep1(syminfo.tickerid, "30" , emaBull)
TF60Bull = securityNoRep1(syminfo.tickerid, "60" , emaBull)
TF240Bull = securityNoRep1(syminfo.tickerid, "240" , emaBull)
TFDBull = securityNoRep1(syminfo.tickerid, "1440", emaBull)
TF5Strong = securityNoRep1(syminfo.tickerid, "5" , adxstrong)
TF15Strong = securityNoRep1(syminfo.tickerid, "15" , adxstrong)
TF30Strong = securityNoRep1(syminfo.tickerid, "30" , adxstrong)
TF60Strong = securityNoRep1(syminfo.tickerid, "60" , adxstrong)
TF240Strong = securityNoRep1(syminfo.tickerid, "240" , adxstrong)
TFDStrong = securityNoRep1(syminfo.tickerid, "1440", adxstrong)
[upperKC1, lowerKC1] = f_kc(close, 55, 3)
[upperKC2, lowerKC2] = f_kc(close, 55, 4)
[upperKC3, lowerKC3] = f_kc(close, 55, 5)
[upperKC4, lowerKC4] = f_kc(close, 55, 6)
[wt1, wt2] = wavetrend(hlc3, 13, 21)
// Colors
cyan = #00dbff, cyan30 = color.new(cyan, 70)
pink = #e91e63, pink30 = color.new(pink, 70)
// Plot
plotshape(showReversal and ta.crossover(wt1, wt2) and wt2 <= -55, "Reversal Buy" , shape.labelup, location.belowbar, color = colorBuy, size=size.small)
plotshape(showReversal and ta.crossunder(wt1, wt2) and wt2 >= 55, "Reversal Sell", shape.labeldown, location.abovebar, color = colorSell, size=size.small)
plotshape(showReversal and rsiOs, "Oversold" , shape.diamond, location.belowbar, color = colorOs, size=size.tiny)
plotshape(showReversal and rsiOb, "Overbought", shape.diamond, location.abovebar, color = colorOb, size=size.tiny)
plot(showEmas ? ema1 : na, "Moving Average 1", colorEma1, 2)
plot(showEmas ? ema2 : na, "Moving Average 2", colorEma2, 2)
plot(showEmas ? ema3 : na, "Moving Average 3", colorEma3, 2)
var dashboard_loc = position.top_right
var dashboard_size = size.small
var dashboard = showDashboard ? table.new(dashboard_loc, 3, 15, tableBgColor, #000000, 2, tableBgColor, 1) : na
dashboard_cell(column, row, txt, signal=false) => table.cell(dashboard, column, row, txt, 0, 0, signal ? #000000 : tableTextColor, text_size=dashboard_size)
dashboard_cell_bg(column, row, col) => table.cell_set_bgcolor(dashboard, column, row)
if barstate.islast and showDashboard
dashboard_cell(0, 0, "Timeframe")
dashboard_cell(0, 1, "Chart")
dashboard_cell(0, 2, "5 min")
dashboard_cell(0, 3, "15 min")
dashboard_cell(0, 4, "30 min")
dashboard_cell(0, 5, "1H")
dashboard_cell(0, 6, "4H")
dashboard_cell(0, 7, "Daily")
dashboard_cell(1, 0, "Bias")
dashboard_cell(1, 1, emaBull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 1, emaBull)
dashboard_cell(1, 2, TF5Bull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 2, TF5Bull)
dashboard_cell(1, 3, TF15Bull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 3, TF15Bull)
dashboard_cell(1, 4, TF30Bull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 4, TF30Bull)
dashboard_cell(1, 5, TF60Bull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 5, TF60Bull)
dashboard_cell(1, 6, TF240Bull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 6, TF240Bull)
dashboard_cell(1, 7, TFDBull ? "🟢" : "🔴", true), dashboard_cell_bg(1, 7, TFDBull)
dashboard_cell(2, 0, "Strength")
dashboard_cell(2, 1, adxstrong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 1, adxstrong)
dashboard_cell(2, 2, TF5Strong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 2, TF5Strong)
dashboard_cell(2, 3, TF15Strong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 3, TF15Strong)
dashboard_cell(2, 4, TF30Strong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 4, TF30Strong)
dashboard_cell(2, 5, TF60Strong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 5, TF60Strong)
dashboard_cell(2, 6, TF240Strong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 6, TF240Strong)
dashboard_cell(2, 7, TFDStrong ? "🚀🚀" : "🚀", true), dashboard_cell_bg(2, 7, TFDStrong)
plot(showRevBands ? upperKC1 : na, "Upper Reversal Band 1", colorupperband)
plot(showRevBands ? upperKC2 : na, "Upper Reversal Band 2", colorupperband)
plot(showRevBands ? upperKC3 : na, "Upper Reversal Band 3", colorupperband)
plot(showRevBands ? upperKC4 : na, "Upper Reversal Band 4", colorupperband)
plot(showRevBands ? lowerKC1 : na, "Lower Reversal Band 1", colorlowerband)
plot(showRevBands ? lowerKC2 : na, "Lower Reversal Band 2", colorlowerband)
plot(showRevBands ? lowerKC3 : na, "Lower Reversal Band 3", colorlowerband)
plot(showRevBands ? lowerKC4 : na, "Lower Reversal Band 4", colorlowerband)
fill(plot(showRibbon ? ribbon1 : na, "", na, editable=false), plot(showRibbon ? ribbon2 : na, "", na, editable=false), ribbon1 > ribbon2 ? uptrend : downtrend)
// Alerts
alert01 = ta.crossover(wt1, wt2) and wt2 <= -55
alert02 = ta.crossunder(wt1, wt2) and wt2 >= 55
alerts(sym) =>
if alert01 or alert02
alert_text = alert01 ? "Buy Signal" : alert02 ? "Sell Signal" : "Buy Signal , Sell Signal"
alert(alert_text, alert.freq_once_per_bar_close)
alerts(syminfo.tickerid)
alertcondition(alert01, "Buy Alert", "Buy Signal, TimeFrame={{interval}}")
alertcondition(alert02, "Sell Alert", "Sell Signal, TimeFrame={{interval}}")
//////// MTF SUPPORT & RESISTANCE ////////
group = "MULTI-TIMEFRAME S/R"
showSR = input.bool(true, title = "", inline = "01", group=group)
timef = input.timeframe("", "", inline = "01", group=group)
levels = input.int(7 , "Levels", inline = "01", group = group)
linewidth = input.int(1, "Width", inline = "02", group = group) * 20
supportcolor = input.color(color.new(#00ddff, 75), "", inline = "02", group = group)
resistancecolor = input.color(color.new(#e91e62, 75), "", inline = "02", group = group)
labelon = input.string("On", "Label", ["On", "Off"], inline = "03", group = group)
labelsize = input.string("Default", "Size", ["Small", "Default", "Large"], inline = "03", group = group)
labelcol = input.color(#787b86, "", inline = "03", group = group)
labelloc = input.int(10, "Offset", inline = "04", group = group) + 30
showtimef = input.bool(true, "Show Timeframe", inline = "04", group = group)
showtprice = input.bool(true, "Show Price", inline = "04", group = group)
// get data on ticker based on chosen timeframe
src_c = request.security(syminfo.tickerid,timef,close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
src_o = request.security(syminfo.tickerid,timef,open, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
f_resInMinutes() =>
_resInMinutes = timeframe.multiplier * (timeframe.isseconds ? 1. / 60 : timeframe.isminutes ? 1. : timeframe.isdaily ? 60. * 24 : timeframe.isweekly ? 60. * 24 * 7 : timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
_resInMinutes
f_timefResInMinutes(_res) =>
request.security(syminfo.tickerid, _res, f_resInMinutes())
f_timefIsIntraday(_res) =>
[intraday, daily, weekly, monthly] = request.security(syminfo.tickerid, _res, [timeframe.isintraday, timeframe.isdaily, timeframe.isweekly, timeframe.ismonthly])
check = intraday ? "Intraday" : daily ? "Daily" : weekly ? "Weekly" : monthly ? "Monthly" : "Error"
check
mtimef_multiplier = int (f_timefResInMinutes(timef) / f_resInMinutes())
prd = 10
maxnumpp = 284
ChannelW = 10
min_strength = 2
prd := prd * mtimef_multiplier
float src1 = math.max(src_c, src_o)
float src2 = math.min(src_c, src_o)
float src3 = math.max(close, open)
float src4 = math.min(close, open)
float ph = ta.pivothigh(src1, prd, prd)
float pl = ta.pivotlow(src2, prd, prd)
Lstyle = line.style_solid
timef_res = f_timefIsIntraday(timef)
timef_text = str.tostring(timef)
if str.tostring(timef) == ""
timef_text := na(timeframe.multiplier / 60) ? timeframe.period : timeframe.multiplier < 60 ? timeframe.period + " M |" : str.tostring(timeframe.multiplier / 60) + " H |"
else if timef_res == "Intraday"
timef_text := na(str.tonumber(timef) / 60) ? str.tostring(timef) : str.tonumber(timef) < 60 ? str.tostring(timef) + " M |" : str.tostring(str.tonumber(timef) / 60) + " H |"
else
timef_text := str.tostring(timef)
//calculate maximum S/R channel zone width
prdhighest = request.security(syminfo.tickerid, timef, ta.highest(300))
prdlowest = request.security(syminfo.tickerid, timef, ta.lowest(300))
cwidth = (prdhighest - prdlowest) * ChannelW / 100
var pivotvals = array.new_float(0)
if ph or pl
array.unshift(pivotvals, ph ? ph : pl)
if array.size(pivotvals) > maxnumpp // limit the array size
array.pop(pivotvals)
get_sr_vals(ind) =>
float lo = array.get(pivotvals, ind)
float hi = lo
int numpp = 0
for y = 0 to array.size(pivotvals) - 1 by 1
float cpp = array.get(pivotvals, y)
float wdth = cpp <= lo ? hi - cpp : cpp - lo
if wdth <= cwidth // fits the max channel width?
lo := cpp <= lo ? cpp : lo
hi := cpp > lo ? cpp : hi
numpp += 1
numpp
[hi, lo, numpp]
var sr_up_level = array.new_float(0)
var sr_dn_level = array.new_float(0)
sr_strength = array.new_float(0)
find_loc(strength) =>
ret = array.size(sr_strength)
for i = ret > 0 ? array.size(sr_strength) - 1 : na to 0 by 1
if strength <= array.get(sr_strength, i)
break
ret := i
ret
ret
check_sr(hi, lo, strength) =>
ret = true
for i = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
//included?
if array.get(sr_up_level, i) >= lo and array.get(sr_up_level, i) <= hi or array.get(sr_dn_level, i) >= lo and array.get(sr_dn_level, i) <= hi
if strength >= array.get(sr_strength, i)
array.remove(sr_strength, i)
array.remove(sr_up_level, i)
array.remove(sr_dn_level, i)
ret
else
ret := false
ret
break
ret
var sr_lines = array.new_line(11, na)
var sr_labels = array.new_label(11, na)
var timef_labels = array.new_label(11, na)
if ph or pl
//because of new calculation, remove old S/R levels
array.clear(sr_up_level)
array.clear(sr_dn_level)
array.clear(sr_strength)
//find S/R zones
for x = 0 to array.size(pivotvals) - 1 by 1
[hi, lo, strength] = get_sr_vals(x)
if check_sr(hi, lo, strength)
loc = find_loc(strength)
// if strength is in first levels sr then insert it to the arrays
if loc < levels and strength >= min_strength
array.insert(sr_strength, loc, strength)
array.insert(sr_up_level, loc, hi)
array.insert(sr_dn_level, loc, lo)
// keep size of the arrays = 5
if array.size(sr_strength) > levels
array.pop(sr_strength)
array.pop(sr_up_level)
array.pop(sr_dn_level)
for x = 1 to 10 by 1
line.delete(array.get(sr_lines, x))
label.delete(array.get(sr_labels, x))
label.delete(array.get(timef_labels, x))
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
if showSR
array.set(sr_lines, x + 1, line.new(x1=bar_index, y1=mid, x2=bar_index - 1, y2=mid, extend=extend.both, color=mid >= close ? resistancecolor : supportcolor, style=Lstyle, width=linewidth))
if labelon == "On"
size = labelsize == "Small" ? size.small : labelsize == "Default" ? size.normal : size.large
array.set(sr_labels, x + 1, label.new(x=bar_index + labelloc, y=mid, text=(showtimef ? timef_text : na) + (showtprice ? (" " + str.tostring(mid)) : na), color=mid >= close ? #ff525200 : #00e67700, textcolor=labelcol,
size = size, style=label.style_label_left))
f_crossed_over() =>
ret = false
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
if close[1] <= mid and close > mid
ret := true
ret
ret
f_crossed_under() =>
ret = false
for x = 0 to array.size(sr_up_level) > 0 ? array.size(sr_up_level) - 1 : na by 1
float mid = math.round_to_mintick((array.get(sr_up_level, x) + array.get(sr_dn_level, x)) / 2)
if close[1] >= mid and close < mid
ret := true
ret
ret
alertcondition(f_crossed_over(), title= "Price Breaks Resistance", message = "Price Breaks Resistance, TimeFrame={{interval}}")
alertcondition(f_crossed_under(), title="Price Loses Support", message="Price Loses Support, TimeFrame={{interval}}")
//////// GANN ONE BAR SWING ////////
styleGann = line.style_solid
var arrayXGann = array.new_int(5,time)
var arrayYGann = array.new_float(5,close)
var arrayLineGann = array.new_line()
int drawLineGann = 0
_high = request.security(syminfo.tickerid,"",high,lookahead=barmerge.lookahead_on)
_low = request.security(syminfo.tickerid,"",low,lookahead=barmerge.lookahead_on)
_close = request.security(syminfo.tickerid,"",close,lookahead=barmerge.lookahead_on)
_open = request.security(syminfo.tickerid,"",open,lookahead=barmerge.lookahead_on)
highPrev = _high
lowPrev = _low
// drawLineGann
drawLineGann := 0
if(_high[0] > highPrev[1] and _low[0] > lowPrev[1])
if(array.get(arrayYGann,0) > array.get(arrayYGann,1))
if(_high[0] > array.get(arrayYGann,0))
if(_high[0] <= high)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _high[0])
drawLineGann := 2
else
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_high[0])
drawLineGann := 1
else if(_high[0] < highPrev[1] and _low[0] < lowPrev[1])
if(array.get(arrayYGann,0) > array.get(arrayYGann,1))
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_low[0])
drawLineGann := 1
else
if(_low[0] < array.get(arrayYGann,0))
if(_low[0] >= low)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _low[0])
drawLineGann := 2
else if((_high[0] >= highPrev[1] and _low[0] < lowPrev[1]) or (_high[0] > highPrev[1] and _low[0] <= lowPrev[1]))
if(array.get(arrayYGann,0) > array.get(arrayYGann,1))
if(_high[0] >= array.get(arrayYGann,0) and array.get(arrayYGann,1) <= _low[0])
if(_high[0] <= high)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _high[0])
drawLineGann := 2
else if(_high[0] >= array.get(arrayYGann,0) and array.get(arrayYGann,1) >= _low[0])
if(_close < _open)
if(_high[0] <= high)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _high[0])
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_low[0])
drawLineGann := 3
else
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_low[0])
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_high[0])
drawLineGann := 4
else if(array.get(arrayYGann,0) < array.get(arrayYGann,1))
if(_low[0] <= array.get(arrayYGann,0) and _high[0] <= array.get(arrayYGann,1))
if(_low[0] >= low)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _low[0])
drawLineGann := 2
else if(_low[0] <= array.get(arrayYGann,0) and _high[0] >= array.get(arrayYGann,1))
if(_close > _open)
if(_low[0] >= low)
array.set(arrayXGann, 0, time)
array.set(arrayYGann, 0, _low[0])
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_high[0])
drawLineGann := 3
else
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_high[0])
array.unshift(arrayXGann,time)
array.unshift(arrayYGann,_low[0])
drawLineGann := 4
else
if(array.get(arrayYGann,0) >= low)
array.set(arrayXGann, 0, time)
drawLineGann := 2
if(showGann and timeframe.in_seconds())
if(drawLineGann == 2)
if(array.size(arrayLineGann) >0)
line.set_xy2(array.get(arrayLineGann,0),array.get(arrayXGann,0),array.get(arrayYGann,0))
else
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,1),array.get(arrayYGann,1),array.get(arrayXGann,0),array.get(arrayYGann,0), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
else if(drawLineGann == 1)
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,1),array.get(arrayYGann,1),array.get(arrayXGann,0),array.get(arrayYGann,0), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
else if(drawLineGann == 3)
if(array.size(arrayLineGann) >0)
line.set_xy2(array.get(arrayLineGann,0),array.get(arrayXGann,1),array.get(arrayYGann,1))
else
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,2),array.get(arrayYGann,2),array.get(arrayXGann,1),array.get(arrayYGann,1), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,1),array.get(arrayYGann,1),array.get(arrayXGann,0),array.get(arrayYGann,0), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
else if(drawLineGann == 4)
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,2),array.get(arrayYGann,2),array.get(arrayXGann,1),array.get(arrayYGann,1), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
array.unshift(arrayLineGann,line.new(array.get(arrayXGann,1),array.get(arrayYGann,1),array.get(arrayXGann,0),array.get(arrayYGann,0), color = colorGann,xloc = xloc.bar_time,width = 1,style=line.style_solid))
//////// AUTO GOLDEN POCKET ////////
// ] —————— Vars —————— [
var fib0500 = close
var fib0618 = close
var fib0650 = close
// ] —————— Find Dev Pivots —————— [
getMultiTfPivots()=>
float ab = ta.pivothigh(2, 2)
float cd = ta.pivotlow(2, 2)
phBIndexS = ab ? time[2] : na
plBIndexS = cd ? time[2] : na
[ab, phBIndexS, cd, plBIndexS]
// get if there if Pivot High/low and their start/end times
[ab, phBIndexS, cd, plBIndexS] = request.security(syminfo.tickerid, timeframe, getMultiTfPivots(), lookahead = barmerge.lookahead_on)
// ] —————— Fibs Handles —————— [
// Get last highs/lows.
pivothigh = na(ab[1]) and ab ? ab : na
pivotlow = na(cd[1]) and cd ? cd : na
var isHighLast = true
var curPivotP = 0.
var lastPivotP = 0.
var curPivotBi = 0
var lastPivotBi = 0
// Special case: where high & low detected at the same time.
if not na(pivothigh) and not na(pivotlow)
lastPivotP := isHighLast ? cd : ab
curPivotP := isHighLast ? ab : cd
lastPivotBi := isHighLast ? plBIndexS : phBIndexS
curPivotBi := isHighLast ? phBIndexS : plBIndexS
// All cases
else
isHighLast := not na(pivothigh) ? true : not na(pivotlow) ? false : isHighLast
lastPivotP := not na(pivothigh) and not isHighLast[1] or not na(pivotlow) and isHighLast[1] ? curPivotP : lastPivotP
curPivotP := not na(pivothigh) ? ab : not na(pivotlow) ? cd : curPivotP
lastPivotBi := not na(pivothigh) and not isHighLast[1] or not na(pivotlow) and isHighLast[1] ? curPivotBi : lastPivotBi
curPivotBi := not na(pivothigh) ? phBIndexS : not na(pivotlow) ? plBIndexS : curPivotBi
// Logic fibo direction.
fiboDirUp = isHighLast
// Last Update Barindex.
var barLastUpdate = 0
barLastUpdate := lastPivotBi
// Calculate fibs levels.
rangeD = isHighLast ? curPivotP - lastPivotP : lastPivotP - curPivotP
fib0500 := fiboDirUp ? curPivotP - 0.5 * rangeD : curPivotP + 0.5 * rangeD
fib0618 := fiboDirUp ? curPivotP - 0.618 * rangeD : curPivotP + 0.618 * rangeD
fib0650 := fiboDirUp ? curPivotP - 0.650 * rangeD : curPivotP + 0.650 * rangeD
// ] —————— Plot —————— [
var fib0500Line = line.new(0, low, bar_index, high)
var fib0500Label = label.new(bar_index, low, text="Init")
var fib0618Line = line.new(0, low, bar_index, high)
var fib0618Label = label.new(bar_index, low, text="Init")
var fib0650Line = line.new(0, low, bar_index, high)
var fib0650Label = label.new(bar_index, low, text="Init")
labelOffset = 3
if autofib
line.delete(fib0500Line)
label.delete(fib0500Label)
fib0500Line := line.new(barLastUpdate, fib0500, time, fib0500, xloc=xloc.bar_time, color=colorAll, width=1)
fib0500Label := label.new(x=bar_index + labelOffset, y = fib0500, xloc=xloc.bar_index, text=str.tostring(0.5), style=label.style_none, size=size.small, textcolor=colorAll, textalign=text.align_center)
if autofib
line.delete(fib0618Line)
label.delete(fib0618Label)
fib0618Line := line.new(barLastUpdate, fib0618, time, fib0618, xloc=xloc.bar_time, color=colorAll, width=1)
fib0618Label := label.new(x=bar_index + labelOffset, y = fib0618, xloc=xloc.bar_index, text=str.tostring(0.618), style=label.style_none, size=size.small, textcolor=colorAll, textalign=text.align_center)
if autofib
line.delete(fib0650Line)
label.delete(fib0650Label)
fib0650Line := line.new(barLastUpdate, fib0650, time, fib0650, xloc=xloc.bar_time, color=colorAll, width=1)
fib0650Label := label.new(x=bar_index + labelOffset, y = fib0650, xloc=xloc.bar_index, text=str.tostring(0.650), style=label.style_none, size=size.small, textcolor=colorAll, textalign=text.align_center)
//////// VOLUME PROFILE ////////
// VARIABLES //
float vp_Vmax = 0.0
int vp_VmaxId = 0
int vp_N_BARS = 377
var int vp_first = time
vp_a_P = array.new_float(vp_N_BARS + 1, 0.0)
vp_a_V = array.new_float(vp_N_BARS, 0.0)
vp_a_D = array.new_float(vp_N_BARS, 0.0)
vp_a_W = array.new_int(vp_N_BARS, 0)
//////// CALCULATIONS ////////
float vp_HH = ta.highest(high, 233)
float vp_LL = ta.lowest(low, 233)
if barstate.islast
float vp_HL = (vp_HH - vp_LL) / vp_N_BARS
for j = 1 to vp_N_BARS + 1 by 1
array.set(vp_a_P, j - 1, vp_LL + vp_HL * j)
for i = 0 to 233 - 1 by 1
int Dc = 0
array.fill(vp_a_D, 0.0)
for j = 0 to vp_N_BARS - 1 by 1
float Pj = array.get(vp_a_P, j)
if low[i] < Pj and high[i] > Pj
float Dj = array.get(vp_a_D, j)
float dDj = Dj + nz(volume[i])
array.set(vp_a_D, j, dDj)
Dc += 1
Dc
for j = 0 to vp_N_BARS - 1 by 1
float Vj = array.get(vp_a_V, j)
float Dj = array.get(vp_a_D, j)
float dVj = Vj + (Dc > 0 ? Dj / Dc : 0.0)
array.set(vp_a_V, j, dVj)
vp_Vmax := array.max(vp_a_V)
vp_VmaxId := array.indexof(vp_a_V, vp_Vmax)
for j = 0 to vp_N_BARS - 1 by 1
float Vj = array.get(vp_a_V, j)
int Aj = math.round(30 * Vj / vp_Vmax)
array.set(vp_a_W, j, Aj)
// PLOTTING //
if showVP and barstate.isfirst
vp_first := time
vp_first
vp_change = ta.change(time)
vp_x_loc = timenow + math.round(vp_change * 60)
f_setup_bar(n) =>
x1 = vp_VmaxId == n ? math.max(time[233], vp_first) : timenow + math.round(vp_change * (60 - array.get(vp_a_W, n)))
ys = array.get(vp_a_P, n)
line.new(x1=x1, y1=ys, x2=vp_x_loc, y2=ys, xloc=xloc.bar_time, extend=extend.none, color=vp_VmaxId == n ? vp_poc_color : vp_bar_color, style=line.style_solid, width=1)
if showVP and barstate.islast
for i = 0 to vp_N_BARS - 1 by 1
f_setup_bar(i)
////////SMART MONEY CONCEPTS////////
//----------------------------------------}
//Order Blocks
//----------------------------------------{
v_buy = #00dbff4d
v_sell = #e91e634d
timeframe1=' : '
show_iob = 'All'=='All' or 'All'=='Internal'
show_ob = 'All'=='All' or 'All'=='External'
ob_showlast = 5
iob_showlast = 5
styleSMC = 'Colored'
v_lookback= 10
ob_loockback=10
timediff=(time[1]-time[101])/100
//----------------------------------------}
//Liquidity Levels
//----------------------------------------{
_highLineStyleHTF = "Solid"
highLineStyleHTF = _highLineStyleHTF=="Solid" ? line.style_solid : _highLineStyleHTF=="Dashed" ? line.style_dashed : line.style_dotted
box_width = 2.5
lineWidthHTF=2
highBoxBorderColorHTF = color.new(highLineColorHTF,90)
lowBoxBorderColorHTF = color.new(lowLineColorHTF,90)
displayStyle_liq = "Boxes"
//----------------------------------------}
//Fair Value Gaps (FVG)
//----------------------------------------{
i_bullishfvgcolor = color.new(color.green,100)
i_bearishfvgcolor = color.new(color.green,90)
i_fillByMid = true
i_deleteonfill = true
i_textColor = color.white
i_mtf = "HTF"
i_tfos = 10
i_mtfos = 50
//----------------------------------------}
//BOS and ChoCH
//----------------------------------------{
// Constants
color CLEAR = color.rgb(0,0,0,100)
// Inputs
swingSize = 8
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
color transparent = #ffffff00
length = 50
is_newbar(res) =>
t = time(res)
not na(t) and (na(t[1]) or t > t[1])
Show_MS(x, y, txt, css, dashed, down, lbl_size)=>
label.new(int(math.avg(x, bar_index)), y, txt, color = transparent, textcolor = css, style = down ? label.style_label_down : label.style_label_up, size = lbl_size)
line.new(x, y, bar_index, y, color = css, style = dashed ? line.style_dashed : line.style_solid)
f_barssince(_cond, _count) =>
_barssince = bar_index - ta.valuewhen(_cond, bar_index, _count)
_barssince
//Swings detection/measurements
calculate_swing_points(length)=>
var prev = 0
prev := high[length] > ta.highest(length) ? 0 : low[length] < ta.lowest(length) ? 1 : prev[1]
t = prev == 0 and prev[1] != 0 ? high[length] : 0
b = prev == 1 and prev[1] != 1 ? low[length] : 0
[t, b]
var t_MS = 0, var int_t_MS = 0
var internal_y_up = 0., var internal_x_up = 0, var internal_y_dn = 0., var internal_x_dn = 0
var y_up = 0., var x_up = 0 , var y_dn = 0., var x_dn = 0
var crossed_up = true, var crossed_down = true
var internal_up_broke = true, var internal_dn_broke = true
var up_trailing = high, var down_trailing = low
var up_trailing_x = 0, var down_trailing_x = 0
var high_text = '', var low_text = ''
bullish_OB_Break = false
bearish_OB_Break = false
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------- Market Structure
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bosConfType = 'Candle High'
ChoCH = true
// Functions
lineStyle(x) =>
switch x
'Solid' => line.style_solid
'Dashed' => line.style_dashed
'Dotted' => line.style_dotted
pivot_high_found = ta.pivothigh(high, 10, 10)
pivot_low_found = ta.pivotlow(low, 10, 10)
var float prevHigh_s = na,var float prevLow_s = na,var int prevHighIndex_s = na,var int prevLowIndex_s = na
bool higher_highs = false, bool lower_highs = false, bool higher_lows = false, bool lower_lows = false
var int prevSwing_s = 0
if not na(pivot_high_found)
if pivot_high_found >= prevHigh_s
higher_highs := true
prevSwing_s := 2
else
lower_highs := true
prevSwing_s := 1
prevHigh_s := pivot_high_found
prevHighIndex_s := bar_index - 10
if not na(pivot_low_found)
if pivot_low_found >= prevLow_s
higher_lows := true
prevSwing_s := -1
else
lower_lows := true
prevSwing_s := -2
prevLow_s := pivot_low_found
prevLowIndex_s := bar_index - 10
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------- Fair Value Gaps
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// ———————————————————— Global data {
//Using current bar data for HTF highs and lows instead of security to prevent future leaking
var htfH = open
var htfL = open
if close > htfH
htfH:= close
if close < htfL
htfL := close
//Security Data, used for HTF Bar Data reference
sClose = request.security(ticker.standard(syminfo.tickerid), i_tf, close[1], barmerge.gaps_off, barmerge.lookahead_on)
sHighP2 = request.security(ticker.standard(syminfo.tickerid), i_tf, high[2], barmerge.gaps_off, barmerge.lookahead_on)
sLowP2 = request.security(ticker.standard(syminfo.tickerid), i_tf, low[2], barmerge.gaps_off, barmerge.lookahead_on)
sOpen = request.security(ticker.standard(syminfo.tickerid), i_tf, open[1], barmerge.gaps_off, barmerge.lookahead_on)
sBar = request.security(ticker.standard(syminfo.tickerid), i_tf, bar_index, barmerge.gaps_off, barmerge.lookahead_on)
//var keyword can be used to hold data in memory, with pinescript all data is lost including variables unless the var keyword is used to preserve this data
var bullishgapholder = array.new_box(0)
var bearishgapholder = array.new_box(0)
var bullishgapholder_fill = array.new_box(0)
var bearishgapholder_fill = array.new_box(0)
var bullish_high_holder = array.new_line(0)
var bearish_high_holder = array.new_line(0)
var bullish_low_holder = array.new_line(0)
var bearish_low_holder = array.new_line(0)
var bullishmidholder = array.new_line(0)
var bearishmidholder = array.new_line(0)
var bullishlabelholder = array.new_label(0)
var bearishlabelholder = array.new_label(0)
var transparentcolor = color.new(color.white,100)
var fvg_apper=false
var fvg_break=false
fvg_apper:=false
fvg_break:=false
// ———————————————————— Functions {
//function paramaters best declared with '_' this helps defer from variables in the function scope declaration and elsewhere e.g. close => _close
create_fvg_func(_upperlimit,_lowerlimit,_midlimit,_bar,_boxholder,_boxholder_fill,_midholder,_highholder,_lowholder,_labelholder,_boxcolor,_mtfboxcolor, _htf)=>
timeholder = str.tostring(i_tf)
offset = i_mtfos
boxbgcolor = _mtfboxcolor
bg_color = color.new(_mtfboxcolor,90)
if _htf == false
timeholder := str.tostring(timeframe.period)
offset := i_tfos
boxbgcolor := _boxcolor
array.push(_boxholder,box.new(_bar,_upperlimit,_bar+(timediff)*20,_lowerlimit,border_color=true? bg_color : na,bgcolor = true? bg_color : na, extend = false ? extend.right:extend.none,xloc = xloc.bar_time,text='',text_color=#787b86,text_halign=text.align_right,text_size=size.small))
array.push(_boxholder_fill,box.new(_bar,_upperlimit,_bar+(timediff)*20,_lowerlimit,border_color=true? bg_color : na ,bgcolor = true? bg_color : na, extend = false ? extend.right:extend.none,xloc = xloc.bar_time))
array.push(_midholder,line.new(_bar,(_lowerlimit+_upperlimit)/2.0,_bar+(timediff)*20,_midlimit,color = #787b86, extend = false ? extend.right:extend.none,style=line.style_solid,width=1,xloc = xloc.bar_time))
array.push(_lowholder,line.new(_bar,_lowerlimit,_bar+(timediff)*20,_lowerlimit,color = i_fillByMid?boxbgcolor:na, extend = false ? extend.right:extend.none,width=1,xloc = xloc.bar_time))
array.push(_highholder,line.new(_bar,_upperlimit,_bar+(timediff)*20,_upperlimit,color = i_fillByMid?boxbgcolor:na, extend = false ? extend.right:extend.none,width=1,xloc = xloc.bar_time))
//checks for gap between current candle and 2 previous candle e.g. low of current candle and high of the candle before last, this is the fair value gap.
check_fvg_func(smcclose,smchigh,_highp2,smclow,_lowp2,smcopen,_bar,_htf)=>
gap=0
thold_ = (ta.highest(smchigh,300) - ta.lowest(smclow,300)) * math.max(1.5, 0.1) / 100.
if smcopen > smcclose // red
if _lowp2>smchigh
if not(true) or math.abs(_lowp2 -smchigh) > thold_
upperlimit = smchigh
lowerlimit = _lowp2
midlimit = lowerlimit + ((upperlimit - lowerlimit) / 2.)
gap:=1
create_fvg_func(upperlimit,lowerlimit,midlimit,_bar,bullishgapholder,bullishgapholder_fill,bullishmidholder,bullish_high_holder,bullish_low_holder,bullishlabelholder,i_bullishfvgcolor,i_mtfbullishfvgcolor,_htf)
else
if smclow>_highp2
if not(true) or math.abs(smclow - _highp2) > thold_
upperlimit = smclow
lowerlimit = _highp2
midlimit = lowerlimit + ((upperlimit - lowerlimit) / 2.)
gap:=-1
create_fvg_func(upperlimit,lowerlimit,midlimit,_bar,bearishgapholder,bearishgapholder_fill,bearishmidholder,bearish_high_holder,bearish_low_holder,bearishlabelholder,i_bearishfvgcolor,i_mtfbearishfvgcolor,_htf)
gap
//Used to remove the gap from its relevant array as a result of it being filled.
delete_fvg_func(_currentgap,_currentgap_fill,_i,_boxholder,_boxholder_fill,_midholder,_highholder,_lowholder,_labelholder)=>
array.remove(_boxholder,_i)
array.remove(_boxholder_fill,_i)
currentmid=array.get(_midholder,_i)
currenthigh=array.get(_highholder,_i)
currentlow=array.get(_lowholder,_i)
array.remove(_midholder,_i)
array.remove(_highholder,_i)
array.remove(_lowholder,_i)
if i_deleteonfill
line.delete(currentmid)
line.delete(currenthigh)
line.delete(currentlow)
else
line.set_extend(currentmid, extend.none)
line.set_x2(currentmid,time)
line.set_extend(currenthigh, extend.none)
line.set_x2(currenthigh,time)
line.set_extend(currentlow, extend.none)
line.set_x2(currentlow,time)
if i_deleteonfill
box.delete(_currentgap)
box.delete(_currentgap_fill)
else
box.set_extend(_currentgap,extend.none)
box.set_right(_currentgap,time)
//checks if gap has been filled either by 0.5 fill (i_fillByMid) or SHRINKS the gap to reflect the true value gap left.
validate_fvg_func(smchigh,smclow)=>
fvg_removed=0
if array.size(bullishgapholder) > 0
for i = array.size(bullishgapholder)-1 to 0
currentgap_fill = array.get(bullishgapholder_fill,i)
currentgap = array.get(bullishgapholder,i)
cmid = array.get(bullishmidholder,i)
chigh = array.get(bullish_high_holder,i)
clow = array.get(bullish_low_holder,i)
line.set_x2(cmid,timenow+(timediff)*20)
line.set_x2(chigh,timenow+(timediff)*20)
line.set_x2(clow,timenow+(timediff)*20)
box.set_right(currentgap_fill,timenow+(timediff)*20)
box.set_right(currentgap,timenow+(timediff)*20)
currentmid = array.get(bullishmidholder,i)
currenthigh = array.get(bullish_high_holder,i)
currentlow = array.get(bullish_low_holder,i)
currenttop = box.get_top(currentgap)
if high > currenttop
fvg_removed:=1
delete_fvg_func(currentgap,currentgap_fill,i,bullishgapholder,bullishgapholder_fill,bullishmidholder,bullish_high_holder,bullish_low_holder,bullishlabelholder)
if array.size(bearishgapholder) > 0
for i = array.size(bearishgapholder)-1 to 0
currentgap_fill = array.get(bearishgapholder_fill,i)
currentgap = array.get(bearishgapholder,i)
cmid = array.get(bearishmidholder,i)
chigh = array.get(bearish_high_holder,i)
clow = array.get(bearish_low_holder,i)
line.set_x2(cmid,timenow+(timediff)*20)
line.set_x2(chigh,timenow+(timediff)*20)
line.set_x2(clow,timenow+(timediff)*20)
box.set_right(currentgap_fill,timenow+(timediff)*20)
box.set_right(currentgap,timenow+(timediff)*20)
currenttop = box.get_top(currentgap)
currentmid = array.get(bearishmidholder,i)
currenthigh = array.get(bearish_high_holder,i)
currentlow = array.get(bearish_low_holder,i)
if low < currenttop
fvg_removed:=-1
delete_fvg_func(currentgap,currentgap_fill,i,bearishgapholder,bearishgapholder_fill,bearishmidholder,bearish_high_holder,bearish_low_holder,bearishlabelholder)
fvg_removed
// pine provided function to determine a new bar
if is_newbar(i_tf)
htfH := high
htfL := low
// }
fvg_gap=0
// User Input, allow MTF data calculations
if is_newbar(i_tf) and (i_mtf == "Current + HTF" or i_mtf == "HTF") and show_fvg and barstate.isconfirmed
fvg_gap:=check_fvg_func(sClose,htfH,sHighP2,htfL,sLowP2,sOpen,time[2],true)
alertcondition(fvg_gap==1,"Bullish FVG","Bullish FVG Found Ez-SMC")
alertcondition(fvg_gap==-1,"Bearish FVG","Bearish FVG Found Ez-SMC")
fvg_removed=validate_fvg_func(high,low)
alertcondition(fvg_removed==1,"Bullish FVG Break","Bullish FVG Broken Ez-SMC")
alertcondition(fvg_removed==-1,"Bearish FVG Break","Bearish FVG Broken Ez-SMC")
if array.size(bullishgapholder) > 4
d_box=array.shift(bullishgapholder)
box.delete(d_box)
if array.size(bullishgapholder_fill) > 4
d_box=array.shift(bullishgapholder_fill)
box.delete(d_box)
if array.size(bullishmidholder) > 4
d_line=array.shift(bullishmidholder)
line.delete(d_line)
if array.size(bullish_high_holder) > 4
d_line=array.shift(bullish_high_holder)
line.delete(d_line)
if array.size(bullish_low_holder) > 4
d_line=array.shift(bullish_low_holder)
line.delete(d_line)
if array.size(bearishgapholder) > 4
d_box_=array.shift(bearishgapholder)
box.delete(d_box_)
if array.size(bearishgapholder_fill) > 4
d_box_=array.shift(bearishgapholder_fill)
box.delete(d_box_)
if array.size(bearishmidholder) > 4
d_line_=array.shift(bearishmidholder)
line.delete(d_line_)
if array.size(bearish_high_holder) > 4
d_line_=array.shift(bearish_high_holder)
line.delete(d_line_)
if array.size(bearish_low_holder) > 4
d_line_=array.shift(bearish_low_holder)