MQL5 Delphi_dll

library dll_mql5;

{ Important note about DLL memory management: ShareMem must be the

  first unit in your library's USES clause AND your project's (select

  Project-View Source) USES clause if your DLL exports any procedures or

  functions that pass strings as parameters or function results. This

  applies to all strings passed to and from your DLL--even those that

  are nested in records and classes. ShareMem is the interface unit to

  the BORLNDMM.DLL shared memory manager, which must be deployed along

  with your DLL. To avoid using BORLNDMM.DLL, pass string information

  using PChar or ShortString parameters. }

uses

  Math,

  Windows,  // it needed for the MessageBox function

  Dialogs,  // it needed for the ShowMessage function from the Dialogs unit

  SysUtils, // the UnixDateDelta constant from there

  DateUtils, // the IncSecon and DateTimeToUnix functions are used

  Graphics,

  ap in 'src\ap.pas',

  ablasf in 'src\ablasf.pas',

  ablas in 'src\ablas.pas',

  blas in 'src\blas.pas',

  bdsvd in 'src\bdsvd.pas',

  svd in 'src\svd.pas',

  creflections in 'src\creflections.pas',

  descriptivestatistics in 'src\descriptivestatistics.pas',

  gammafunc in 'src\gammafunc.pas',

  hblas in 'src\hblas.pas',

  igammaf in 'src\igammaf.pas',

  linreg in 'src\linreg.pas',

  normaldistr in 'src\normaldistr.pas',

  ortfac in 'src\ortfac.pas',

  reflections in 'src\reflections.pas',

  rotations in 'src\rotations.pas',

  sblas in 'src\sblas.pas';

{$R *.res}

//----------------------------------------------------------+

//

//----------------------------------------------------------+

type

  DoubleArray = array[0..2047, 0..1] of double;

  StructData = packed record

    i: Integer;

    d: Double;

    b: Boolean;

    dt:Int64;

  end;

var   Buffer: PWideChar;

      StrGlobal: WideString;

const BUFFER_SIZE = 255;

//------------------------------------------------------+

// to prevent errors, use the stdcall (or cdecl) for the exported functions

//------------------------------------------------------+

procedure MsgBox(); stdcall;

begin

    {1} MessageBox(0,'Hello World!','terminal', MB_OK);

    {2} ShowMessage('Hello World!'); // alternative to the MessageBox function

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

Function MQL5_Time_To_TDateTime(dt: Int64): TDateTime;

begin

      Result:= IncSecond(UnixDateDelta, dt);

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

Function TDateTime_To_MQL5_Time(dt: TDateTime):Int64;

begin

      Result:= DateTimeToUnix(dt);

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function SetParam(var i: Integer; d: Double; const b: Boolean;

                  var dt: Int64): PWideChar; stdcall;

begin

  if (b) then d:=0;                   // the value of the variable d is not changed in the calling program

  i:= 10;                             // assign a new value for i

  dt:= TDateTime_To_MQL5_Time(Now()); // assign the current time for dt

  Result:= 'The values of variables i and dt are changed';

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function SetStruct(var data: StructData): PWideChar; stdcall;

begin

  if (data.b) then data.d:=0;

  data.i:= 10; // assign a new value for i

  data.dt:= TDateTime_To_MQL5_Time(Now()); // assign the current time for dt

  Result:= 'The values of variables i, d and dt are changed';

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function SetArray(var arr: IntegerArray; const len: Cardinal): PWideChar; stdcall;

var i:Integer;

begin

  Result:='Fibonacci numbers:';

  if (len < 3) then exit;

  arr[0]:= 0;

  arr[1]:= 1;

  for i := 2 to len-1 do

    arr[i]:= arr[i-1] + arr[i-2];

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function SetOptional(var a:Integer; b:Integer=0):PWideChar; stdcall;

begin

    if (b=0) then Result:='Call with default parameters'

    else          Result:='Call without default parameters';

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

procedure SetString(const str:PWideChar) stdcall;

begin

  StrCat(str,'Current time:');

  strCat(str, PWideChar(TimeToStr(Now)));

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function GetStringBuffer():PWideChar; stdcall;

var StrLocal: WideString;

begin

     // working through the dynamically allocated memory buffer

     StrPCopy(Buffer, WideFormat('Current date and time: %s', [DateTimeToStr(Now)]));

     // working through the global varialble of WideString type

     StrGlobal:=WideFormat('Current time: %s', [TimeToStr(Time)]);

     // working through the local varialble of WideString type

     StrLocal:= WideFormat('Current date: %s', [DateToStr(Date)]);

{A}  Result := Buffer;

{B}  Result := PWideChar(StrGlobal);

     // it's equal to the following

     Result := @StrGlobal[1];

{Ñ}  Result := 'Return of the line stored in the code section';

     // memory pointer, that can be released when exit from the function

{D}  Result := @StrLocal[1];

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

function CalcLRChannel(var rates: DoubleArray; const len: Integer;

                    var A, B, max: Double):Integer; stdcall;

var arr: TReal2DArray;

    info: Integer;

    value: Double;

begin

    SetLength(arr,len,2);

    // copying data to two-dimensional array

    for info:= 0 to len - 1 do

    begin

      arr[info,0]:= rates[info,0];

      arr[info,1]:= rates[info,1];

    end;

    // calculation of linear regression coefficients

    LRLine(arr, len, info, A,  B);

    // find the maximal deviation from the approximation line found

    // and determine the channel width

    max:= rates[0,1] - A;

    for info := 1 to len - 1 do

    begin

      value:= Abs(rates[info,1]- (A + B*info));

      if (value > max) then max := value;

    end;

    Result:=0;

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

exports

      CalcLRChannel,

      GetStringBuffer,

      SetString,

      SetOptional,

      SetArray,

      SetStruct,

      SetParam,

  {A} MsgBox,

  {B} MsgBox name 'MessageBox';// rename of the exported function

//----------------------------------------------------------+

//

//----------------------------------------------------------+

procedure DLLEntryPoint(dwReason: DWord); // events handler

begin

    case dwReason of

      DLL_PROCESS_ATTACH: // DLL attached to the process;

          // allocate memory

          Buffer:=AllocMem(BUFFER_SIZE);

      DLL_PROCESS_DETACH: // DLL detached from the process;

          // release memory

          FreeMem(Buffer);

    end;

end;

//----------------------------------------------------------+

//

//----------------------------------------------------------+

begin

    DllProc := @DLLEntryPoint; //Assign event handler

    DLLEntryPoint(DLL_PROCESS_ATTACH);

end.