Trendline Regression TV -> PRT

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #203758 quote
    ashehzi
    Participant
    Average

    Hi PRC team, hope you guys are well. Thanks for whatever you have been doing wrt PRT/PRC.

    I’ve used Trend Line Regression indicator on TradingView (https://www.tradingview.com/script/tf2TTN6c/) and I think we PRT community will surely benefit from it. I appreciate is someone could convert it. As the source code is open, I am sharing here. It is combo of a shared library and the indicator code using that library.

    // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
    // © dandrideng
    
    //@version=5
    
    // @description least_squares_regression: Least squares regression algorithm
    library("least_squares_regression", overlay=true)
    
    // @function basic_lsr: Basic least squares regression algorithm
    // @param series int[] t: time scale value array corresponding to price
    // @param series float[] p: price scale value array corresponding to time
    // @param series int array_size: the length of regression array
    // @returns reg_slop, reg_intercept, reg_level, reg_stdev
    export basic_lsr(series int[] t, series float[] p, series int array_size) =>
    	p_t = array.new_float(array_size, 0)
    	t_2 = array.new_float(array_size, 0)
    	
    	//init array
    	for i = 0 to array_size - 1
    	    array.set(p_t, i, array.get(p, i) * array.get(t, i))
    	    array.set(t_2, i, array.get(t, i) * array.get(t, i))
    	
    	//get slop and intercept
    	sum_t = array.sum(t)
    	sum_p = array.sum(p)
    	sum_t_2 = array.sum(t_2)
    	sum_p_t = array.sum(p_t)
    	a = (array_size * sum_p_t - sum_p * sum_t) / (array_size * sum_t_2 - math.pow(sum_t, 2))
    	b = (sum_p - a * sum_t) / array_size
        
        //get regression prediction value
        _p = array.new_float(array_size, 0)
        for i = 0 to array_size - 1
            array.set(_p, i, a * array.get(t, i) + b)
        
        //get regression level 
        float r1 = 0
        float r2 = 0
        p_avg = array.avg(p)
        for i = 0 to array_size - 1
            r1 += math.pow(array.get(_p, i) - p_avg, 2)
            r2 += math.pow(array.get(p, i) - p_avg, 2)
        r = -math.log10(1 - r1 / r2)
        
        //get regression standard devition
        _s = array.new_float(array_size, 0)
        for i = 0 to array_size - 1
            array.set(_s, i, array.get(p, i) - array.get(_p, i))
        s = array.stdev(_s)
    	
    	//return results
    	[a, b, r, s]
    
    // @function top_trend_line_lsr: Trend line fitting based on least square algorithm
    // @param series int[] t: time scale value array corresponding to price
    // @param series float[] p: price scale value array corresponding to time
    // @param series int array_size: the length of regression array
    // @param string reg_type: regression type in 'top' and 'bottom'
    // @param series int max_iter: maximum fitting iterations
    // @param series int min_points: the threshold of regression point numbers
    // @returns reg_slop, reg_intercept, reg_level, reg_stdev, reg_point_num
    export trend_line_lsr(series int[] t, series float[] p, series int array_size, string reg_type, series int max_iter, series int min_points) =>
    	[a, b, r, s] = basic_lsr(t, p, array_size)
    	x1 = array.get(t, 0)
    	x2 = array.get(t, array_size - 1)
    	n = array_size //Function arguments cannot be mutable, what the fuck!
    
    	for i = 0 to max_iter - 1
    	    //exit conditions
        	if n < min_points
        	    break
        	   
        	//init new tick and price array
            _t = array.new_int(n, 0)
            _p = array.new_float(n, 0)
            _n = 0
            
            //fine the ground truth values that bigger than predictions
            for j = 0 to n - 1
                if reg_type == 'top'
                    if (a * array.get(t, j) + b) < array.get(p, j)
                        array.set(_t, _n, array.get(t, j))
                        array.set(_p, _n, array.get(p, j))
                        _n += 1
                else if reg_type == 'bottom'
                    if (a * array.get(t, j) + b) > array.get(p, j)
                        array.set(_t, _n, array.get(t, j))
                        array.set(_p, _n, array.get(p, j))
                        _n += 1
                else
                    break
            
            //exit if new array size is less than threshold
            if _n < min_points
                break
            
            //override result if r of new array is bigger than last array
            [_a, _b, _r, _s] = basic_lsr(_t, _p, _n)
            if _r > r
                x1 := array.get(_t, 0)
                x2 := array.get(_t, _n - 1)
                a := _a
                b := _b
                r := _r
                s := _s
                n := _n
        
        //after for loop 
        [x1, x2, a, b, r, s, n]
    
    
    
    

     

    // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
    // © dandrideng
    
    //@version=5
    indicator(title="Trend Line Regression", shorttitle="TLR", overlay=true, max_bars_back=800, max_lines_count=400, max_labels_count=400)
    
    import dandrideng/least_squares_regression/1 as lsr
    
    //trend line regression
    lookback_left = input.int(defval=5, title="Pivot Lookback Left", group="Trend Line Regression")
    lookback_right = input.int(defval=5, title="Pivot Lookback Right", group="Trend Line Regression")
    reg_forward = input.int(defval=20, title="Max Lookback Forward", group="Trend Line Regression")
    min_length = input.int(defval=100, title="Min Regression Length", maxval=500, group="Trend Line Regression")
    max_length = input.int(defval=200, title="Max Regression Length", maxval=500, group="Trend Line Regression")
    length_step = input.int(defval=100, title="Regression Length Steps", group="Trend Line Regression")
    max_iteration = input.int(defval=4, title="Max Iterations of Regression", group="Trend Line Regression")
    max_points = input.int(defval=30, title="Max Point Numbers of Trend Line", group="Trend Line Regression")
    min_points = input.int(defval=3, title="Min Point Numbers of Trend Line", group="Trend Line Regression")
    min_reg_level = input.float(defval=4, title="Min Regression Level of Trend Line", group="Trend Line Regression")
    std_offset = input.float(defval=0.5, title="Multiply Regression Std", group="Trend Line Regression")
    top_line_color = input.color(defval=color.red, title="Color of Top Trend Line", group="Trend Line Regression")
    bottom_line_color = input.color(defval=color.green, title="Color of Bottom Trend Line", group="Trend Line Regression")
    extend_lines = input.bool(defval=true, title="Extend Lines", group="Trend Line Regression") ? extend.right : extend.none
    draw_pivot = input.bool(defval=false, title="Draw Piovt High/Low", group="Trend Line Regression")
    show_labels = input.bool(defval=false, title="Show Labels", group="Trend Line Regression")
    
    pivot_high = ta.pivothigh(high, lookback_left, lookback_right)
    pivot_low = ta.pivotlow(low, lookback_left, lookback_right)
    
    plot(draw_pivot ? pivot_high : na, offset=-lookback_left)
    plot(draw_pivot ? pivot_low : na, offset=-lookback_left)
    
    //check regression (functional)
    check_trend_line(start, end, type, a, b) =>
        res = true
        for i = start + 1 to end - 1
            yi = a * i + b
            yi_1 = a * (i - 1) + b
            if type == "top" and (close[i] > yi and close[i - 1] > yi_1)
                res := false
                break
            else if type == "bottom" and (close[i] < yi and close[i - 1] < yi_1)
                res := false
                break
        
        res
        
    //draw trend line regressions (functional)
    draw_trend_line(forward, length, type) =>
        pivot_src = type == "top" ? pivot_high : pivot_low
    
        tick = array.new_int(max_points, 0)
        price = array.new_float(max_points, 0)
        num = 0
    
        for i = 0 to length - 1
            if not na(pivot_src[i + forward]) and num < max_points
                array.set(tick, num, i + lookback_left + forward)
                array.set(price, num, pivot_src[i + forward])
                num := num + 1
            
        if num > 0
            [x2, x1, a, b, r, s, n] = lsr.trend_line_lsr(tick, price, num, type, max_iteration, min_points)
            y1 = x1 * a + b
            y2 = x2 * a + b
            o = s * std_offset
            
            if n > min_points and r > min_reg_level and check_trend_line(x1, x2, type, a, b)
                var line mid_line = na
                mid_line := line.new(x1=bar_index-x1, y1=y1, x2=bar_index-x2, y2=y2)
                line.set_width(mid_line, 1)
                line.set_color(mid_line, color.new(type == "top" ? top_line_color : bottom_line_color, 25))
                line.set_extend(mid_line, extend_lines)
                line.set_style(mid_line, line.style_dashed)
            
                var line top_line = na
                top_line := line.new(x1=bar_index-x1, y1=y1+o, x2=bar_index-x2, y2=y2+o)
                line.set_width(top_line, 1)
                line.set_color(top_line, color.new(type == "top" ? top_line_color : bottom_line_color, 25))
                line.set_extend(top_line, extend_lines)
                
                var line bottom_line = na
                bottom_line := line.new(x1=bar_index-x1, y1=y1-o, x2=bar_index-x2, y2=y2-o)
                line.set_width(bottom_line, 1)
                line.set_color(bottom_line, color.new(type == "top" ? top_line_color : bottom_line_color, 25))
                line.set_extend(bottom_line, extend_lines)
                
                linefill.new(mid_line, top_line, color=color.new(type == "top" ? top_line_color : bottom_line_color, 90))
                linefill.new(mid_line, bottom_line, color=color.new(type == "top" ? top_line_color : bottom_line_color, 90))
                
                if show_labels
                    var label reg_label = na
                    reg_label := label.new(x=bar_index-x2, y=type == "top" ? y2+o : y2-o, textcolor=color.white)
                    label.set_color(reg_label, color.new(type == "top" ? top_line_color : bottom_line_color, 30))
                    label.set_text(reg_label, "Level: " + str.tostring(r, "#.###") + "\nPoints: " + str.tostring(n, "#"))
                    label.set_style(reg_label, type == "top" ? label.style_label_down : label.style_label_up)
    
    //delete all lines
    all_lines = line.all
    if array.size(all_lines) > 0
    	for i = 0 to array.size(all_lines) - 1
    		line.delete(array.get(all_lines, i))
    		
    //delete all labels
    all_labels = label.all
    if array.size(all_labels) > 0
    	for i = 0 to array.size(all_labels) - 1
    		label.delete(array.get(all_labels, i))
    
    //trend line
    for l = min_length to max_length by length_step
        draw_trend_line(reg_forward, l, "top")
        draw_trend_line(reg_forward, l, "bottom")
            
    //end of file
    #203938 quote
    ashehzi
    Participant
    Average

    Hi Team,

    appreciate any input or pointers? I can try myself but could you please see if it is doable in PRC and what do I need to avoid/use?

    Regards

    Ash

Viewing 2 posts - 1 through 2 (of 2 total)
  • You must be logged in to reply to this topic.

Trendline Regression TV -> PRT


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
ashehzi @ashehzi Participant
Summary

This topic contains 1 reply,
has 1 voice, and was last updated by ashehzi
3 years, 3 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 11/07/2022
Status: Active
Attachments: No files
Logo Logo
Loading...