MT5 Examples (Delphi 12 (2009) )

library dll_mql5;

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.

///////////////////////////////////////////////////////////////////////////////////////

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

//|                                                  Testing_DLL.mq5 |

//|                        Copyright 2009, MetaQuotes Software Corp. |

//|                                              http://www.mql5.com |

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

#property copyright "2009, MetaQuotes Software Corp."

#property link      "http://www.mql5.com"

#property version   "1.00"

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

//|                                                                  |

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

struct STRUCT_DATA

  {

   int               i;

   double            d;

   bool              b;

   datetime          dt;

  };

#import "dll_mql5.dll"

void MsgBox(void);

void MessageBox(void);//=void MsgBox(void);

string GetStringBuffer(void);

void SetString(string &a);

string SetParam(int &i,double d,bool b,datetime &dt);

string SetStruct(STRUCT_DATA &data);

string SetArray(int &arr[],int len);

string SetOptional(int &a,int b=0);

int DrawLRLine(double &rates,int len);

#import

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

void OnStart()

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

  {

   int i,len;

   double d;

   bool b;

   datetime dt;

   string s;

   STRUCT_DATA data;

   int arr[12];

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

// 1. Call of procedure

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

   MsgBox();

// If the names of the DLL functions coincide with the names of the MQL5 standard library functions,  

// when calling up a DLL function, it is vital to indicate the name of the DLL.   

   dll_mql5::MessageBox();

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

// 2.Working with simple data types

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

// initialization of variables

   i = 5;

   d = 2.8;

   b = true;

   dt= D'05.05.2010 08:31:27';

// calling the function

   s=SetParam(i,d,b,dt);

// output of result

   printf("%s i=%s d=%s b=%s dt=%s",s,IntegerToString(i),DoubleToString(d),b?"true":"false",TimeToString(dt));

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

// 3.Working with structure

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

   data.i = 5;

   data.d = 2.8;

   data.b = true;

   data.dt= D'05.05.2010 08:31:27';

   s=SetStruct(data);

   printf("%s i=%s d=%s b=%s dt=%s",s,IntegerToString(data.i),DoubleToString(data.d),

          data.b?"true":"false",TimeToString(data.dt));

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

// 4.Working with an array

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

   len=ArraySize(arr);

   s=SetArray(arr,len);

// output of result

   for(int i=0; i<len; i++)

      s=s+" "+IntegerToString(arr[i]);

   printf(s);

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

// 5.1.Working with a string using the Windows API style

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

// the string should be initialized before the use

// the buffer size should be greater or equal to the length of the string

   StringInit(s,255,0); 

// the string buffer is passed to DLL by reference

   SetString(s);

// output of result

   printf(s);

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

// 5.2.Working with a string. String buffer in DLL.

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

   s=GetStringBuffer();

   printf(s);

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

// 6.Working with default parameters

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

   i=1;

   s=SetOptional(i); // the second parameter is optional

   printf(s);

  }

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

////////////////////////////////////////////////////////////////////////////////////////

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

//|                                                   LR_Channel.mq5 |

//|                        Copyright 2009, MetaQuotes Software Corp. |

//|                                              http://www.mql5.com |

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

#property copyright "2009, MetaQuotes Software Corp."

#property link      "http://www.mql5.com"

#property version   "1.00"

#property indicator_chart_window

#include <Charts\Chart.mqh>

#include <ChartObjects\ChartObjectsChannels.mqh>

#import "dll_mql5.dll"

int CalcLRChannel(double &rates[][2],int len,double &A,double &B,double &max);

#import

input int period=75;

CChart               *chart;

CChartObjectChannel  *line_up,*line_dn,*line_md;

double                arr[][2]; //data array for processing in the ALGLIB format

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

int OnInit()

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

  {

   if((chart=new CChart)==NULL)

     {printf("Chart not created"); return(false);}

   chart.Attach();

   if(chart.ChartId()==0)

     {printf("Chart not opened");return(false);}

   if((line_up=new CChartObjectChannel)==NULL)

     {printf("Channel not created"); return(false);}

   if((line_dn=new CChartObjectChannel)==NULL)

     {printf("Channel not created"); return(false);}

   if((line_md=new CChartObjectChannel)==NULL)

     {printf("Channel not created"); return(false);}

   return(0);

  }

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

int OnCalculate(const int rates_total,

                const int prev_calculated,

                const datetime &time[],

                const double &open[],

                const double &high[],

                const double &low[],

                const double &close[],

                const long &tick_volume[],

                const long &volume[],

                const int &spread[])

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

  {

   double a,b, //Coefficients of the approximating line  

         max;  //maximum deviation from the approximating line 

               //is equal to half the width of the channel

   static double save_max;

   int len=period;  //number of points for calculation

   ArrayResize(arr,len);

// copying of history to a two-dimensional array

   int j=0;

   for(int i=rates_total-1; i>=rates_total-len; i--)

     {

      arr[j][0] = j;

      arr[j][1] = close[i];

      j++;

     }

// channel parameters calculation

   CalcLRChannel(arr,len,a,b,max);

// if the width of the channel has changed

   if(max!=save_max)

     {

      save_max=max;

      // Delete the channel

      line_md.Delete();

      line_up.Delete();

      line_dn.Delete();

      // Creating a channel with new coordinates

      line_md.Create(chart.ChartId(), "LR_Md_Line", 0, time[rates_total-1],       a, time[rates_total-len], a + b*(len-1)       );

      line_up.Create(chart.ChartId(), "LR_Up_Line", 0, time[rates_total-1], a + max, time[rates_total-len], a + b*(len-1) + max );

      line_dn.Create(chart.ChartId(), "LR_Dn_Line", 0, time[rates_total-1], a - max, time[rates_total-len], a + b*(len-1) - max );

      // Assigning the color of channel lines

      line_up.Color(RoyalBlue);

      line_dn.Color(RoyalBlue);

      line_md.Color(RoyalBlue);

      // Assigning the line width

      line_up.Width(2);

      line_dn.Width(2);

      line_md.Width(2);

     }

   return(len);

  }

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

void OnDeinit(const int reason)

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

  {

// Deleting the created objects

   chart.Detach();

   delete line_dn;

   delete line_up;

   delete line_md;

   delete chart;

  }

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