-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstoch-x.pine
More file actions
127 lines (106 loc) · 6.42 KB
/
stoch-x.pine
File metadata and controls
127 lines (106 loc) · 6.42 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
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © realanthonyc https://www.tradingview.com/u/realanthonyc
//@version=6
// --------------------------------------------------------------------
// Stoch X: Stochastic with Divergence & Signals
// On Github: https://github.com/realanthonyc/Stoch-X
// v1.1.9
// --------------------------------------------------------------------
indicator(title="Stoch X: Stochastic with Divergence & Signals", shorttitle="Stoch X", format=format.price, precision=1, timeframe="", timeframe_gaps=true)
// === Inputs ===
// Colors
bearColor = color.new(color.red, 35)
bullColor = color.new(color.green, 35)
noneColor = color.new(color.white, 100)
// Settings
grpStoch = "Settings"
periodK = input.int(14, title="%K", minval=1, group=grpStoch)
smoothK = input.int(1, title="%K Smoothing", minval=1, group=grpStoch, tooltip = "To ensure optimal divergence detection, set it to 1.")
periodD = input.int(3, title="%D", minval=1, group=grpStoch)
valUpper = input.int(80, title="Upper Band Value", group=grpStoch)
valLower = input.int(20, title="Lower Band Value", group=grpStoch)
// Settings for Cross Signals
grpStochCross = "Settings for Cross Signals"
crossNote1 = "Cross signals occur when %K2 crosses %S outside the band."
crossNote2 = "Increase this value for smoother, slower signals; decrease it for higher sensitivity."
crossNote3 = "Less sensitive and more accurate signals for lower timeframes."
periodK2 = input.int(1, title="%K2", minval=1, group=grpStochCross, tooltip = crossNote1, display = display.data_window)
periodS = input.int(5, title="%S", minval=1, group=grpStochCross, tooltip = crossNote2, display = display.data_window)
periodK2_Low = input.int(2, title="%K2 for 30m or Below", minval=1, group=grpStochCross, tooltip = crossNote3, display = display.data_window)
periodS_Low = input.int(6, title="%S for 30m or Below", minval=1, group=grpStochCross, tooltip = crossNote3, display = display.data_window)
valCrossLevel = input.int(-10, title="Cross Signals Plot Level", group=grpStochCross, display = display.data_window)
// Divergence Settings
grpDiv = "Divergence Settings"
calculateDivergence = input.bool(true, title="Calculate Divergence", group=grpDiv, display = display.data_window, tooltip ="Based on %K")
lookbackRight = input.int(5, title="Pivot Lookback Right", group=grpDiv, display = display.data_window)
lookbackLeft = input.int(5, title="Pivot Lookback Left", group=grpDiv, display = display.data_window)
rangeUpper = input.int(60, title="Max Lookback Range", group=grpDiv, display = display.data_window)
rangeLower = input.int(5, title="Min Lookback Range", group=grpDiv, display = display.data_window)
// === Stochastic Calculation ===
k = ta.sma(ta.stoch(close, high, low, periodK), smoothK)
d = ta.sma(k, periodD)
// Dynamic Period Logic
// 30 minutes = 1800 seconds
// Logic handles Ticks/Range/Volume (na seconds) by defaulting to Regular (false on isLowTF)
currentSeconds = timeframe.in_seconds(timeframe.period)
isLowTF = not na(currentSeconds) and currentSeconds <= 1800
periodS_Dynamic = isLowTF ? periodS_Low : periodS
periodK2_Dynamic = isLowTF ? periodK2_Low : periodK2
s = ta.sma(k, periodS_Dynamic)
k2 = ta.sma(k, periodK2_Dynamic)
// === Plotting: Stochastic Lines ===
plot(k, title="%K", color=#2962FF)
plot(k2, title="%K2", color=color.new(#9C27B0, 30), display=display.none)
plot(d, title="%D", color=#FF6D00)
plot(s, title="%S", color=color.new(#018383, 30), display=display.none)
// Dynamic Band
h0 = hline(valUpper, "Upper Band", color=color.new(#27c5ff, 50), linestyle=hline.style_dotted, editable=false)
hline(50, "Middle Band", color=color.new(#787B86, 50))
h1 = hline(valLower, "Lower Band", color=color.new(#27c5ff, 50), linestyle=hline.style_dotted, editable=false)
fill(h0, h1, color=color.rgb(33, 150, 243, 95), title="Background")
// === Plotting: Cross Signals ===
// Use %K2 and %S for crossing logic
bullCross = ta.crossover(k2, s) and k2 < valLower
bearCross = ta.crossunder(k2, s) and k2 > valUpper
// Uses valCrossLevel for vertical positioning
plotshape(bearCross ? valCrossLevel : na, title="Bearish Cross", style=shape.xcross, location=location.absolute, color=bearColor, size=size.tiny)
plotshape(bullCross ? valCrossLevel : na, title="Bullish Cross", style=shape.xcross, location=location.absolute, color=bullColor, size=size.tiny)
// === Plotting: Divergence ===
_inRange(bool cond) =>
bars = ta.barssince(cond)
rangeLower <= bars and bars <= rangeUpper
plFound = false
phFound = false
bullCond = false
bearCond = false
// Source for pivots remains K (Standard Divergence)
srcLBR = k[lookbackRight]
if calculateDivergence
// Regular Bullish
// Osc: Higher Low
plFound := not na(ta.pivotlow(k, lookbackLeft, lookbackRight))
// Calculate range check separately to prevent short-circuiting of ta.barssince
bool rangeConditionBull = _inRange(plFound[1])
oscHL = srcLBR > ta.valuewhen(plFound, srcLBR, 1) and rangeConditionBull
// Price: Lower Low
lowLBR = low[lookbackRight]
priceLL = lowLBR < ta.valuewhen(plFound, lowLBR, 1)
bullCond := priceLL and oscHL and plFound
// Regular Bearish
// Osc: Lower High
phFound := not na(ta.pivothigh(k, lookbackLeft, lookbackRight))
// Calculate range check separately to prevent short-circuiting
bool rangeConditionBear = _inRange(phFound[1])
oscLH = srcLBR < ta.valuewhen(phFound, srcLBR, 1) and rangeConditionBear
// Price: Higher High
highLBR = high[lookbackRight]
priceHH = highLBR > ta.valuewhen(phFound, highLBR, 1)
bearCond := priceHH and oscLH and phFound
// Divergence Lines
plot(plFound ? srcLBR : na, offset = -lookbackRight, title = "Regular Bullish", linewidth = 1, color = (bullCond ? bullColor : noneColor), display = display.pane, editable = calculateDivergence)
plot(phFound ? srcLBR : na, offset = -lookbackRight, title = "Regular Bearish", linewidth = 1, color = (bearCond ? bearColor : noneColor), display = display.pane, editable = calculateDivergence)
// === Alerts ===
alertcondition(bullCond, title='Regular Bullish Divergence', message="Found a new Regular Bullish Divergence")
alertcondition(bearCond, title='Regular Bearish Divergence', message='Found a new Regular Bearish Divergence')
alertcondition(bullCross, title='Stoch Bullish Cross', message='Stoch Bullish Cross in Oversold Zone')
alertcondition(bearCross, title='Stoch Bearish Cross', message='Stoch Bearish Cross in Overbought Zone')