-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsqueeze.groovy
More file actions
135 lines (102 loc) · 6.11 KB
/
squeeze.groovy
File metadata and controls
135 lines (102 loc) · 6.11 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
// This code is adapted from Squeeze Momentum Indicator [LazyBear] found at https://www.tradingview.com/v/nqQ1DT5a/
//@version=6
indicator(shorttitle = 'SQZMOM', title = 'Squeeze Momentum Indicator [By Tashfeen as an update to LazyBear]', overlay = false)
length = input.int(20, title = 'BB Length')
mult = input.float(2.0, title = 'BB MultFactor')
lengthKC = input.int(20, title = 'KC Length')
multKC = input.float(1.5, title = 'KC MultFactor')
useTrueRange = input.bool(true, title = 'Use TrueRange (KC)')
showPriceLabels = input.bool(false, title = 'Show Price Labels for Inside Candle') // Default is false
// Options for inside candles
showInsideCandles = input.bool(false, title = 'Show Inside Candles')
showStackedEMALabel = input.bool(true, title='Show SIgnal when EMAs are stacked bullish 8 > 21 > 34 EMA')
//showGrayCross = input.bool(true, title = 'Show Inside Candle Only with Gray Cross')
// black is for building squeeze
//showBlackCrossInsideDay = input.bool(true, title = 'Show Inside Candle Only with Black Cross')
// gray is for squeezing
//showGrayCrossInsideDay = input.bool(true, title = 'Show Inside Candle Only with Gray Cross')
//showInsideDayWhileSqueeze = input.bool(false, title = 'Show only inside candles while long squeeze')
// Threshold for consecutive black crosses
threshold = 6
showThresholdLabel = input.bool(true, title = 'Show Label When Threshold is Reached')
// Calculate BB
source = close
basis = ta.sma(source, length)
dev = multKC * ta.stdev(source, length)
upperBB = basis + dev
lowerBB = basis - dev
// Calculate KC
ma = ta.sma(source, lengthKC)
kcRange = useTrueRange ? ta.tr : high - low // Renamed 'range' to 'kcRange'
rangema = ta.sma(kcRange, lengthKC)
upperKC = ma + rangema * multKC
lowerKC = ma - rangema * multKC
sqzOn = lowerBB > lowerKC and upperBB < upperKC
sqzOff = lowerBB < lowerKC and upperBB > upperKC
noSqz = not sqzOn and not sqzOff
val = ta.linreg(source - math.avg(math.avg(ta.highest(high, lengthKC), ta.lowest(low, lengthKC)), ta.sma(close, lengthKC)), lengthKC, 0)
// Inside candle condition (current candle within the range of the previous one)
insideCandle = high < high[1] and low > low[1]
// Track the last inside candle
var float lastInsideCandleIndex = na
if insideCandle
lastInsideCandleIndex := bar_index
lastInsideCandleIndex
bcolor = val > 0 ? val > nz(val[1]) ? color.lime : color.green : val < nz(val[1]) ? color.red : color.maroon
scolor = noSqz ? color.blue : sqzOn ? color.black : color.gray
plot(val, color = bcolor, style = plot.style_histogram, linewidth = 4)
plot(0, color = scolor, style = plot.style_cross, linewidth = 2)
adjustedY = val < 0 ? 3 : val
// Plot arrows for inside candles based on the selected cross color
if insideCandle and showInsideCandles
// Condition 1: Inside candle with a black cross -- getting ready for squeeze
//if scolor == color.black
label.new(bar_index, adjustedY, showPriceLabels and bar_index == lastInsideCandleIndex ? str.tostring(high, '#.##') + ' / ' + str.tostring(low, '#.##') : '', style = label.style_label_down, color = color.new(color.black, 0), textcolor = color.black)
// Condition 2: Inside candle with a gray cross -- actively squeezing
//if scolor == color.gray and showInsideDayWhileSqueeze and val > 0
// label.new(bar_index, adjustedY, showPriceLabels and bar_index == lastInsideCandleIndex ? str.tostring(high, '#.##') + ' / ' + str.tostring(low, '#.##') : '', style = label.style_label_down, color = color.new(#787b86a2, 0), textcolor = color.black)
//else if scolor == color.gray
// label.new(bar_index, adjustedY, showPriceLabels and bar_index == lastInsideCandleIndex ? str.tostring(high, '#.##') + ' / ' + str.tostring(low, '#.##') : '', style = label.style_label_down, color = color.new(#787b86a2, 0), textcolor = color.black)
// Add label when threshold for consecutive black crosses is reached
var int blackCrossCount = 0
if scolor == color.black
blackCrossCount := blackCrossCount + 1
blackCrossCount
else
blackCrossCount := 0
blackCrossCount
if blackCrossCount == threshold and showThresholdLabel
label.new(bar_index, val > 0 ? val + 0 : val, 'Threshold Reached: ' + str.tostring(threshold) + ' Black Crosses', style = val > 0 ? label.style_label_down : label.style_label_up, color = color.rgb(255, 82, 82, 61), textcolor = color.white)
// Calculate EMAs
ema8 = ta.ema(close, 8)
ema21 = ta.ema(close, 21)
ema34 = ta.ema(close, 34)
// Check for stacked EMAs (bullish condition)
stackedEMAs = ema8 > ema21 and ema21 > ema34
// Detect momentum shift from negative to positive
momentumShift = val > 0 and val[1] <= 0
// Signal when both conditions are met
signal = stackedEMAs and momentumShift
// Plot signal on the chart
//plotshape(signal, title = 'Bullish Signal', location = location.abovebar, color = color.green, style = shape.labeldown, text = '🔼')
// Add label at 'val' when stacked EMAs & momentum shift conditions are met
if signal and showStackedEMALabel
label.new(bar_index, val * -1, '🔥 Bullish', style = label.style_label_up, color = color.green, textcolor = color.white)
// Define the number of bars for the last 3 years (assuming daily candles)
barsBack = 756
// Find highest and lowest values in the last 3 years
highestVal = ta.highest(val, barsBack)
lowestVal = ta.lowest(val, barsBack)
// Create a table in the top-right corner
var table dataTable = table.new(position = position.top_right, columns = 2, rows = 3, bgcolor = color.blue, border_width = 1)
// Only update the table on the latest bar
if bar_index == ta.highest(bar_index, barsBack)
// Header row
table.cell(dataTable, 0, 0, "Metric", text_color=color.white, bgcolor=color.blue)
table.cell(dataTable, 1, 0, "Value", text_color=color.white, bgcolor=color.blue)
// 3-Year High row
table.cell(dataTable, 0, 1, "3Y High", text_color=color.white, bgcolor=color.green)
table.cell(dataTable, 1, 1, str.tostring(highestVal, "#.##"), text_color=color.white, bgcolor=color.green)
// 3-Year Low row
table.cell(dataTable, 0, 2, "3Y Low", text_color=color.white, bgcolor=color.red)
table.cell(dataTable, 1, 2, str.tostring(lowestVal, "#.##"), text_color=color.white, bgcolor=color.red)