Linear Regression Trendline

Moderator: admin

Linear Regression Trendline

Postby Apprentice » Mon Mar 15, 2010 1:17 pm

This indicator seems to be over, it is not so.

I have to fix the algorithm of trend lines, I plan to add the channel as well.

I have to add algorithm for timely, intelligent end of the previous and the beginning of the new trend, currently i use arbitrary period.

I made this indicator, as a test of my Lua skills,.

I must admit, it is not difficult to learn the functions, but to design a suitable algorithm has been another matter. I'm pretty rusty. I need two hours to finish it.
Attachments
Linear Regression Trendline.PNG
Linear Regression Trendline
linear regression trendline.lua
Linear Regression Trendline
(2.43 KiB) Downloaded 1107 times
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Nikolay.Gekht » Tue Mar 16, 2010 1:35 pm

I would like to pay your attention at the following part of your indicator:

Code: Select all
local sumy=0;
local sumxy=0;
local sumx=0;
local sumx2=0;

...
function Update()
      ...
      sumy=sumy+zakljucna;
      sumxy=sumxy+(zakljucna*test);
      sumx=sumx+test;
      sumx2=sumx2+(test*test);
end


This will work well only when you have applied your indicator on the static historical data, which never receives updates and never be scrolled back, to upload more data.

Please look at the logic.

1) Your indicator is applied to the chart. sumy is zero.
2) Marketscope starts to calculate the indicator from the oldest (0) bar to newest, calling the Update function once per candle. sumy accumulates the sequental value as it is expected.
3a) Now the user scrolled your chart back, so older data appears in the front of the collection. The marketscope starting to call your indicator for older bars. Oups, but sumy contains the value which already accumulated a sum for newest value!
3b) Now the new tick comes and updates the last candle. The marketscope calls your indicator again to re-caculate the value for the latest candle. In fact, we must substract the previously calculated value for a candle before adding a new one.

You have to do the following to avoid this:

1) Create internal streams for sumy, sumy2, sumx, sumx2
Add the following code into the Prepare function
Code: Select all
sumy = instance:addInternalStream(0, 0);
sumy1 = instance:addInternalStream(0, 0);
sumx = instance:addInternalStream(0, 0);
sumx2 = instance:addInternalStream(0, 0);


2) For the first candle just put the first value, for further candles - use the stored previous value from the internal streams

Code: Select all
if period == 0 then
   sumy[period] = zakljucna;
else
  sumy[period] = sumy[period - 1] + zakljucna;
end


In this way your indicator will be absolutely safe to be recalculated starting at any candle or in case the candle is recalculated multiple times.
Nikolay.Gekht
FXCodeBase: Site Admin
 
Posts: 1235
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Re: Linear Regression Trendline

Postby Apprentice » Tue Mar 16, 2010 3:07 pm

Thank you for your instructions, I noticed that something is not working properly, but I have not had time to address the problem.

Still thinking two dimensionally, you're right I have to add a third dimension, time.

I am aware of streams but I did not accept them yet.

Poor handling errors gave me a lot of problems, I have a piece of code that freezes the entire application, prevent re-boot, deletion of indicators is requested , except that I found the Variation Index (IVAR) indicator creates problems, I wrote to you more on your PM . when I find time, tomorrow.

Now working on a set of related indicators, Sklope and R-Squared, These streams could help.
Need them to finish the Linear Regression Trendline.
Done, by the end of Friday, I hope, before closing, so I could test them.
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Apprentice » Tue Mar 16, 2010 4:56 pm

I rushed with modifications, I'm pretty fatigue, 18 hour work day is behind me, so I have not checked details. If you have time you can review the code.
Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
    indicator:name("Linear Regrasion Line");
    indicator:description("Linear Regrasion Line");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Indicator);

    indicator.parameters:addInteger("period", "Period", "Period", 20);
    indicator.parameters:addColor("out_color", "Color of out", "Color of out", core.rgb(255, 0, 0));
end

-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block


local first;
local source = nil;

-- Streams block
local out = nil;
local a =0;
local b =0;
local c =0;
local tmp =0;
local pmt =0;
local prvi =0;
local drugi =0;
local petlja =1;
local zakljucna=0;
local oldx=0
local oldy=0
local frame=0;
local testreset=0;

-- Routine
function Prepare()
    frame = instance.parameters.period;
    source = instance.source;
    first = source:first();
   
sumy = instance:addInternalStream(0, 0);
sumxy = instance:addInternalStream(0, 0);
sumy1 = instance:addInternalStream(0, 0);
sumx = instance:addInternalStream(0, 0);
sumx2 = instance:addInternalStream(0, 0);
test = instance:addInternalStream(0, 0);

    local name = profile:id() .. "(" .. source:name() .. ", " .. frame .. ")";
    instance:name(name);
    out = instance:addStream("out", core.Line, name, "out", instance.parameters.out_color, first);
end

-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period)
    if period >= first and source:hasData(period) then
     
      if testreset == 0 and period > first then
      test[period]=test[period-1]+1;
      sumy[period] = sumy[period - 1] + zakljucna;
  sumxy[period]=sumxy[period-1]+(zakljucna*test[period]);
  sumx[period]=sumx[period-1]+test[period];
  sumx2[period]=sumx2[period-1]+(test[period]*test[period]);
      else
      testreset=0;
      test[period]=1;
      sumy[period] = zakljucna;
   sumxy[period]=zakljucna*test[period];
   sumx[period]=test[period];
   sumx2[period]=test[period]*test[period];
      end
   
    zakljucna=source.close[period];
          
      if test[period] == frame then   
         
       c=sumx2[period]*test[period]-sumx[period]*sumx[period];
       b=(sumxy[period]*test[period]-sumx[period]*sumy[period])/c;
       a=(sumy[period]-sumx[period]*b)/test[period];
       pmt=a+b*test[period];
                   
       core.drawLine(out, core.range(oldx, period), oldy, oldx, pmt,period);
       oldx=period;
       oldy=pmt;
      
      testreset=1;      
      
      end        
      
    end
end
Attachments
linear regression trendline.lua
Linear Regression Trendline
(2.86 KiB) Downloaded 1067 times
Linear Regression Trendline.PNG
Linear Regression Trendline
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Apprentice » Wed Mar 17, 2010 6:15 am

I finished the two versions of Slope indicator .
The first of two secondary indicators. You can use them as independent entities.
I hope that tomorrow I will finish second, and on Friday combined all three indicators in order to get the advanced version of Linear Regression Trendline
Attachments
Slope_simple.lua
Slope_simple.lua
(1.64 KiB) Downloaded 1063 times
slope advanced.lua
slope advanced.lua
(3.33 KiB) Downloaded 1076 times
slope.PNG
Slope
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Nikolay.Gekht » Wed Mar 17, 2010 6:10 pm

I have taken a look at linear regression trendline.lua. It looks more or less working, but can be optimized and simplified. For example, you do not need to calculate the test stream and saving of the previous position can be more effective via bookmarks, because the position of the same bar inside the stream can be changed between calls of the Update function.

I also deployed the beta version of the SDK and have a beta of Marketscope in my hand. I think, it's a good idea to write the indicator for a new version.
Nikolay.Gekht
FXCodeBase: Site Admin
 
Posts: 1235
Joined: Wed Dec 16, 2009 6:39 pm
Location: Cary, NC

Re: Linear Regression Trendline

Postby Apprentice » Thu Mar 18, 2010 6:19 am

Tomorrow and all weekend I've booked for the optimization of the code.

I made a working version of RSquared indicators.
But I encountered an unexpected obstacle.

Horizontal lines that can not be updated.

Lines 67 -75


Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
    indicator:name("RSquared");
    indicator:description("RSquared");
    indicator:requiredSource(core.Bar);
    indicator:type(core.Oscillator);

    indicator.parameters:addInteger("period", "Period", "Period", 14);
    indicator.parameters:addColor("RSquared_color", "Color of RSquared", "Color of RSquared", core.rgb(255, 0, 0));
   indicator.parameters:addColor("Line_color", "Color of Line", "Color of Line", core.rgb(255, 0, 0));

end

-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block

local first;
local source = nil;

-- Streams block
local RSquared = nil;
local Line = nil;
local a =0;
local b =0;
local c =0;
local tmp =0;
local pmt =0;
local prvi =0;
local drugi =0;
local petlja =1;
local zakljucna=0;
local oldx=0
local oldy=0
local frame=0;
local testreset=0;
local petlja =0;

-- Routine
function Prepare()
    frame = instance.parameters.period;
   
   
   
    source = instance.source;
    first = source:first();
   
sumy = instance:addInternalStream(0, 0);
sumxy = instance:addInternalStream(0, 0);
sumy1 = instance:addInternalStream(0, 0);
sumx = instance:addInternalStream(0, 0);
sumx2 = instance:addInternalStream(0, 0);
sumy2 = instance:addInternalStream(0, 0);
test = instance:addInternalStream(0, 0);

    local name = profile:id() .. "(" .. source:name() .. ", " .. frame .. ")";
    instance:name(name);
    RSquared = instance:addStream("RSquared", core.Line, name, "RSquared", instance.parameters.RSquared_color, first);
   
   Line = instance:addStream("Line", core.Line, name, "Line", instance.parameters.Line_color, first);
   
   
   if frame <= 5 then    Line:addLevel(0.77)    end
   if frame > 5  and frame <= 10  then    Line:addLevel(0.77);    end
   if frame > 10  and frame <= 14  then    Line:addLevel(0.40);    end
   if frame > 14  and frame <= 20  then    Line:addLevel(0.27);    end
   if frame > 20  and  frame <= 25  then    Line:addLevel(0.20);    end
   if frame > 25  and frame <= 30   then    Line:addLevel(0.16);    end
   if frame > 30 and  frame <= 50  then     Line:addLevel(0.13);    end
   if frame > 50 and  frame <= 50  then    Line:addLevel(0.18);    end
   if frame >= 120 then  Line:addLevel(0.03) end
   
   
   
   
      
end

-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period)
 if period >= frame and source:hasData(period) then
 
                     sumy[period] = 0;
                  sumxy[period]=0;
                  sumx[period]=0;
                  sumx2[period]=0;
      
                      if testreset==1 then
                  test[period]=test[period-1]-1;
                  testreset=0;
                  end
   
                      if period==first then
                  test[period]=1;
                  else
                  test[period]=test[period-1]+1;
                  end
      
                   if test[period] > frame  then
                              
                        for petlja = (period-frame), period, 1 do
                        
                           if petlja == (period-frame) then
                           test[petlja]=1;
                           sumy[petlja] = source.close[petlja];
                           sumxy[petlja]=source.close[petlja]*test[petlja];
                           sumx[petlja]=test[petlja];
                           sumx2[petlja]=test[petlja]*test[petlja];
                           sumy2[petlja]= source.close[petlja]* source.close[petlja];
                           else
                           test[petlja]=test[petlja-1]+1;                                       
                            sumy[petlja] = sumy[petlja - 1] + source.close[petlja];
                            sumxy[petlja]=sumxy[petlja-1]+(source.close[petlja]*test[petlja]);
                            sumx[petlja]=sumx[petlja-1]+test[petlja];
                            sumx2[petlja]=sumx2[petlja-1]+(test[petlja]*test[petlja]);
                           sumy2[petlja]= sumy2[petlja-1]+ source.close[petlja]* source.close[petlja];
                           end
                        end
                        testreset=1;
                  end
          if period > frame /2 then                     
         
      
       --a=(sumy-sumx*b)/test;
      
      
      
         
            
      
      
         
            c=sumx2[period-frame/2]*test[period-frame/2]-sumx[period-frame/2]*sumx[period-frame/2];
          b=(sumxy[period-frame/2]*test[period-frame/2]-sumx[period-frame/2]*sumy[period-frame/2])/c;      
          d=sumy2[period-frame/2]*test[period-frame/2]-sumy[period-frame/2]*sumy[period-frame/2];
           div=math.sqrt(c*d);
           e=(sumxy[period-frame/2]*test[period-frame/2]-sumx[period-frame/2]*sumy[period-frame/2])/ div;
            RSquared[period- frame/2]=e*e;
         end
       end
 end
Attachments
R-Squared.lua
R-Squared
(4.66 KiB) Downloaded 1077 times
Last edited by Apprentice on Thu Mar 18, 2010 3:07 pm, edited 2 times in total.
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Apprentice » Thu Mar 18, 2010 6:50 am

If you want you can write, test indicator on the new version of Marketscope.
For starting point of each line uses a variable "a" instead the end of previous line end variable "oldy".

Indicator is described in detail in the book Technical analysis from A to Z, page 176

Before the end, i add a few dozen lines of code, maybe hundredth.
Apart from better algorithms, Linear Regression Slope and R-Squared are only auxiliary indicators for the algorithm, it would be good to add and Raff Regression Channel.

I really should not take such a complex indicator for learning.
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Apprentice » Sat Mar 20, 2010 11:20 am

Finally all starting to look as it should.

More or less over, see room for improvement on Linear Regression Trendline, objections and suggestions are welcome.

Probably it is too difficult a challenge for me but anyway I'm going to try to design an algorithm for pattern recognition, among other things.
Attachments
Linear Regression Trend Line with Raff Channel Linear Regression Slope Simple Slope and R-Squared.PNG
R-Squared
Linear Regression Slope.lua
Linear Regression Slope
(2.28 KiB) Downloaded 1077 times
Simple Slope.lua
Simple Slope
(1.63 KiB) Downloaded 1095 times
Last edited by Apprentice on Mon Mar 22, 2010 3:16 am, edited 2 times in total.
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Re: Linear Regression Trendline

Postby Apprentice » Sun Mar 21, 2010 3:20 pm

R-Squared & Linear Regrasion Line with Raff Regrasion Channel

Linear Regrasion Line with Raff Regrasion Channel is not completed.
Attachments
R-Squared.lua
R-Squared.lua
(3.38 KiB) Downloaded 1091 times
Linear Regrasion Line with Raff Channel.lua
Linear Regrasion Line with Raff Channel
(6.63 KiB) Downloaded 1057 times
User avatar
Apprentice
FXCodeBase: Confirmed User
 
Posts: 36435
Joined: Thu Dec 31, 2009 11:59 am
Location: Zagreb, Croatia

Next

Return to Indicator Development

Who is online

Users browsing this forum: No registered users and 4 guests