I have been writing DLLs in FreePascal under Lazarus and thought someone might be interested in these MAs that I have ported from my MT4 code. The JMA is very fast in Pascal and runs through 1000 prices in less than a blink of an eye so makes it usable compared to the run time in an MT4 indicator. clp is a pointer to an array of close prices and I think the rest of the stuff is obvious.
Inserted Code
type
TBuffer = array[0..1000000] of Real;
PtPrice = ^TBuffer;
function TForm1.EMA(CurBar, Period: integer; clp: PtPrice): real;
var
prices: array of real;
i,j,arrlim,StBar: integer;
k,tmp: real;
begin
StBar := CurBar-Period+1;
if (StBar >0) then
begin
arrlim:=Period-1;
SetLength(prices,Period);
j:=0;
for i := StBar to CurBar do
begin
prices[j]:=clp^[i];
j:=j+1;
end;
k := 2 / (period + 1);
tmp := prices[0];
for i := 1 to arrlim do
tmp := tmp * (1 - k) + prices[i] * k;
for i := 1 to arrlim do
tmp := tmp * (1 - k) + prices[i] * k;
EMA:=tmp;
end
else EMA:=clp^[CurBar];
end;
function TForm1.SMA(CurBar, Period: integer; clp: PtPrice): real;
var
i,StBar: integer;
tmp: real;
begin
StBar := CurBar-Period+1;
if (StBar >0) and (Period>0) then
begin
tmp:=0;
for i := StBar to CurBar do
tmp := tmp + clp^[i];
SMA:=tmp/Period;
end
else SMA:=clp^[CurBar];
end;
function TForm1.JMA(Period, Phase, Index: integer; clp: PtPrice): real;
var
fD8,fF0,ii,jj,shift,value2: integer;
v5,v6,s28,s30,s38,s40,s48,s50,s58,s60,s68: integer;
vv,v1,v2,v3,v4,s8,s10,s18,s20,s70: Real;
f8,f10,f18,f20,f28,f30,f38,f40,f48,f50,f58,f60,f68,f70,f78,f80,f88,f90: Real;
f98,fA0,fA8,fB0,fB8,fC0,fC8,fD0,f0,fE0,fE8,fF8,Value: Real;
list,ring1: array[0..127] of Real;
ring2: array[0..10] of Real =(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
buffer: array[0..63] of Real;
begin
if Index>Period+barcnt then
begin
fF0:=0;
v5:=0; v6:=0; s38:=0; s40:=0; s48:=0; s50:=0; s58:=0; s60:=0; s68:=0;
vv:=0; v1:=0; v2:=0; v3:=0; v4:=0; s8:=0; s10:=0; s18:=0; s20:=0; s70:=0;
f8:=0; f10:=0; f18:=0; f20:=0; f28:=0; f30:=0; f38:=0; f40:=0; f48:=0; f50:=0; f58:=0; f60:=0; f68:=0;
f70:=0; f78:=0; f80:=0; f88:=0; f90:=0; f98:=0; fA0:=0; fA8:=0; fB0:=0; fB8:=0; fC0:=0; fC8:=0; fD0:=0;
f0:=0; fE0:=0; fE8:=0; fF8:=0;
//SetLoopCount(0);
for ii := 0 to 63 do
begin
ring1[ii] := 0.0;
ring1[ii+64] := 0.0;
buffer[ii]:=0.0;
end; // for ii
for shift:=Index-Period-barcnt To Index do
Begin
s28 := 63;
s30 := 64;
for ii := 0 to s28 do begin
list[ii] := -1000000.0;
end; // for ii
for ii := s30 to 127 do begin
list[ii] := 1000000.0;
end; //for ii
f0 := 1;
//{--------------------------------------------------------------------}
Value:=clp^[shift];
if (fF0 < 61) then begin
fF0:= fF0 + 1;
buffer[fF0] := Value;
end;
//{--------------------------------------------------------------------}
// { main cycle }
if (fF0 > 30) then begin
f80 := (Period - 1) / 2;
if (Phase < -100) then f10 := 0.5
else if (Phase > 100) then f10 := 2.5
else f10 := Phase / 100 + 1.5;
v1 := Ln(SqRt(f80));
v2 := v1;
if (v1 / Ln(2.0) + 2 < 0) then v3 := 0 else v3 := v2 / Ln(2.0) + 2;
f98 := v3;
if (0.5 <= f98 - 2) then f88 := f98 - 2 else f88 := 0.5;
f78 := SqRt(f80) * f98;
f90 := f78 / (f78 + 1);
f80 := f80 * 0.9;
f50 := f80 / (f80 + 2);
if (f0 <> 0) then begin
f0 := 0;
v5 := 0;
for ii := 1 to 29 do
if (buffer[ii+1] <> buffer[ii]) then v5 := 1;
fD8 := v5*30;
if (fD8 = 0) then f38 := Value else f38 := buffer[1];
f18 := f38;
if (fD8 > 29) then fD8 := 29;
end else
fD8 := 0;
for ii := fD8 downto 0 do begin //{ another bigcycle...}
value2:=31-ii;
if (ii = 0) then f8 := Value else f8 := buffer[value2];
f28 := f8 - f18;
f48 := f8 - f38;
if (Abs(f28) > Abs(f48)) then v2 := Abs(f28) else v2 := Abs(f48);
fA0 := v2;
vv := fA0;
if (s48 <= 1) then s48 := 127 else s48 := s48 - 1;
if (s50 <= 1) then s50 := 10 else s50 := s50 - 1;
if (s70 < 128) then s70 := s70 + 1;
s8 := s8 + vv - ring2[s50];
ring2[s50] := vv;
if (s70 > 10) then s20 := s8 / 10 else s20 := s8 / s70;
if (s70 > 127) then begin
s10 := ring1[s48];
ring1[s48] := s20;
s68 := 64; s58 := s68;
while (s68 > 1) do begin
if (list[s58] < s10) then begin
s68 := s68 >>1;
s58 := s58 + s68;
end else if (list[s58] <= s10) then begin
s68 := 1;
end else begin
s68 := s68 >>1;
s58 := s58 - s68;
end; // if list
end; // while
end else begin
ring1[s48] := s20;
if (s28 + s30 > 127) then begin
s30 := s30 - 1;
s58 := s30;
end else begin
s28 := s28 + 1;
s58 := s28;
end; // if s28
if (s28 > 96) then s38 := 96 else s38 := s28;
if (s30 < 32) then s40 := 32 else s40 := s30;
end; // if s70
s68 := 64;
s60 := s68;
while (s68 > 1) do begin
if (list[s60] >= s20) then begin
if (list[s60 - 1] <= s20) then begin
s68 := 1;
end else begin
s68 := s68 >>1;
s60 := s60 - s68;
end; // if s60-1
end else begin
s68 := s68 >>1;
s60 := s60 + s68;
end; // if s60 >=
if ((s60 = 127) and (s20 > list[127])) then s60 := 128;
end; // while s68
if (s70 > 127) then begin
if (s58 >= s60) then begin
if ((s38 + 1 > s60) and (s40 - 1 < s60)) then s18 := s18 + s20
else if ((s40 > s60) and (s40 - 1 < s58)) then s18 := s18 + list[s40 - 1];
end else if (s40 >= s60) then begin
if ((s38 + 1 < s60) and (s38 + 1 > s58)) then s18 := s18 + list[s38 + 1];
end else if (s38 + 2 > s60) then s18 := s18 + s20
else if ((s38 + 1 < s60) and (s38 + 1 > s58)) then s18 := s18 + list[s38 + 1];
if (s58 > s60) then begin
if ((s40 - 1 < s58) and (s38 + 1 > s58)) then s18 := s18 - list[s58] else
if ((s38 < s58) and (s38 + 1 > s60)) then s18 := s18 - list[s38];
end else begin
if ((s38 + 1 > s58) and (s40 - 1 < s58)) then s18 := s18 - list[s58]
else if ((s40 > s58) and (s40 < s60)) then s18 := s18 - list[s40];
end; // if s58
end; // if s70
if (s58 <= s60) then begin
if (s58 >= s60) then
list[s60] := s20
else begin
for jj := s58 + 1 to s60 - 1 do list[jj - 1] := list[jj];
list[s60 - 1] := s20;
end; // if s58 >=
end else begin
for jj := s58 - 1 downto s60 do list[jj + 1] := list[jj];
list[s60] := s20;
end; // if s58 <=
if (s70 <= 127) then begin
s18 := 0;
for jj := s40 to s38 do s18 := s18 + list[jj];
end; // if s70
f60 := s18 / (s38 - s40 + 1);
if (fF8 + 1 > 31) then fF8 := 31 else fF8 := fF8 + 1;
if (fF8 <= 30) then begin
if (f28 > 0) then f18 := f8 else f18 := f8 - f28 * f90;
if (f48 < 0) then f38 := f8 else f38 := f8 - f48 * f90;
fB8 := Value;
if (fF8 <> 30) then continue; // this will cause code to go back to the loop @ for ii bigcycle
// ie skips the rest of the code within the for-next
// only continues below if fF8=30...
if (fF8=30) then BEGIN
fC0 := Value;
if (round(f78+0.5) >= 1) then v4 := round(f78+0.5) else v4 := 1;
fE8 := round(v4+0.5);
if (round(f78-0.5) >= 1) then v2 := round(f78-0.5) else v2 := 1;
fE0 := round(v2-0.5);
if (fE8 = fE0) then
f68 := 1
else begin
v4 := fE8 - fE0;
f68 := (f78 - fE0) / v4;
end; // if fE8 =
if (fE0 <= 29) then v5 := round(fE0) else v5 := 29;
if (fE8 <= 29) then v6 := round(fE8) else v6 := 29;
fA8 := (Value - buffer[fF0 - v5]) * (1 - f68) / fE0 + (Value - buffer[fF0 - v6]) * f68 / fE8;
END; // if fF8 <=
end else begin
if (f98 >= power(fA0/f60, f88)) then v1 := power(fA0/f60, f88) else v1 := f98;
if (v1 < 1) then
v2 := 1
else begin
if (f98 >= power(fA0/f60, f88)) then v3 := power(fA0/f60, f88) else v3 := f98;
v2 := v3;
end; // if v1
f58 := v2;
f70 := power(f90, sqrt(f58));
if (f28 > 0) then f18 := f8 else f18 := f8 - f28 * f70;
if (f48 < 0) then f38 := f8 else f38 := f8 - f48 * f70;
end; // if fF8<
end; // for ii bigcycle
if (fF8 > 30) then begin
f30 := power(f50, f58);
fC0 := (1 - f30) * Value + f30 * fC0;
fC8 := (Value - fC0) * (1 - f50) + f50 * fC8;
fD0 := f10 * fC8 + fC0;
f20 := f30 * -2;
f40 := f30 * f30;
fB0 := f20 + f40 + 1;
fA8 := (fD0 - fB8) * fB0 + f40 * fA8;
fB8 := fB8 + fA8;
end;
JMA:= fB8;
end; // if fF0>30
if (fF0 <= 30) then JMA:=0.0;
end; // for shift (main cycle)
end
else JMA:=clp^[Index];
end;