Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // /$$$$$$ /$$ /$$
- // /$$__ $$ | $$ | $$
- //| $$ \__//$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$
- //| $$$$$$|_ $$_/ /$$__ $$| $$ /$$//$$__ $$ /$$__ $$ /$$_____/|_ $$_/ /$$__ $$| $$ /$$//$$__ $$ /$$_____/
- // \____ $$ | $$ | $$$$$$$$ \ $$/$$/| $$$$$$$$| $$ \__/| $$$$$$ | $$ | $$$$$$$$ \ $$/$$/| $$$$$$$$| $$$$$$
- // /$$ \ $$ | $$ /$$| $$_____/ \ $$$/ | $$_____/| $$ \____ $$ | $$ /$$| $$_____/ \ $$$/ | $$_____/ \____ $$
- //| $$$$$$/ | $$$$/| $$$$$$$ \ $/ | $$$$$$$| $$ /$$$$$$$/ | $$$$/| $$$$$$$ \ $/ | $$$$$$$ /$$$$$$$/
- // \______/ \___/ \_______/ \_/ \_______/|__/ |_______/ \___/ \_______/ \_/ \_______/|_______/
- // © Steversteves
- //@version=5
- indicator("Quadratic & Linear Time Series Regression [SS]", shorttitle = "Quadratic & Linear Regression [SS]", overlay=true, max_bars_back = 5000)
- // Groups //
- g0 = "Timeframe Select"
- g1 = "Setting and Analysis Type"
- g2 = "Standard Deviation Extensions"
- // User inputs //
- start_time = input.time(timestamp("20 Jul 2022 00:00 +000"), title = "Start time for Period", confirm = true, group = g0)
- typeselect = input.string("Quadratic Time Series", "Select Regression Type", ["Quadratic Time Series", "Linear Regression Time Series"], group = g1)
- showrngtbl = input.bool(true, "Show Range Table", group = g1)
- showstats = input.bool(true, "Show Statistics Table", group = g1)
- pltfills = input.bool(true, "Plot Fills", group = g1)
- ci_input = input.float(1.96, "Confidence Interval Input", group = g1)
- stdevi = input.string("None", "Add Additional Standard Deviation Bands", ["None", "One", "Two", "Three"], group = g2)
- stdev1 = input.float(2, "Standard Deviation Input 1", group = g2)
- stdev2 = input.float(3, "Standard Deviation Input 2", group = g2)
- stdev3 = input.float(4, "Standard Deviation Input 3", group = g2)
- // Define Variables
- float x1 = 0.0
- float x2 = 0.0
- float y = 0.0
- float result = 0.0
- // Define analysis type
- if typeselect == "Quadratic Time Series"
- x1 := time
- x2 := math.pow(time,2)
- y := close
- if typeselect == "Linear Regression Time Series"
- x1 := time
- x2 := 0
- y := close
- int candle = 0
- // Regression
- x1_sq = array.new_float()
- x2_sq = array.new_float()
- x1_array = array.new_float()
- x2_array = array.new_float()
- x1_y = array.new_float()
- x2_y = array.new_float()
- x1_x2 = array.new_float()
- y_array = array.new_float()
- candle_a = array.new_float()
- result_a = array.new_float()
- for i = 0 to 4999
- if time[i] >= start_time
- array.push(x1_sq, (x1[i] * x1[i]))
- array.push(x2_sq, (x2[i] * x2[i]))
- array.push(x1_array, x1[i])
- array.push(x2_array, x2[i])
- array.push(x1_y, (x1[i] * y[i]))
- array.push(x2_y, (x2[i] * y[i]))
- array.push(x1_x2, (x1[i] * x2[i]))
- array.push(y_array, y[i])
- array.push(candle_a, candle + 1)
- x1_sq_sum = array.sum(x1_sq)
- x2_sq_sum = array.sum(x2_sq)
- x1_sum = array.sum(x1_array)
- x2_sum = array.sum(x2_array)
- x1_y_sum = array.sum(x1_y)
- x2_y_sum = array.sum(x2_y)
- x1_x2_sum = array.sum(x1_x2)
- y_sum = array.sum(y_array)
- i1_x = x1_sq_sum - (math.pow(x1_sum, 2) / array.size(y_array))
- i2_x = x2_sq_sum - (math.pow(x2_sum, 2) / array.size(y_array))
- i1_y = x1_y_sum - ((x1_sum * y_sum) / array.size(y_array))
- i2_y = x2_y_sum - ((x2_sum * y_sum) / array.size(y_array))
- len = array.size(y_array)
- ix1x2 = x1_x2_sum - ((x1_sum * x2_sum) / array.size(y_array))
- b1 = ((i2_x * i1_y) - (ix1x2 * i2_y)) / ((i1_x * i2_x) - math.pow(ix1x2, 2))
- b2 = ((i1_x * i2_y) - (ix1x2 * i1_y)) / ((i1_x * i2_x) - math.pow(ix1x2, 2))
- b0 = (y_sum / len) - (b1 * (x1_sum / len)) - (b2 * (x2_sum / len))
- quad_result = (x1 * b1) + (x2 * b2) + b0
- //
- lin_reg_b1 = x1_y_sum - (x1_sum * y_sum) / len
- bbb2 = x1_sq_sum - (math.pow(x1_sum, 2) / len)
- slope = (lin_reg_b1 / bbb2)
- abc = y_sum - (slope * x1_sum)
- abc1 = abc / array.size(y_array)
- lin_reg_result = (x1 * slope) + abc1
- if typeselect == "Quadratic Time Series"
- result := quad_result
- if typeselect == "Linear Regression Time Series"
- result := lin_reg_result
- for i = 0 to 4999
- if time[i] >= start_time
- array.push(result_a, result[i])
- se_residuals = array.new_float()
- for i = 0 to len
- array.push(se_residuals, (result[i] - y[i]) * (result[i] - y[i]))
- se_add = array.sum(se_residuals)
- r1 = se_add / (len - 2)
- se= math.sqrt(r1)
- candle_count = array.sum(candle_a)
- // Colours
- color black = color.rgb(0, 0, 0)
- color white = color.white
- color outer_c = color.new(color.red, 85)
- color outer_b = color.new(color.orange, 85)
- color outer_a = color.new(color.yellow, 85)
- color inner = color.new(color.lime, 85)
- color outer = color.new(color.red, 70)
- h = plot(result, color = inner)
- ii = plot(result + se, color = inner)
- j = plot(result - se, color = inner)
- fill(h, ii, color = pltfills ? inner : na)
- fill(h, j, color= pltfills ? inner : na)
- tss = se_add + se_add
- // Correlation
- float pr = 0.0
- float r2 = 0.0
- cov = array.covariance(x1_x2, y_array)
- lin_cov = array.covariance(y_array, x1_array)
- x1_x2_sd = array.stdev(x1_x2)
- y_sd = array.stdev(y_array)
- x1_sd = array.stdev(x1_array)
- quad_cor = cov / (x1_x2_sd * y_sd)
- lin_cor = lin_cov / (x1_sd * y_sd)
- r2_quad = math.pow(quad_cor, 2)
- r2_lin = math.pow(lin_cor, 2)
- if typeselect == "Quadratic Time Series"
- pr := quad_cor
- r2 := r2_quad
- if typeselect == "Linear Regression Time Series"
- pr := lin_cor
- r2 := r2_lin
- best_fit = math.max(quad_cor, lin_cor)
- least_variance = math.max(r2_quad, r2_lin)
- string best_fit_res = best_fit == quad_cor ? "The Quadratic Regression Approach has a Stronger relationship for this data" : best_fit == lin_cor ? "The Linear Regression Approach has a Strnger Relationship for this data." : na
- string least_variance_res = least_variance == r2_quad? "The Quad Regression explains the variance in data better than the LinReg Model" : least_variance == r2_lin ? "The Lin regression explains the variance in data better than the QuadReg Model." : na
- // Extension of Standard Deviation Bands
- stdev_extend_1 = se * stdev1
- stdev_extend_2 = se * stdev2
- stdev_extend_3 = se * stdev3
- f_confidence_interval(array1, array2) =>
- upper_bound = 0.0
- lower_bound = 0.0
- ci_conv = 0.0
- // Standard Error
- avg1 = array.avg(array1)
- avg2 = array.avg(array2)
- asd1 = array.stdev(array1)
- asd2 = array.stdev(array2)
- se1 = (math.pow(asd1,2) / array.size(array1))
- se2 = (math.pow(asd2,2) / array.size(array2))
- se3 = (se1 + se2)
- s_er = math.sqrt(se3)
- // Confidence interval
- avg_dif = (avg1 - avg2)
- ci = s_er * ci_input
- upper_bound := avg_dif + ci
- lower_bound := avg_dif - ci
- ci_conv := (ci_input - 1) * 100
- [upper_bound, lower_bound, ci_conv]
- [ci_upper, ci_lower, ci_conversion] = f_confidence_interval(y_array, result_a)
- // SD 1 band
- a = plot(stdevi == "One" or stdevi == "Two" or stdevi == "Three" ? result + stdev_extend_1 : na, color = outer_a)
- b = plot(stdevi == "One" or stdevi == "Two" or stdevi == "Three" ? result - stdev_extend_1: na, color = outer_a)
- // SD 2 Bands
- c = plot(stdevi == "Two" or stdevi == "Three" ? result + stdev_extend_2 : na, color = outer_b)
- d = plot(stdevi == "Two" or stdevi == "Three" ? result - stdev_extend_2: na, color = outer_b)
- // SD 3 Band
- e = plot(stdevi == "Three" ? result + stdev_extend_3 : na, color = outer_c)
- f = plot(stdevi == "Three" ? result - stdev_extend_3: na, color = outer_c)
- fill(a, ii, color = pltfills ? outer_a : na)
- fill(a, c, color = pltfills ? outer_b : na)
- fill(c, e, color = pltfills ? outer_c : na)
- fill(j, b, color = pltfills ? outer_a : na)
- fill(b, d, color = pltfills ? outer_b : na)
- fill(d, f, color = pltfills ? outer_c : na)
- var table data = table.new(position.bottom_right, 5, 8, bgcolor = black,frame_color = white, frame_width = 2)
- if showstats
- table.cell(data, 1, 1, text = "R2 = " + str.tostring(math.round(r2, 4)), bgcolor = black, text_color = white)
- table.cell(data, 1, 2, text = "Pearson Correlation = " + str.tostring(math.round(pr,2)), bgcolor = black, text_color = white)
- table.cell(data, 1, 4, text = "Upper Bound Confidence Interval " + str.tostring(math.round(ci_conversion)) + "% = " + str.tostring(math.round(ci_upper,2)) + "\n Lower Bound Confidence Interval " + str.tostring(math.round(ci_conversion)) + "% = " + str.tostring(math.round(ci_lower,2)), bgcolor = black, text_color = white)
- table.cell(data, 1, 5, text = str.tostring(best_fit_res), bgcolor = black, text_color = white)
- table.cell(data, 1, 6, text = str.tostring(least_variance_res), bgcolor = black, text_color = white)
- table.cell(data, 1, 7, text = "Total Candles in Period = " + str.tostring(candle_count), bgcolor = black, text_color = white)
- // Range
- f_condition_counter(condition, candlecount) =>
- perc_success = 0.0
- num_success = 0.0
- var int pass = 0
- for i = 0 to 5000
- if time[i] >= start_time
- if condition[i] and barstate.islast
- pass := pass + 1
- num_success := pass
- perc_success := (pass / candlecount) * 100
- [perc_success, num_success]
- // Extensions of Standard Deviation
- pos_stdev_extend_1 = result + (se * stdev1)
- pos_stdev_extend_2 = result + (se * stdev2)
- pos_stdev_extend_3 = result + (se * stdev3)
- neg_stdev_extend_1 = result - (se * stdev1)
- neg_stdev_extend_2 = result - (se * stdev2)
- neg_stdev_extend_3 = result - (se * stdev3)
- // Within Range Counter
- bool within_range = close <= result + se and close >= result - se
- bool outside_range = close > result + se or close < result - se
- bool within_pos_1 = close > result + se and close < pos_stdev_extend_1
- bool within_pos_2 = close >= pos_stdev_extend_1 and close < pos_stdev_extend_2
- bool within_pos_3 = close >= pos_stdev_extend_2 and close <= pos_stdev_extend_3
- bool pos_outside = close >= pos_stdev_extend_3
- bool within_neg_1 = close < result - se and close > neg_stdev_extend_1
- bool within_neg_2 = close <= neg_stdev_extend_1 and close > neg_stdev_extend_2
- bool within_neg_3 = close <= neg_stdev_extend_2 and close > neg_stdev_extend_3
- bool neg_outside = close <= neg_stdev_extend_3
- [within_rng_perc, within_rng_num] = f_condition_counter(within_range, candle_count)
- [within_pos1_perc, within_pos1_num] = f_condition_counter(within_pos_1, candle_count)
- [within_pos2_perc, within_pos2_num] = f_condition_counter(within_pos_2, candle_count)
- [within_pos3_perc, within_pos3_num] = f_condition_counter(within_pos_3, candle_count)
- [pos_outside_perc, pos_outside_num] = f_condition_counter(pos_outside, candle_count)
- [within_neg1_perc, within_neg1_num] = f_condition_counter(within_neg_1, candle_count)
- [within_neg2_perc, within_neg2_num] = f_condition_counter(within_neg_2, candle_count)
- [within_neg3_perc, within_neg3_num] = f_condition_counter(within_neg_3, candle_count)
- [neg_outside_perc, neg_outside_num] = f_condition_counter(neg_outside, candle_count)
- var table count_table = table.new(position.middle_right, 5, 11, bgcolor = black, frame_color = white, frame_width = 2)
- neg_sd1 = (stdev1 * -1)
- neg_sd2 = (stdev2 * -1)
- neg_sd3 = (stdev3 * -1)
- // Price Ranges
- rng_ucl = result + se
- rng_lcl = result - se
- if showrngtbl
- table.cell(count_table, 1, 1, text = "Condition", bgcolor=black, text_color = white)
- table.cell(count_table, 2, 1, text = "%", bgcolor=black, text_color = white)
- table.cell(count_table, 3, 1, text = "# Candles", bgcolor=black, text_color = white)
- table.cell(count_table, 4, 1, text = "Price Range", bgcolor=black, text_color = white)
- table.cell(count_table, 1, 2, text = "Below Range", bgcolor = outer, text_color = white)
- table.cell(count_table, 1, 3, text = str.tostring(neg_sd3) + " SD", bgcolor = outer_c, text_color = white)
- table.cell(count_table, 1, 4, text = str.tostring(neg_sd2) + " SD", bgcolor = outer_b, text_color = white)
- table.cell(count_table, 1, 5, text = str.tostring(neg_sd1) + " SD", bgcolor = outer_a, text_color = white)
- table.cell(count_table, 1, 6, text = "In Range", bgcolor = inner, text_color = white)
- table.cell(count_table, 1, 7, text = str.tostring(stdev1) + " SD", bgcolor = outer_a, text_color = white)
- table.cell(count_table, 1, 8, text = str.tostring(stdev2) + " SD", bgcolor = outer_b, text_color = white)
- table.cell(count_table, 1, 9, text = str.tostring(stdev3) + " SD", bgcolor = outer_c, text_color = white)
- table.cell(count_table, 1, 10, text = "Above Range", bgcolor = outer, text_color = white)
- table.cell(count_table, 2, 2, text = str.tostring(math.round(neg_outside_perc)) + "%", bgcolor = outer, text_color = white)
- table.cell(count_table, 2, 3, text = str.tostring(math.round(within_neg3_perc)) + "%", bgcolor = outer_c, text_color = white)
- table.cell(count_table, 2, 4, text = str.tostring(math.round(within_neg2_perc)) + "%", bgcolor = outer_b, text_color = white)
- table.cell(count_table, 2, 5, text = str.tostring(math.round(within_neg1_perc)) + "%", bgcolor = outer_a, text_color = white)
- table.cell(count_table, 2, 6, text = str.tostring(math.round(within_rng_perc)) + "%", bgcolor = inner, text_color = white)
- table.cell(count_table, 2, 7, text = str.tostring(math.round(within_pos1_perc)) + "%", bgcolor = outer_a, text_color = white)
- table.cell(count_table, 2, 8, text = str.tostring(math.round(within_pos2_perc)) + "%", bgcolor = outer_b, text_color = white)
- table.cell(count_table, 2, 9, text = str.tostring(math.round(within_pos3_perc)) + "%", bgcolor = outer_c, text_color = white)
- table.cell(count_table, 2, 10, text = str.tostring(math.round(pos_outside_perc)) + "%", bgcolor = outer, text_color = white)
- table.cell(count_table, 3, 2, text = str.tostring(neg_outside_num), bgcolor = outer, text_color = white)
- table.cell(count_table, 3, 3, text = str.tostring(within_neg3_num), bgcolor = outer_c, text_color = white)
- table.cell(count_table, 3, 4, text = str.tostring(within_neg2_num), bgcolor = outer_b, text_color = white)
- table.cell(count_table, 3, 5, text = str.tostring(within_neg1_num), bgcolor = outer_a, text_color = white)
- table.cell(count_table, 3, 6, text = str.tostring(within_rng_num), bgcolor = inner, text_color = white)
- table.cell(count_table, 3, 7, text = str.tostring(within_pos1_num), bgcolor = outer_a, text_color = white)
- table.cell(count_table, 3, 8, text = str.tostring(within_pos2_num), bgcolor = outer_b, text_color = white)
- table.cell(count_table, 3, 9, text = str.tostring(within_pos3_num), bgcolor = outer_c, text_color = white)
- table.cell(count_table, 3, 10, text = str.tostring(pos_outside_num), bgcolor = outer, text_color = white)
- table.cell(count_table, 4, 2, text = "<= " + str.tostring(math.round(neg_stdev_extend_3,2)), bgcolor = outer, text_color = white)
- table.cell(count_table, 4, 3, text = str.tostring(math.round(neg_stdev_extend_2,2)) + " to " + str.tostring(math.round(neg_stdev_extend_3,2)), bgcolor = outer_c, text_color = white)
- table.cell(count_table, 4, 4, text = str.tostring(math.round(neg_stdev_extend_1,2)) + " to " + str.tostring(math.round(neg_stdev_extend_2, 2)), bgcolor = outer_b, text_color = white)
- table.cell(count_table, 4, 5, text = str.tostring(math.round(rng_lcl,2)) + " to " + str.tostring(math.round(neg_stdev_extend_1)), bgcolor = outer_a, text_color = white)
- table.cell(count_table, 4, 6, text = str.tostring(math.round(rng_lcl,2)) + " to " + str.tostring(math.round(rng_ucl)), bgcolor = inner, text_color = white)
- table.cell(count_table, 4, 7, text = str.tostring(math.round(rng_ucl,2)) + " to " + str.tostring(math.round(pos_stdev_extend_1,2)), bgcolor = outer_a, text_color = white)
- table.cell(count_table, 4, 8, text = str.tostring(math.round(pos_stdev_extend_1,2)) + " to " + str.tostring(math.round(pos_stdev_extend_2,2)), bgcolor = outer_b, text_color = white)
- table.cell(count_table, 4, 9, text = str.tostring(math.round(pos_stdev_extend_2,2)) + " to " + str.tostring(math.round(pos_stdev_extend_3,2)), bgcolor = outer_c, text_color = white)
- table.cell(count_table, 4, 10, text = ">= " + str.tostring(math.round(pos_stdev_extend_3,2)), bgcolor = outer, text_color = white)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement