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;