Files
QuanTAlib/lib/channels/sdchannel/sdchannel.pine
T

61 lines
2.6 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Standard Deviation Channel (SDCHANNEL)", "SDCHANNEL", overlay=true)
//@function Calculates Standard Deviation Channel with lines N standard deviations above and below a linear regression line
//@param period Lookback period for regression and standard deviation calculation (period > 1)
//@param source Source series for analysis (usually close)
//@param multiplier Standard deviation multiplier for channel distance (multiplier > 0)
//@returns Tuple containing [upper_channel, regression_line, lower_channel]
//@optimized Uses linear regression with O(n) complexity per bar
sdchannel(simple int period, series float source = close, simple float multiplier = 2.0) =>
if period <= 1
runtime.error("Period must be > 1")
if multiplier <= 0.0
runtime.error("Multiplier must be > 0")
float sumX = 0.0
float sumY = 0.0
float sumXY = 0.0
float sumX2 = 0.0
for i = 0 to period - 1
float x = float(i)
float y = source[period - 1 - i]
sumX := sumX + x
sumY := sumY + y
sumXY := sumXY + x * y
sumX2 := sumX2 + x * x
float n = float(period)
float slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX)
float intercept = (sumY - slope * sumX) / n
float currentX = float(period - 1)
float regressionLine = slope * currentX + intercept
float sumSquaredResiduals = 0.0
for i = 0 to period - 1
float x = float(i)
float y = source[period - 1 - i]
float predicted = slope * x + intercept
float residual = y - predicted
sumSquaredResiduals := sumSquaredResiduals + residual * residual
float stdDev = math.sqrt(sumSquaredResiduals / n)
float upperChannel = regressionLine + multiplier * stdDev
float lowerChannel = regressionLine - multiplier * stdDev
[upperChannel, regressionLine, lowerChannel]
// ---------- Main loop ----------
// Inputs
i_period = input.int(20, "Period", minval=2)
i_source = input.source(close, "Source")
i_multiplier = input.float(2.0, "Standard Deviation Multiplier", minval=0.1, step=0.1)
// Calculation
[upperLine, midLine, lowerLine] = sdchannel(i_period, i_source, i_multiplier)
// Plot
p1 = plot(upperLine, "Upper Channel", color=color.yellow, linewidth=2)
p2 = plot(midLine, "Regression Line", color=color.yellow, linewidth=2)
p3 = plot(lowerLine, "Lower Channel", color=color.yellow, linewidth=2)
fill(p1, p2, color=color.new(color.red, 90), title="Upper Fill")
fill(p2, p3, color=color.new(color.green, 90), title="Lower Fill")