LSMA indicator... please help with error :(

Indicators coded by community members
Message
Author
User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

LSMA indicator... please help with error :(

#1 Postby Tantalus » Wed Apr 04, 2007 10:39 am

I'm trying to create an indicator for Least Squares Moving Average (LSMA) by modifying the example code for the moving average indicator. I believe the version below might work, but in Delphi it says there's an error in the last line - "Expected BEGIN but received END". Strangely, it gives the same error when I cut and paste the original example code from the help file, without modifications...

I know next to nothing and I can't even begin to compile something using Delphi - maybe some knowledgeable person can see why this code gives an error and perhaps you would compile it to see if it works. I think an LSMA indicator would be a great addition to Forex Tester, but my ignorance of Delphi prevents me from completing this project.

Thanks in advance for any help rendered :)

Code: Select all

library LSMA;

uses
  graphics, IndicatorInterfaceUnit;

var
  // external parameters
  period: integer;          // ?? period
  // index buffer
  bufLSMA: TIndexBuffer;

//---------------------------------------------------------------------------
// Initialization procedure
//---------------------------------------------------------------------------

procedure Init; stdcall;

begin
  // Define parameters
  IndicatorShortName('LSMA');
  SetOutputWindow(ow_ChartWindow);
  // register external parameters
  AddSeparator('Common');
  RegOption('Period', ot_Integer, period);
  SetOptionRange('Period', 1, MaxInt);
  period := 20;
  // Create index buffer
  IndicatorBuffers(1);
  LSMA := CreateIndexBuffer;
  SetIndexBuffer(0, LSMA);
  SetIndexStyle(0, 0, psSolid, 1, clBlue);
end;

//---------------------------------------------------------------------------
// Deinitialization procedure
//---------------------------------------------------------------------------

procedure Done; stdcall;

begin
  // do nothing
end;

//---------------------------------------------------------------------------

// Calculate single bar

//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;

var

  i: integer;
  sum: double;

begin
  sum := 0;
      for i := index + period - 1 downto index do
         begin
         sum := sum + (i - (period + 1) / 3) * Close(period - i);
         end;
      bufLSMA[index] := sum * 6 / (period * (period + 1));
end;

exports
Init, Done, Calculate;

end.

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#2 Postby david070o » Thu Apr 05, 2007 9:23 am

Nice to know you are working on it... I check and make some correction as below... but there is a minor defect on actual drawing in the chart...


library LSMA;

uses
graphics, IndicatorInterfaceUnit,
TechnicalFunctions in 'TechnicalFunctions.pas';

var
// external parameters
period: integer; // ?? period
// index buffer
bufLSMA: TIndexBuffer;

//---------------------------------------------------------------------------
// Initialization procedure
//---------------------------------------------------------------------------

procedure Init; stdcall;

begin
// Define parameters
IndicatorShortName('LSMA');
SetOutputWindow(ow_ChartWindow);
// register external parameters
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);
period := 20;
// Create index buffer
IndicatorBuffers(1);
bufLSMA := CreateIndexBuffer;// MADE CHANGES by david
SetIndexBuffer(0, bufLSMA);// MADE CHANGES by david
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);// MADE CHANGES by david
SetIndexLabel(0, 'LSMA');// MADE CHANGES by david
end;

//---------------------------------------------------------------------------
// Deinitialization procedure
//---------------------------------------------------------------------------

procedure Done; stdcall;

begin
// do nothing
end;

//---------------------------------------------------------------------------

// Calculate single bar

//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;

var

i: integer;
sum: double;

begin
sum := 0;
for i := index + period - 1 downto index do
begin
sum := sum + (i - (period + 1) / 3) * Close(period - i);
end;
bufLSMA[index] := sum * 6 / (period * (period + 1));
end;

exports
Init, Done, Calculate;

end.
Attachments
screen_00001.gif
screen_00001.gif (10.96 KiB) Viewed 26612 times

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#3 Postby david070o » Thu Apr 05, 2007 10:31 am

And is your formula LSMA... I don't know the formula for least square moving average (LSMA).

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#4 Postby Tantalus » Thu Apr 05, 2007 11:48 am

Great job, David, and thanks for making the changes!! It looks like it's working just fine apart from the drop to 0 in the current bar. I can't imagine why it's doing that... Maybe Mike or someone else knowledgeable about FT programming could suggest a remedy.

Yes, the formula is for LSMA - taken from an MT4 indicator I've been using for some time.

Would you be so kind as to post the compiled version so I can check it against my own results?

Thx!! :D

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#5 Postby david070o » Thu Apr 05, 2007 2:08 pm

you mean as dll File?
Attachments
LSMA.zip
(48.12 KiB) Downloaded 881 times

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#6 Postby Tantalus » Fri Apr 06, 2007 10:48 am

Yes, exactly... the DLL file...

Strangely, I find that doesn't work for me the same as it does in your software. It seems to give the proper curve for you up until the last data point, at which it drops down, presumably to 0. For me, all I get is a vertical line at the position of the most recent bar. I'm totally confused about this. Maybe I'll look over the code a little more, but I'm really pretty clueless about Delphi...

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#7 Postby david070o » Fri Apr 06, 2007 1:59 pm

why don't you post a picture... see if i can figure it out...did you try different color for the LSMA line and you have to restart it. I think it is just some silly things in programming.

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#8 Postby Tantalus » Fri Apr 06, 2007 5:09 pm

OK.. Here's the result on the USDJPY. I included an EMA to be sure that other indicators would work here.. The LSMA is set to draw in yellow - you can see that all it gives me is a vertical line at the current bar, drawn from the top to the bottom of the chart window.

Hope you can figure something out - I really think this would be cool if it could be made to work!!

Thx!
Attachments
LSMAnowork.gif
LSMAnowork.gif (58.84 KiB) Viewed 26579 times

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#9 Postby david070o » Sun Apr 08, 2007 10:33 am

Sorry... i could not figure it out. Let's go through basic trouble shooting...
1. You have my dll file so make sure you put it in indicator folder...not in the example/indicator folder.

2. restart your forextester or even restart your computer.

and try it again.

I don't mind giving you a call if you want to email me your phone# or something. my msn email is dd.mm.c@hotmail.com

alright good luck.

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#10 Postby Tantalus » Mon Apr 09, 2007 1:14 pm

OK, I double-checked the folder and it's correct, and I re-started it several times to no avail. Back to the drawing board, eh?

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#11 Postby Terranin » Mon Apr 09, 2007 9:20 pm

Guys, to install indicator you should not copy it somewhere and restart program. Just go to menu File -> Install new indicator and select this dll file. If it find old same indicator - it will delete it everywhere and install new one. Restarting of the program is not necessary.
Hasta la vista
Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#12 Postby Tantalus » Tue Apr 10, 2007 2:22 pm

Ok, thanks for the tip, Mike. I tried this procedure but the program said that the indicator was already installed... I guess that wasn't the problem...

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#13 Postby Terranin » Tue Apr 10, 2007 3:33 pm

Tantalus wrote:Ok, thanks for the tip, Mike. I tried this procedure but the program said that the indicator was already installed... I guess that wasn't the problem...


Yes, but program asks "install it anyway?" if yes - it will reinstall this indicator. (removes old copy of indicator from everywhere)
Hasta la vista

Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#14 Postby Tantalus » Tue Apr 10, 2007 4:20 pm

No, it said that it can't install, because it's already installed. It didn't offer me the option of reinstalling it...

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#15 Postby Terranin » Tue Apr 10, 2007 4:54 pm

Tantalus wrote:No, it said that it can't install, because it's already installed. It didn't offer me the option of reinstalling it...


See image
Attachments
img.png
img.png (7.8 KiB) Viewed 26501 times
Hasta la vista

Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#16 Postby Tantalus » Tue Apr 10, 2007 5:42 pm

This is what I see...
Attachments
cantinstall.gif
cantinstall.gif (5.46 KiB) Viewed 22915 times

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#17 Postby Terranin » Tue Apr 10, 2007 6:17 pm

Tantalus wrote:This is what I see...


Because you should not put it there manually, if you want to install new indicator install it from different folder.
Hasta la vista

Mike

david070o
Posts: 28
Joined: Mon Mar 19, 2007 8:13 pm

#18 Postby david070o » Fri Apr 13, 2007 1:04 am

Hey...
I believe you have to let the data run... as i just found out that our coding does not compute past data. So after you load it in testing mode. Let it run a bit and you will see.

IN picture, the blue dash line is the LSMA....

Good luck.
Attachments
screen_00057.gif
screen_00057.gif (18.8 KiB) Viewed 22891 times

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#19 Postby Tantalus » Fri Apr 13, 2007 9:45 am

Oh, I see... I was trying to use it in Edit mode.. When I try it in test mode I can see the correct line, although as you point out, it won't calculate values into the past.

Also, it doesn't give a correct value for the most recent bar, which would be the most useful one. I'm glad that the math is working, but we need to figure out how to get it to work correctly, both on past data and on the current bar.

Mike, would you consider tossing together some sort of tutorial to help us understand how to make an indicator like this one work? The info in the help file is the barest possible reference material and does next to nothing for newbies like me who don't understand the inner workings of FT. I'm not talking about a primer on Delphi coding, just the specifics of how to get a mathematical formula to calculate and display correctly in FT - an API tutorial. I know you're busy, but it would greatly increase the usefulness of your program (and therefore the interest it generates) if new users could quickly get up to speed on how to get their favorite indicators into the system...

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#20 Postby Terranin » Fri Apr 13, 2007 10:31 am

Tantalus wrote:Oh, I see... I was trying to use it in Edit mode.. When I try it in test mode I can see the correct line, although as you point out, it won't calculate values into the past.

Also, it doesn't give a correct value for the most recent bar, which would be the most useful one. I'm glad that the math is working, but we need to figure out how to get it to work correctly, both on past data and on the current bar.

Mike, would you consider tossing together some sort of tutorial to help us understand how to make an indicator like this one work? The info in the help file is the barest possible reference material and does next to nothing for newbies like me who don't understand the inner workings of FT. I'm not talking about a primer on Delphi coding, just the specifics of how to get a mathematical formula to calculate and display correctly in FT - an API tutorial. I know you're busy, but it would greatly increase the usefulness of your program (and therefore the interest it generates) if new users could quickly get up to speed on how to get their favorite indicators into the system...


Give me the source code of your indicator I will see where the problem is.
Hasta la vista

Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#21 Postby Tantalus » Fri Apr 13, 2007 12:53 pm

Terranin wrote:Give me the source code of your indicator I will see where the problem is.


I believe this is the latest source, as modified by david0o7:

Code: Select all

library LSMA;

uses
graphics, IndicatorInterfaceUnit,
TechnicalFunctions in 'TechnicalFunctions.pas';

var
// external parameters
period: integer; // ?? period
// index buffer
bufLSMA: TIndexBuffer;

//---------------------------------------------------------------------------
// Initialization procedure
//---------------------------------------------------------------------------

procedure Init; stdcall;

begin
// Define parameters
IndicatorShortName('LSMA');
SetOutputWindow(ow_ChartWindow);
// register external parameters
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);
period := 20;
// Create index buffer
IndicatorBuffers(1);
bufLSMA := CreateIndexBuffer;// MADE CHANGES by david
SetIndexBuffer(0, bufLSMA);// MADE CHANGES by david
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);// MADE CHANGES by david
SetIndexLabel(0, 'LSMA');// MADE CHANGES by david
end;

//---------------------------------------------------------------------------
// Deinitialization procedure
//---------------------------------------------------------------------------

procedure Done; stdcall;

begin
// do nothing
end;

//---------------------------------------------------------------------------

// Calculate single bar

//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;

var

i: integer;
sum: double;

begin
sum := 0;
for i := index + period - 1 downto index do
begin
sum := sum + (i - (period + 1) / 3) * Close(period - i);
end;
bufLSMA[index] := sum * 6 / (period * (period + 1));
end;

exports
Init, Done, Calculate;

end.

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#22 Postby Terranin » Fri Apr 13, 2007 1:16 pm

There is something wrong in the formula.

Code: Select all

sum := 0;
for i := index + period - 1 downto index do
  begin
    sum := sum + (i - (period + 1) / 3) * Close(period - i);
  end;
bufLSMA[index] := sum * 6 / (period * (period + 1));


Just imagine that index = 100 (back in history), so

sum := sum + (i - (period + 1) / 3) * Close(period - i);

i - (period + 1) ~ 100 - 10 = 90
and you are multiplying it on Close()! and get very high value that is unseen on the screen, and the farther you go back the bigger become numbers. On the 0 bar it is ok, and when you go bar by bar every time you calculate 0 bar, but when you are trying to calculate whole history you will have invalid results.
Hasta la vista

Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#23 Postby Tantalus » Fri Apr 13, 2007 2:39 pm

OK, here is the exact code which I use in MT4. This code works flawlessly:

Code: Select all

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Yellow     

double LSMA[];

extern int iPeriod = 14;

int k;   int g;   double sum;

int init()
{
   IndicatorBuffers(1);
   SetIndexBuffer(0, LSMA);
   SetIndexStyle(0, DRAW_LINE,STYLE_SOLID, 2);
   return(0);
}

int start()
{
   for(k = Bars - iPeriod - 1; k >= 0; k --)
   {
      sum = 0;
      for(g = iPeriod; g >= 1  ; g --)
         sum += (g - (iPeriod + 1) / 3) * Close[iPeriod - g + k];
      LSMA[k] = sum * 6 / (iPeriod * (iPeriod + 1));
   }
   return(0);
}


Based on a close comparison of this with the FT code, coupled with Mike's remarks, I now think the FT code should be this:

Code: Select all

library LSMA;

uses
graphics, IndicatorInterfaceUnit,
TechnicalFunctions in 'TechnicalFunctions.pas';

var
// external parameters
period: integer; // ?? period
// index buffer
bufLSMA: TIndexBuffer;

//---------------------------------------------------------------------------
// Initialization procedure
//---------------------------------------------------------------------------

procedure Init; stdcall;

begin
// Define parameters
IndicatorShortName('LSMA');
SetOutputWindow(ow_ChartWindow);
// register external parameters
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);
period := 20;
// Create index buffer
IndicatorBuffers(1);
bufLSMA := CreateIndexBuffer;// MADE CHANGES by david
SetIndexBuffer(0, bufLSMA);// MADE CHANGES by david
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);// MADE CHANGES by david
SetIndexLabel(0, 'LSMA');// MADE CHANGES by david
end;

//---------------------------------------------------------------------------
// Deinitialization procedure
//---------------------------------------------------------------------------

procedure Done; stdcall;

begin
// do nothing
end;

//---------------------------------------------------------------------------

// Calculate single bar

//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;

var

i: integer;
sum: double;

begin
sum := 0;
for i := period downto 1 do
  begin
    sum := sum + (i - (period + 1) / 3) * Close(period - i + index);
  end;
bufLSMA[index] := sum * 6 / (period * (period + 1));
end;

exports
Init, Done, Calculate;

end.


It's clear the the value of i must be local to this iteration (one time through for a given index) and so must be separated from the value of index. Only when the price is involved should the index value be used, just like in the MT4 code.

One thing which I've assumed is that FT indicator code should only deal with a single bar, whereas MT4 indicator code must be written to calculate all bars. This is why the MT4 code has two nested loops - the 'k' loop steps through all the data from the oldest (buffered a little to ensure that the first calculation has sufficient data to be valid) to the most recent bar. The 'g' loop steps through only those bars necessary for calculating the current bar. For the FT code, I've used only the inner loop - the 'i' loop, and I assume that FT will call this indicator code as many times as necessary, each time providing the next index in the data, until the entire chart has been calculated. If this assumption is not correct, you will have to make mods to the code to correct it.

Please give this new code a whirl and see if it's better!

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#24 Postby Terranin » Fri Apr 13, 2007 3:36 pm

Tantalus wrote:One thing which I've assumed is that FT indicator code should only deal with a single bar, whereas MT4 indicator code must be written to calculate all bars. This is why the MT4 code has two nested loops - the 'k' loop steps through all the data from the oldest (buffered a little to ensure that the first calculation has sufficient data to be valid) to the most recent bar. The 'g' loop steps through only those bars necessary for calculating the current bar. For the FT code, I've used only the inner loop - the 'i' loop, and I assume that FT will call this indicator code as many times as necessary, each time providing the next index in the data, until the entire chart has been calculated. If this assumption is not correct, you will have to make mods to the code to correct it.

Please give this new code a whirl and see if it's better!


You are correct. FT makes the loop over not calculated bars by itself, so you do not need to do dirty job. It just calls Calculate(index) where index is the bar index in correct order from old bars to 0.

When indicator are calculated on history FT just calls Calculate(0) when new tick arrives to recalculate last bar with index = 0.
Hasta la vista

Mike

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#25 Postby Tantalus » Sat Apr 14, 2007 1:47 pm

Thanks, Mike...

Could you or David try compiling this latest version for me? I'm still clueless about running the Delphi IDE...

Thx!


Return to “Indicators”

Who is online

Users browsing this forum: No registered users and 1 guest