Files
QuanTAlib/lib/oscillators/stoch/stoch.pine
T
Miha Kralj 24e86d762a Add documentation links for various volatility indicators and channels
- Updated BBWN, BBWP, CCV, CV, CVI, EWMA, GKV, HLV, HV, Jvolty, JVOLTYN, MASSI, NATR, RSV, RV, RVI, TR, UI, VOV, VR, YZV indicators with documentation links.
- Added documentation links for Aberration, Acceleration Bands, Andrews' Pitchfork, Adaptive Price Zone, ATR Bands, Bollinger Bands, Center of Gravity, Donchian Channels, Decay Min-Max Channel, Detrended Synthetic Price, EACP, EBSW, HOMOD, Jurik Volatility Bands, Keltner Channel, MA Envelope, Min-Max Channel, Price Channel, Regression Channels, Standard Deviation Channel, Stoller Average Range Channel, Super Trend Bands, Ultimate Bands, Ultimate Channel, VWAP Bands, and VWAP with Standard Deviation Bands.
2026-02-18 11:55:48 -08:00

76 lines
2.9 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Stochastic Oscillator (STOCH)", "Stoch", overlay=false)
//@function Calculates the Stochastic Oscillator (%K and %D). %K = 100 * (close - lowest_low(kLength)) / (highest_high(kLength) - lowest_low(kLength)). %D = SMA(%K, dPeriod). Uses efficient deque implementation for min/max and buffer-based SMA.
//@param kLength `simple int` The lookback period for calculating highest high and lowest low.
//@param dPeriod `simple int` The smoothing period for the %D line (SMA of %K).
//@returns `[float, float]` A tuple containing the %K value and the %D value.
stoch(simple int kLength,simple int dPeriod)=>
if kLength<=0 or dPeriod<=0
runtime.error("Both periods must be positive")
var float kVal=0.0, var float dVal=0.0
var int dHead=0, var float dSum=0.0
var array<int>lowestDeque=array.new_int(0)
var array<float>lowestBuffer=array.new_float(kLength,na)
var array<int>highestDeque=array.new_int(0)
var array<float>highestBuffer=array.new_float(kLength,na)
var array<float>dBuffer=array.new_float(dPeriod,0.0)
int idx=bar_index%kLength
float lv=nz(low), float hv=nz(high)
array.set(lowestBuffer,idx,lv)
array.set(highestBuffer,idx,hv)
while array.size(lowestDeque)>0
if array.get(lowestDeque,0)<=bar_index-kLength
array.shift(lowestDeque)
else
break
while array.size(lowestDeque)>0
if array.get(lowestBuffer,array.get(lowestDeque,array.size(lowestDeque)-1)%kLength)>=lv
array.pop(lowestDeque)
else
break
array.push(lowestDeque,bar_index)
while array.size(highestDeque)>0
if array.get(highestDeque,0)<=bar_index-kLength
array.shift(highestDeque)
else
break
while array.size(highestDeque)>0
if array.get(highestBuffer,array.get(highestDeque,array.size(highestDeque)-1)%kLength)<=hv
array.pop(highestDeque)
else
break
array.push(highestDeque,bar_index)
int li=array.get(lowestDeque,0)
int hi=array.get(highestDeque,0)
float lowestLow=array.get(lowestBuffer,li%kLength)
float highestHigh=array.get(highestBuffer,hi%kLength)
float rnge=highestHigh-lowestLow
kVal:=rnge>0?100*(close-lowestLow)/rnge:0.0
if bar_index==0
dSum:=kVal*dPeriod
array.fill(dBuffer,kVal)
else
float oldVal=array.get(dBuffer,dHead)
dSum:=dSum-oldVal+kVal
array.set(dBuffer,dHead,kVal)
dHead:=(dHead+1)%dPeriod
dVal:=dSum/dPeriod
[kVal,dVal]
// ---------- Main loop ----------
// Inputs
kPeriod = input.int(14, "K Length", minval=1)
dPeriod = input.int(3, "D Smooth", minval=1)
// Calculation
[kValue, dValue] = stoch(kPeriod, dPeriod)
// Plot
plot(kValue, "Stochastic %K", color=color.green, linewidth=2)
plot(dValue, "Stochastic %D", color=color.red, linewidth=2)