Trendline Regression TV -> PRT

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #203758 quote
    ashehziashehzi
    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
    ashehziashehzi
    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.
ProRealAI ProRealAI New

Stuck on this ProBuilder code?

Describe what this topic is trying to build, in plain English, and ProRealAI writes the ProRealTime™ indicator, screener or system for you.

Available in 7 languages
Try ProRealAI

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 ashehziashehzi
3 years, 10 months ago.

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