//@version=5 indicator("Multi Kernel Regression [ChartPrime]", overlay = true, max_lines_count = 500, max_bars_back = 500, max_labels_count = 500) repaint = input.bool(true, "Repaint") kernel = input.string("Laplace", "Kernel Select", [ "Triangular" , "Gaussian" , "Epanechnikov" , "Logistic" , "Log Logistic" , "Cosine" , "Sinc" , "Laplace" , "Quartic" , "Parabolic" , "Exponential" , "Silverman" , "Cauchy" , "Tent" , "Wave" , "Power" , "Morters"]) bandwidth = input.int(14, 'Bandwidth', 1) source = input.source(close, 'Source') deviations = input.float(2.0, 'Deviation', 0, 100, 0.25, inline = "dev") style = input.string("Solid", "Line Style", ["Solid", "Dotted", "Dashed"]) enable = input.bool(false, "", inline = "dev") label_size = input.string("Tiny", "Labels", ["Auto", "Tiny", "Small", "Normal", "Large", "Huge"], inline = "label") labels = input.bool(true, "", inline = "label") bullish_color = input.color(color.rgb(84, 194, 148), "Colors", inline = "color") bearish_color = input.color(color.rgb(235, 57, 57), "", inline = "color") text_color = input.color(color.rgb(8, 12, 20), "", inline = "color") size = switch label_size "Auto" => size.auto "Tiny" => size.tiny "Small" => size.small "Normal" => size.normal "Large" => size.large "Huge" => size.huge line_style = switch style "Solid" => line.style_solid "Dotted" => line.style_dotted "Dashed" => line.style_dashed sq(source) => math.pow(source, 2) gaussian(source, bandwidth) => math.exp(-sq(source / bandwidth) / 2) / math.sqrt(2 * math.pi) triangular(source, bandwidth) => math.abs(source/bandwidth) <= 1 ? 1 - math.abs(source/bandwidth) : 0.0 epanechnikov(source, bandwidth) => math.abs(source/bandwidth) <= 1 ? (3/4.) * (1 - sq(source/bandwidth)) : 0.0 quartic(source, bandwidth) => if math.abs(source/bandwidth) <= 1 15/16. * math.pow(1 - sq(source/bandwidth), 2) else 0.0 logistic(source, bandwidth) => 1 / (math.exp(source / bandwidth) + 2 + math.exp(-source / bandwidth)) cosine(source, bandwidth) => math.abs(source/bandwidth) <= 1 ? (math.pi / 4) * math.cos((math.pi / 2) * (source/bandwidth)) : 0.0 laplace(source, bandwidth) => (1 / (2 * bandwidth)) * math.exp(-math.abs(source/bandwidth)) exponential(source, bandwidth) => (1 / bandwidth) * math.exp(-math.abs(source/bandwidth)) silverman(source, bandwidth) => if math.abs(source/bandwidth) <= 0.5 0.5 * math.exp(-(source/bandwidth)/2) * math.sin((source/bandwidth)/2 + math.pi/4) else 0.0 tent(source, bandwidth) => if math.abs(source/bandwidth) <= 1 1 - math.abs(source/bandwidth) else 0.0 cauchy(source, bandwidth) => 1 / (math.pi * bandwidth * (1 + sq(source / bandwidth))) sinc(source, bandwidth) => if source == 0 1 else math.sin(math.pi * source / bandwidth) / (math.pi * source / bandwidth) wave(source, bandwidth) => if (math.abs(source/bandwidth) <= 1) (1 - math.abs(source/bandwidth)) * math.cos((math.pi * source) / bandwidth) else 0.0 parabolic(source, bandwidth) => if math.abs(source/bandwidth) <= 1 1 - math.pow((source/bandwidth), 2) else 0.0 power(source, bandwidth) => if (math.abs(source/bandwidth) <= 1) math.pow(1 - math.pow(math.abs(source/bandwidth), 3), 3) else 0.0 loglogistic(source, bandwidth) => 1 / math.pow(1 + math.abs(source / bandwidth), 2) morters(source, bandwidth) => if math.abs(source / bandwidth) <= math.pi (1 + math.cos(source / bandwidth)) / (2 * math.pi * bandwidth) else 0.0 kernel(source, bandwidth, style)=> switch style "Triangular" => triangular(source, bandwidth) "Gaussian" => gaussian(source, bandwidth) "Epanechnikov" => epanechnikov(source, bandwidth) "Logistic" => logistic(source, bandwidth) "Log Logistic" => loglogistic(source, bandwidth) "Cosine" => cosine(source, bandwidth) "Sinc" => sinc(source, bandwidth) "Laplace" => laplace(source, bandwidth) "Quartic" => quartic(source, bandwidth) "Parabolic" => parabolic(source, bandwidth) "Exponential" => exponential(source, bandwidth) "Silverman" => silverman(source, bandwidth) "Cauchy" => cauchy(source, bandwidth) "Tent" => tent(source, bandwidth) "Wave" => wave(source, bandwidth) "Power" => power(source, bandwidth) "Morters" => morters(source, bandwidth) type coefficients float[] weights float sumw precalculate(float bandwidth, string kernel)=> var coefficients[] c = array.new() if barstate.isfirst for i = 0 to 499 coefficients w = coefficients.new(array.new(), 0) float sumw = 0 for j = 0 to 499 diff = i - j weight = kernel(diff, bandwidth, kernel) sumw += weight w.weights.push(weight) w.sumw := sumw c.push(w) c else c precalculate_nrp(bandwidth, kernel)=> var float[] weights = array.new() var float sumw = 0 if barstate.isfirst for i = 0 to bandwidth - 1 j = math.pow(i, 2) / (math.pow(bandwidth, 2)) weight = kernel(j, 1, kernel) weights.push(weight) sumw += weight [weights, sumw] else [weights, sumw] multi_kernel_regression(source, bandwidth, deviations, style, labels, enable, line_style, text_color, bullish_color, bearish_color, size, repaint)=> var estimate_array = array.new(500, line.new(na, na, na, na)) var dev_upper_array = array.new(500, line.new(na, na, na, na)) var dev_lower_array = array.new(500, line.new(na, na, na, na)) var up_labels = array.new