I managed to port the regression indicator. The syntax was very unfamiliar to me at first but it is so logical and structured that it took no time at all to figure it out.
I performed a rudimentary benchmark on the execution speed (during backtest) and found a 64% increase with the Lazarus dll as opposed to iCustom()!!
7bit, I followed the instructions you gave on changing the compiler options to produce a smaller .dll file. What I am interested in is not necessarily small size, but fast execution speed.
Are there any other compiler settings I should know about to produce a faster-computing .dll file?
I am quite impressed with the speed increase as it is, but of course I thirst for more!
.. a question:
I realize that MT4 won't integrate with a 64bit dll, but can't I make a 32bit dll act as a middle man to pass data between MT4 and the 64bit dll? Then I could possibly squeeze out more processing power.
Also, how does processor parallelization play in? I know a single instance of MT4 can only use 1 processor core; can this limitation be avoided with free pascal?
If anyone is interested, here is the i-Regr port to free pascal that I made. It returns the current bar's regression, the last bar's regression, and the standard deviation coefficient, by reference to the array "vars." Any tips to speed it up would be greatly appreciated!![](https://resources.faireconomy.media/images/emojis/64/1f60a.png?v=15.1)
Lazarus code:
MQL4 code:
I performed a rudimentary benchmark on the execution speed (during backtest) and found a 64% increase with the Lazarus dll as opposed to iCustom()!!
7bit, I followed the instructions you gave on changing the compiler options to produce a smaller .dll file. What I am interested in is not necessarily small size, but fast execution speed.
Are there any other compiler settings I should know about to produce a faster-computing .dll file?
I am quite impressed with the speed increase as it is, but of course I thirst for more!
.. a question:
I realize that MT4 won't integrate with a 64bit dll, but can't I make a 32bit dll act as a middle man to pass data between MT4 and the 64bit dll? Then I could possibly squeeze out more processing power.
Also, how does processor parallelization play in? I know a single instance of MT4 can only use 1 processor core; can this limitation be avoided with free pascal?
If anyone is interested, here is the i-Regr port to free pascal that I made. It returns the current bar's regression, the last bar's regression, and the standard deviation coefficient, by reference to the array "vars." Any tips to speed it up would be greatly appreciated!
![](https://resources.faireconomy.media/images/emojis/64/1f60a.png?v=15.1)
Lazarus code:
Inserted Code
library regression; Uses Math; {$mode objfpc}{$H+} type TCandle = packed record time: LongInt; // POSIX timestamp open, high, low, close, volume: Double; end; THistory = array[0..MaxLongInt div SizeOf(TCandle) - 1] of TCandle; PHistory = ^THistory; TBuffer = array[0..MaxLongInt div SizeOf(Double) - 1] of Double; PBuffer = ^TBuffer; TVal = array[0..2] of Double; PVal = ^TVal; var i0: LongInt = 0; const EMPTY_VALUE = $7FFFFFFF; function regression(history: PHistory; period: LongInt; degree: LongInt; index: LongInt; var vals: PVal): Double; var sum: Double; i: LongInt; ai: array[0..9,0..9] of double; b: array[0..9] of double; x: array[0..9] of double; sx: array[0..19] of double; ip: LongInt; p: LongInt; n: LongInt; f: LongInt; ii: LongInt; jj: LongInt; kk: LongInt; ll: LongInt; nn: LongInt; sq: Double; qq: Double; mm: Double; tt: Double; mi: LongInt; fx: array of Double; begin if index < period then exit(EMPTY_VALUE); if period < 1 then exit(history^[index].Close); sum := 0; ip:=period; p:=ip; sx[1] :=p+1; nn := degree+1; SetLength(fx,p+1); mi := 1; for mi:=1 to nn*2-2 do begin sum:=0; for n:=i0 to i0+p do begin sum := sum+ power(n,mi); end; sx[mi+1]:=sum; end; for mi:=1 to nn do begin sum:=0.00000; for n:=i0 to i0+p do begin if (mi = 1) then sum:= sum+ history^[index-n].Close else sum:= sum+ (history^[index-n].Close * power(n,mi-1)); end; b[mi]:=sum; end; for jj:=1 to nn do begin for ii:=1 to nn do begin kk:=ii+jj-1; ai[ii,jj]:=sx[kk]; end end; for kk:=1 to nn-1 do begin ll:=0; mm:=0; for ii:=kk to nn do begin if (Abs(ai[ii,kk])>mm) then begin mm:=Abs(ai[ii,kk]); ll:=ii; end; end; if ll=0 then exit(EMPTY_VALUE) else begin if ll<>kk then begin for jj:=1 to nn do begin tt:=ai[kk,jj]; ai[kk,jj]:=ai[ll,jj]; ai[ll,jj]:=tt; end; tt:=b[kk]; b[kk]:=b[ll]; b[ll]:=tt; end; end; for ii:=kk+1 to nn do begin qq:=ai[ii,kk]/ai[kk,kk]; for jj:=1 to nn do begin if jj=kk then ai[ii,jj]:=0 else ai[ii,jj]:=ai[ii,jj]-qq*ai[kk,jj]; end; b[ii]:=b[ii]-qq*b[kk]; end; end; x[nn]:=b[nn]/ai[nn,nn]; for ii:=nn-1 Downto 1 do begin tt:=0; for jj:=1 to nn-ii do begin tt:=tt+ai[ii,ii+jj]*x[ii+jj]; x[ii]:=(1/ai[ii,ii])*(b[ii]-tt); end; end; for n:=i0 to i0+p do begin sum:=0; for kk:=1 to degree do begin sum:=sum+x[kk+1]*power(n,kk); end; fx[n]:=x[1]+sum; end; sq:=0.0; for n:=i0 to i0+p do begin sq:=sq+power(history^[index-n].Close-fx[n],2); end; sq:=sqrt(sq/(p+1)); vals^[0] := fx[0]; vals^[1] := fx[1]; vals^[2] :=sq; end; procedure updateBuffer(history: PHistory; bars: LongInt; degree: LongInt; period: LongInt; vals: PVal); stdcall; begin regression(history, period, degree, bars-1, vals); end; exports updateBuffer; begin end.
MQL4 code:
Inserted Code
#property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 Red #property indicator_color2 Red #property indicator_color3 Red #import "regression.dll" void updateBuffer(double &history[][6],int bars, int degree, int period, double &vals[3]); #import extern int period=40; extern double kstd =1; extern int degree = 1; double buffer[]; double up[]; double dn[]; double history[][6]; // this will later point to the complete chart history int init(){ // set up the indicator buffer SetIndexStyle(0, DRAW_LINE); SetIndexBuffer(0, buffer); SetIndexLabel(0, "Regression"); SetIndexStyle(1, DRAW_LINE); SetIndexBuffer(1, up); SetIndexLabel(1, "Regression + STD"); SetIndexStyle(2, DRAW_LINE); SetIndexBuffer(2, dn); SetIndexLabel(2, "Regression - STD"); ArrayCopyRates(history, NULL, 0); } int start(){ double vals[3]; updateBuffer(history, Bars, degree, period, vals); //populate array "vals" with regression values. buffer[0] = vals[0]; //vals[0] is regression's value at current bar up[0] = vals[0]+(vals[2]*kstd); //vals[1] is regression's value at last bar dn[0] = vals[0]-(vals[2]*kstd); //vals[2] is the standard deviation value prior to multiplication by kstd (raw std value) }
Attached File(s)