Change indicator color when rising or falling

How to create strategies and indicators
Message
Author
swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

Change indicator color when rising or falling

#1 Postby swannyfx » Fri May 20, 2011 8:38 am

Hi,

I'd like to modify the color of the HMA indicator so that its blue when the HMA is increasing and red when it's decreasing. I know how to change the color of the indicator using SetIndexStyle but this changes the entire indicator line, how would I get it to switch between two colors based on direction?

HMA code is below. Any input is greatly appreciated.

Thanks,
Swanny.


//---------------------------------------------------------------------------
// Hull Moving average indicator
//---------------------------------------------------------------------------
library HMA;

uses
graphics,
IndicatorInterfaceUnit,
TechnicalFunctions;

var
// External variables
period: integer = 8;

// Buffers
WMA1, WMA2, WMADiff, iHMA: TIndexBuffer;


//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
procedure Init; stdcall;
begin
// define properties
IndicatorShortName('Hull Moving average');
SetOutputWindow(ow_ChartWindow);
SetEmptyValue(0);

// register options
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);

// create buffers
WMA1 := CreateIndexBuffer;
WMA2 := CreateIndexBuffer;
WMADiff := CreateIndexBuffer;
iHMA := CreateIndexBuffer;

IndicatorBuffers(1);
SetIndexBuffer(0, iHMA);
SetIndexStyle(0, ds_Line, psSolid, 1, clYellow);
SetIndexLabel(0, 'HMA');
end;

//---------------------------------------------------------------------------
// Calculate WMA
//---------------------------------------------------------------------------
function WMA(per: integer; index: integer): double;
var
sum: double;
weight: integer;
i: integer;
begin
sum := 0;
weight := 0;
for i:=0 to per - 1 do
begin
sum := sum + Close(index + i) * (per - i);
weight := weight + (per - i);
end;
result := sum / weight;
end;

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;
var
halfperiod: integer;
sqrtperiod: integer;
sum: double;
weight: integer;
i: integer;

begin
if index + period >= Bars then
exit;

halfperiod := Trunc(period / 2);
sqrtperiod := Trunc(Sqrt(period));

WMA1[index] := WMA(halfperiod, index) * 2;
WMA2[index] := WMA(period, index);
WMADiff[index] := WMA1[index] - WMA2[index];

sum := 0;
weight := 0;
for i:=0 to sqrtperiod - 1 do
begin
sum := sum + WMADiff[index + i] * (sqrtperiod - i);
weight := weight + (sqrtperiod - i);
end;
iHMA[index] := sum / weight;
end;

exports

Init, Calculate;

end.

FT Support
Posts: 905
Joined: Sat Jul 11, 2009 10:54 am

#2 Postby FT Support » Mon May 23, 2011 4:07 am

Hello Swanny,

you need to have 2 index buffers, one of them should be red and one of them should be blue.
Then when you populate these buffers with values you need to choose the proper buffer depending on the color which you want to see on the chart.
Check our other product here:
http://www.forexcopier.com

swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

#3 Postby swannyfx » Mon May 23, 2011 5:51 am

Hi FT,

Thanks for the info. I've modified the code, as shown below, and it compiles successfully but when I try to import it into ForexTester, I get the error message 'Cannot install indicator, it will be deleted. Have error: Can not get 'ReplaceStr' proc address'.

I assume there is an error with my code but am not sure what it is. Have I done something wrong in my code (I've marked my modifications with //****** to make the lines easier to identify)?

Thanks,
Swanny.


//---------------------------------------------------------------------------
// Hull Moving average indicator
//---------------------------------------------------------------------------
library HMAColor;

uses
graphics,
IndicatorInterfaceUnit,
TechnicalFunctions;

var
// External variables
period: integer = 21;

// Buffers
WMA1, WMA2, WMADiff, iHMA, HMA1, HMA2: TIndexBuffer; //******


//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
procedure Init; stdcall;
begin
// define properties
IndicatorShortName('Hull Moving average');
SetOutputWindow(ow_ChartWindow);
SetEmptyValue(0);

// register options
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);

// create buffers
WMA1 := CreateIndexBuffer;
WMA2 := CreateIndexBuffer;
WMADiff := CreateIndexBuffer;
iHMA := CreateIndexBuffer;
HMA1 := CreateIndexBuffer; //******
HMA2 := CreateIndexBuffer; //******

IndicatorBuffers(2); //******
SetIndexBuffer(0, HMA1); //******
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);
//******
SetIndexBuffer(1, HMA2); //******
SetIndexStyle(1, ds_Line, psSolid, 1, clRed); //******

end;

//---------------------------------------------------------------------------
// Calculate WMA
//---------------------------------------------------------------------------
function WMA(per: integer; index: integer): double;
var
sum: double;
weight: integer;
i: integer;
begin
sum := 0;
weight := 0;
for i:=0 to per - 1 do
begin
sum := sum + Close(index + i) * (per - i);
weight := weight + (per - i);
end;
result := sum / weight;
end;

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;
var
halfperiod: integer;
sqrtperiod: integer;
sum: double;
weight: integer;
i: integer;

begin
if index + period >= Bars then
exit;

halfperiod := Trunc(period / 2);
sqrtperiod := Trunc(Sqrt(period));

WMA1[index] := WMA(halfperiod, index) * 2;
WMA2[index] := WMA(period, index);
WMADiff[index] := WMA1[index] - WMA2[index];

sum := 0;
weight := 0;
for i:=0 to sqrtperiod - 1 do
begin
sum := sum + WMADiff[index + i] * (sqrtperiod - i);
weight := weight + (sqrtperiod - i);
end;

HMA1[index] := sum / weight; //******
HMA2[index] := sum / weight; //******

if HMA1[index] >= HMA1[index-1] then iHMA[index] := HMA1[index]; //******
if HMA1[index] < HMA1[index-1] then iHMA[index] := HMA2[index]; //******

end;

exports

Init, Calculate;

end.

FT Support
Posts: 905
Joined: Sat Jul 11, 2009 10:54 am

#4 Postby FT Support » Mon May 23, 2011 6:37 am

Hello,

Please try to replace your API with attached libs
Attachments
DelphiAPI.zip
(10.05 KiB) Downloaded 1086 times
Check our other product here:
http://www.forexcopier.com

swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

#5 Postby swannyfx » Mon May 23, 2011 7:40 am

Thanks, compiling with those libs fixed the indicator install issue.

I'm still having a problem switching between the buffers though. I've configured two buffers with different colors and populated them with the same values, but the indicator only displays one color. I think the issue is with the code I'm using to switch between buffers (excerpt from previous post):


HMA1[index] := sum / weight; //blue HMA
HMA2[index] := sum / weight; //red HMA

if HMA1[index] >= HMA1[index-1] then
iHMA[index] := HMA1[index]
else
iHMA[index] := HMA2[index];


Is there an issue with this code or could the problem be elsewhere? (The rest of the code is in my previous post if you need to reference).

Any help is much appreciated.

Thanks,
Swanny.

swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

#6 Postby swannyfx » Wed May 25, 2011 1:44 am

Hi, I'm still having issues switching between the two IndexBuffers, does anyone know how to do this?

Thanks,
Swanny.

FT Support
Posts: 905
Joined: Sat Jul 11, 2009 10:54 am

#7 Postby FT Support » Thu May 26, 2011 4:36 am

Hello Swanny,

Please try something like this:

Code: Select all


var newValue, previousValue: double;

....

newValue := sum / weight;

if (HMA1[index-1] <> 0) then
previousValue := HMA1[index-1]
else
previousValue := HMA2[index-1];

if newValue  >= previousValue then
HMA1[index] := newValue //blue HMA
else
HMA2[index] := newValue; //red HMA

Check our other product here:
http://www.forexcopier.com

swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

#8 Postby swannyfx » Fri May 27, 2011 9:07 pm

Thanks, I never thought of doing it that way. Unfortunately though, it still displays only one IndexBuffer.

I ran through the code logic on a piece of paper and have a question about the line:

if (HMA1[index-1] <> 0) then

If the HMA is lower than the previous bar, the HMA2 buffer (red/down) would be written with the new value, but HMA1 (blue/up) would be blank. In this case, wouldn't HMA1 be Null rather than 0? How would the code react to the if statement when the value is blank? I've tried adding Null to my code instead of 0 but it crashes FT when I try to apply the indicator to a chart.

Here is the code so far:

//---------------------------------------------------------------------------
// Hull Moving average indicator
//---------------------------------------------------------------------------
library HMAColor;

uses
graphics,
IndicatorInterfaceUnit,
TechnicalFunctions;

var
// External variables
period: integer = 21;

// Buffers
WMA1, WMA2, WMADiff, HMA1, HMA2: TIndexBuffer;
newValue, previousValue: double;


//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
procedure Init; stdcall;
begin
// define properties
IndicatorShortName('HMA Colored');
SetOutputWindow(ow_ChartWindow);
SetEmptyValue(0);

// register options
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);

// create buffers
WMA1 := CreateIndexBuffer;
WMA2 := CreateIndexBuffer;
WMADiff := CreateIndexBuffer;
HMA1 := CreateIndexBuffer;
HMA2 := CreateIndexBuffer;

IndicatorBuffers(2);
SetIndexBuffer(0, HMA1);
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);
SetIndexLabel(0, 'HMA up');

SetIndexBuffer(1, HMA2);
SetIndexStyle(1, ds_Line, psSolid, 1, clRed);
SetIndexLabel(1, 'HMA down');

end;

//---------------------------------------------------------------------------
// Calculate WMA
//---------------------------------------------------------------------------
function WMA(per: integer; index: integer): double;
var
sum: double;
weight: integer;
i: integer;
begin
sum := 0;
weight := 0;
for i:=0 to per - 1 do
begin
sum := sum + Close(index + i) * (per - i);
weight := weight + (per - i);
end;
result := sum / weight;
end;

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;
var
halfperiod: integer;
sqrtperiod: integer;
sum: double;
weight: integer;
i: integer;

begin
if index + period >= Bars then
exit;

halfperiod := Trunc(period / 2);
sqrtperiod := Trunc(Sqrt(period));

WMA1[index] := WMA(halfperiod, index) * 2;
WMA2[index] := WMA(period, index);
WMADiff[index] := WMA1[index] - WMA2[index];

sum := 0;
weight := 0;
for i:=0 to sqrtperiod - 1 do
begin
sum := sum + WMADiff[index + i] * (sqrtperiod - i);
weight := weight + (sqrtperiod - i);
end;

newValue := sum / weight;

if (HMA1[index-1] <> 0) then
previousValue := HMA1[index-1]
else
previousValue := HMA2[index-1];

if newValue >= previousValue then
HMA1[index] := newValue //blue HMA
else
HMA2[index] := newValue; //red HMA

end;

exports

Init, Calculate;

end.


Thanks,
Swanny.

swannyfx
Posts: 35
Joined: Fri Jun 18, 2010 12:35 am

#9 Postby swannyfx » Sat May 28, 2011 12:12 am

I figured it out, had the bar numbering the wrong way. Here's the final code:

//---------------------------------------------------------------------------
// Hull Moving average indicator
//---------------------------------------------------------------------------
library HMAColor;

uses
graphics,
IndicatorInterfaceUnit,
TechnicalFunctions;

var
// External variables
period: integer = 21;

// Buffers
WMA1, WMA2, WMADiff, HMA1, HMA2: TIndexBuffer;
newValue, previousValue: double;


//---------------------------------------------------------------------------
// Initialize indicator
//---------------------------------------------------------------------------
procedure Init; stdcall;
begin
// define properties
IndicatorShortName('HMA Colored');
SetOutputWindow(ow_ChartWindow);
SetEmptyValue(0);

// register options
AddSeparator('Common');
RegOption('Period', ot_Integer, period);
SetOptionRange('Period', 1, MaxInt);

// create buffers
WMA1 := CreateIndexBuffer;
WMA2 := CreateIndexBuffer;
WMADiff := CreateIndexBuffer;
HMA1 := CreateIndexBuffer;
HMA2 := CreateIndexBuffer;

IndicatorBuffers(2);
SetIndexBuffer(0, HMA1);
SetIndexStyle(0, ds_Line, psSolid, 1, clBlue);
SetIndexLabel(0, 'HMA up');

SetIndexBuffer(1, HMA2);
SetIndexStyle(1, ds_Line, psSolid, 1, clRed);
SetIndexLabel(1, 'HMA down');

end;

//---------------------------------------------------------------------------
// Calculate WMA
//---------------------------------------------------------------------------
function WMA(per: integer; index: integer): double;
var
sum: double;
weight: integer;
i: integer;
begin
sum := 0;
weight := 0;
for i:=0 to per - 1 do
begin
sum := sum + Close(index + i) * (per - i);
weight := weight + (per - i);
end;
result := sum / weight;
end;

//---------------------------------------------------------------------------
// Calculate requested bar
//---------------------------------------------------------------------------
procedure Calculate(index: integer); stdcall;
var
halfperiod: integer;
sqrtperiod: integer;
sum: double;
weight: integer;
i: integer;

begin
if index + period >= Bars then
exit;

halfperiod := Trunc(period / 2);
sqrtperiod := Trunc(Sqrt(period));

WMA1[index] := WMA(halfperiod, index) * 2;
WMA2[index] := WMA(period, index);
WMADiff[index] := WMA1[index] - WMA2[index];

sum := 0;
weight := 0;
for i:=0 to sqrtperiod - 1 do
begin
sum := sum + WMADiff[index + i] * (sqrtperiod - i);
weight := weight + (sqrtperiod - i);
end;

newValue := sum / weight;

if (HMA1[index+1] <> 0) then
previousValue := HMA1[index+1]
else
previousValue := HMA2[index+1];

if newValue >= previousValue then
HMA1[index] := newValue //blue HMA
else
HMA2[index] := newValue; //red HMA

end;

exports

Init, Calculate;

end.


Thanks for your help,
Swanny.

christoff
Posts: 46
Joined: Thu Nov 09, 2006 2:29 am

Have error: Can not get 'ReplaceStr' proc address'

#10 Postby christoff » Fri Aug 12, 2011 1:54 am

FT Support wrote:Hello,

Please try to replace your API with attached libs


Hi

I also get this error when I try to import my custom indicator into ForexTester.

I get the error message 'Cannot install indicator, it will be deleted. Have error: Can not get 'ReplaceStr' proc address'.

I did replace my API with attached libs by copying the 2 files into c:\lazarus\projects. But I still gets the same error.

I don't know if I have to copy the files into FT2 as well and if so where.

Please help

Christoff

Thank you but I solved the problem by using the suggestions in this post:
http://forextester.com/forum/viewtopic. ... highlight=

christoff
Posts: 46
Joined: Thu Nov 09, 2006 2:29 am

#11 Postby christoff » Tue Aug 16, 2011 12:54 am

Hi Swanny,

I took you code for the HMA that you made available in this post and change it to cater for all the different MA type because I was looking for EMA that will change color on slope change.

there is just one problem and it is that the indi leaves blank spaces in between the color changes.

I currently bypass this problem by just 1st loading a normal EMA and then on top of that I load the color change one.

Maybe someone out there know how to fix it inside the MA_Color indi so that we don't need to overlay 2 MA's.

Regards,
Christoff
Attachments
MovingAverageColor.zip
(1.78 MiB) Downloaded 1057 times

FT Support
Posts: 905
Joined: Sat Jul 11, 2009 10:54 am

#12 Postby FT Support » Tue Aug 16, 2011 7:58 am

Hello,

Pelase try to add one more point to one of the buffers that you use for changing MA colors.

blank spaces appear when you stop showing one buffer at some point let's say index=n and then show next buffer from index=n+1 point. so to fix the problem you need to stop showing first buffer at index=n+1 or start showing next buffer at index=n
Check our other product here:
http://www.forexcopier.com

christoff
Posts: 46
Joined: Thu Nov 09, 2006 2:29 am

#13 Postby christoff » Wed Aug 17, 2011 3:11 am

Thanks,

dackjaniels (he said the same thing as you) was so kind to fix the problem and posted the updated indicator here:

http://www.forextester.com/forum/viewtopic.php?t=2607

Regards,
Christoff

sneakers
Posts: 1
Joined: Thu Mar 15, 2012 5:45 pm

#14 Postby sneakers » Thu Mar 15, 2012 5:57 pm

I will be interested to network via skype with anyone using Forex Tester to test the Hull Moving Average. Contact me by private message for skype user name.


Return to “FT API”

Who is online

Users browsing this forum: No registered users and 9 guests