Trendline Regression TV -> PRT

Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #223046 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]

    Now below is indicator, above was using the lib.

    // 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
    #223047 quote
    JC_Bywan
    Moderator
    Master

    Hi, I’ve added it to the list of conversions to assess. If someone “speaks” the TV language and wants to attempt the conversion before Nicolas is back, please feel free to proceed, thanks. (Edit: I didn’t phrase this very well, any translation contribution is welcome at any time, whether he’s here or not)

    #226740 quote
    ashehzi
    Participant
    Average

    I feel it can be a good trading strat if  converted to PRT.

    #226820 quote
    LucasBest
    Participant
    Junior

    As this indicator use a lot of functions, it would be more easy to understand its spirit (how it works to determine supports and resistance) and then code it in PRT language than trying to convert it like it have been coded in Tradingview language.

    Also note that the use of linear regression is not mandatory here. I have done alsmost the same without using it.

    #246925 quote
    ashehzi
    Participant
    Average

    Hi Lucas,

    What is the indicator used to caputre-decran pictures? Is it available on PRT?

    Thanks

    Ash

    #246945 quote
    LucasBest
    Participant
    Junior

    Hi,

    it is an old version of a custom indicator of mine.

    You can find snapshots for simple trendline in prorealcode.

    Lucas

    ashehzi thanked this post
    #247341 quote
    ashehzi
    Participant
    Average

    Hi Lucas,

    If you don’t mind, would it possible to get this custom indicator? Thanks.

    Regards,

    Ash

Viewing 7 posts - 1 through 7 (of 7 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 6 replies,
has 3 voices, and was last updated by ashehzi
8 months, 3 weeks ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 10/30/2023
Status: Active
Attachments: 2 files
Logo Logo
Loading...