English Русский 中文 Español Deutsch Português 한국어 Français Italiano Türkçe
DelphiでDLLをMQL5向けに書くためのガイド

DelphiでDLLをMQL5向けに書くためのガイド

MetaTrader 5 | 6 10月 2015, 12:25
934 0
Andriy Voitenko
Andriy Voitenko

はじめに

Delphi 2009の開発環境による例を使用しながらDLLを書くメカニズムを考察していきます。バージョンは、MQL5において全てのコード行はユニコード形式で保存されることに基づいて選択されています。Delphiの古いバージョンではSysUtilsモジュールが ユニコード形式の行を扱う機能が備わっていません。

なんらかの理由で古いバージョン(Delphi 2007以前のもの)をお使いの場合は、ANSI形式で作業をする必要があります。 MetaTrader 5とデータ交換をするには、ユニコードへ直接逆変換でコードを作成する必要があります。そういった煩雑な作業を避けるため、Delphi 2009以降の環境でのMQL5向けDLLモジュールの開発を推奨します。Delphiに慣れるための30日間お試しバージョンは次の公式ウェブサイトからダウンロードできます。 http://embarcadero.com.


1. プロジェクト作成

プロジェクトを作成するために、メニュー項目を選んでDLLウィザードを実行します。 : 「ファイル -> 新規 -> その他 ... -> DLL ウィザード」 図1を参照ください。

DLLウィザードを用いたプロジェクト作成

図1 DLLウィザードを用いたプロジェクト作成

結果、 図2にあるように空のDLL プロジェクトが作成されます。

空のDLLプロジェクト

図2 空のDLLプロジェクト

プロジェクトタイトルの長い説明のポイントは、動的に割り当てられたメモリで作業する際に正確な接続とメモリマネージャの使用法を思い出していただくことです。これについてはストリングの項目で詳しく述べます。

新規DLLに関数を書き込む前に、プロジェクトをコンフィギュアすることが重要です。

メニューからプロジェクトプロパティウィンドウを開きます。: 「プロジェクト-> オプション ...」 またはキーボード操作では 「Shift + Ctrl + F11」 です。

デバッグの手順を簡素化するには、DLLファイルをフォルダに直接作成する必要があります。 '.. \\MQL5\\Libraries' Trade Terminal MetaTrtader5. このために、 DelphiCompilerタブで図3のように対応するプロパティOutput directoryを設定します。それによりDLLでプロジェクトフォルダから端末フォルダーに生成されるファイルを常にコピーする手間がはぶけます。

DLLファイル作成結果を保存するフォルダ タスク

図3 DLLファイル作成結果を保存するフォルダを指定します。

アセンブリ中にウィンドウのシステム内に存在がないままBPLモジュールが連結され、作成されたDLLが将来動作しないのを避けるため、パッケージタブ上、ランタイムパッケージで構築フラグにチェックが入っていないことを確認することが重要です。これは図4に示されています。

アセンブリからのBPLファミリーモジュール除外

図4 アセンブリからのBPLファミリーモジュール除外

プロジェクトのコンフィグレーションを完了し、作業フォルダにそれを保存したら、指定されたプロジェクト名がのちにコンパイルされたDLLファイル名となります。


2. 手順と関数の追加

DLLモジュールでエクスポートされた手順と関数を書くときの一般的な状況について、パラメータを用いずに例を使って考察します。パラメータの通知と変換については次の項で述べます。

小規模なデグレッションObject Pascal言語で手順や関数を書くとき、プログラマーは数えきれないコンポーネントを書くのではなく、この環境のために開発された内蔵ライブラリのDelphi関数を使用することができます。たとえば、テクストメッセージを伴うモーダルウィンドウを表示するなどのように同じアクションの処理に、 API関数 MessageBox を使用することができます。それはVCLライブラリの ShowMessageの手順と同じです。

二番目の選択肢では、ダイアログ モジュールをインクルードすることで、それには標準ウィンドウ ライブラリを使用する簡単な作業ができる利点があります。 ただ、DLLファイルのサイズはだいたい500 KB増加することになります。ディスクスペースを圧迫しない小さなDLLファイルにしたい場合は、 VCLの使用はお薦めできません。

説明付検証プロジェクトの例は以下です。

library dll_mql5;

uses
  Windows, // necessary for the work of the MessageBox function
  Dialogs; // necessary for the work of the ShowMessage procedure from the Dialogs module

var   Buffer: PWideChar;
//------------------------------------------------------+
procedure MsgBox(); stdcall; // 
//to avoid errors, use the stdcall (or cdecl) for the exported functions
//------------------------------------------------------+
begin
    {1} MessageBox(0,'Hello World!','terminal', MB_OK);
    {2} ShowMessage('Hello World!');// alternative to the MessageBox function 
end;

//----------------------------------------------------------+
exports
//----------------------------------------------------------+
  {A} MsgBox,
  {B} MsgBox name 'MessageBox';// renaming of the exported function


//----------------------------------------------------------+
procedure DLLEntryPoint(dwReason: DWord); // event 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.
//----------------------------------------------------------+

エクスポートされた関数はすべてモディファイアstdcallまたはcdeclで通知される必要があります。モディファイアがひとつも指定されていない場合、Delphiは初期設定呼び出し規約を採用します。それは基本的にスタックというよりはパラメータを渡すためのCPU登録を使用するものです。それはまちがいなく、外部関数 DLLを呼び出す段階で渡されたパラメータへの連携時にエラーを招きます。

"begin end"セクションは標準的なDLLイベントハンドラの初期化コードを含んでいます。DLLEntryPointコールバック手順は、それを呼んだ手順に接続、または切断時に呼ばれます。これらイベントは正しい動的メモリ管理のために使われ、例にあるように必要に応じて割り当てられます。

MQL5を呼びます。

#import "dll_mql5.dll"
    void MsgBox(void);
    void MessageBox(void);
#import

// Call of procedure
   MsgBox();
// If the names of the function coincide with the names of MQL5 standard library function
// use the DLL name when calling the function
   dll_mql5::MessageBox();


3. 関数へのパラメータ渡と返される値

パラメータを渡すことを考える前に、MQL5とObject Pascalのデータ対応表を分析します。

MQL5のデータタイプ Object Pascal (Delphi)のデータタイプ 注意
char ShortInt
uchar Byte
short SmallInt
ushort Word
int Integer
uint Cardinal
long Int64
ulong UInt64
float Single
double Double
ushort (символ) WideChar
string PWideChar
bool Boolean
datetime TDateTime 変換が必要です。(当項の下を参照ください)
color TColor

表1 MQL5とObject Pascalのデータ対応表

表からおわかりのように、日時以外のすべてのデータタイプにDelphiは完全な類似体を持っています。

渡すパラメータを2とおり見てみます。値渡しと参照渡しです。両者ともパラメータ宣言の形式は表2にあります。

パラメータ変換メソッド MQL5の通知 Delphiの通知 注意
値通知 int func (int a); func (a:Integer): Integer;

int func (int a); func (var a: Integer): Integer; エラー:アクセス違反 に書きこみ <メモリアドレス>
リンク通知 int func (int &a); func (var a: Integer): Integer; 正。ただし モディフィアバーなしで行が変換!

int func (int &a); func (a: Integer): Integer; エラー:変数の値の代わりにメモリセル アドレスを含む

表2 パラメータ渡しのメソッド

ここから、渡されたパラメータと返された値の連携例について考察していきます。


3.1日時変換

まず、変換したい日時データのタイプを処理します。datetimeタイプはフォーマットではなくサイズにおいてのみTDateTimeに対応しているからです。 変換を楽にするために受け取られたデータタイプとしてTDateTimeの代わりにInt64を使用します。 以下は直接変換、逆変換の関数です。

uses 
    SysUtils,  // used for the constant UnixDateDelta 
    DateUtils; // used for the function IncSecon, DateTimeToUnix

//----------------------------------------------------------+
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;


3.2シンプルデータ タイプとの連携

シンプルデータ タイプを変換する方法を検証します。最も一般的に使用されるint、double、dbool、ddatetimeを例として使用します。

Object Pascalを呼びます。

//----------------------------------------------------------+
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:= 'value of variables i and dt are changed';
end;

MQL5を呼びます。

#import "dll_mql5.dll"
    string SetParam(int &i, double d, bool b, datetime &dt);
#import

// initialization of variables
   int i = 5;
   double d = 2.8;
   bool b = true;
   datetime dt= D'05.05.2010 08:31:27';
// calling the function
   s=SetParam(i,d,b,dt);
// output of results
   printf("%s i=%s d=%s b=%s dt=%s",s,IntegerToString(i),DoubleToString(d),b?"true":"false",TimeToString(dt));
結果
変数 i と dt の値は i =  10  d =  2.80000000  b = true dt =  2009.05 に変わります。 05  08 :  42 

値 d は値によって変換されているのでここでは変わりません。変数の値が変わるのを防ぐため、DLL関数内部のモディファイアconstが変数bに使用されています。


3.3ストラクチャと配列の連携

異なるタイプのパラメータをストラクチャに、またあるタイプのパラメータを配列にグループ化すると役に立つことが多いものです。前に上げた例から、SetParam関数の変換されたパラメータすべてをストラクチャに統合する作業について考察します。

Object Pascalを呼びます。

type
StructData = packed record
    i: Integer;
    d: Double;
    b: Boolean;
    dt: Int64;
  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

MQL5を呼びます。

struct STRUCT_DATA
  {
   int i;
   double d;
   bool b;
   datetime dt;
  };

#import "dll_mql5.dll"
    string SetStruct(STRUCT_DATA &data);
#import

   STRUCT_DATA data;
   
   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));
結果
変数 i 、  d 、dt の値は i =  10  d =  0.00000000  b = true dt =  2009.05 に変わります。 05  12 :  19 

前に挙げた例との大きな違いを知っておくことは重要です。ストラクチャは参照を使って変換されるので、選択フィールドが呼ばれた関数内で編集されないように保護されない可能性があります。この場合、データの統合を監視するタスクは全面的にプログラマの仕事です。

では、連続するフィボナッチの数列を配列に書いていく例で配列の連携を考えていきます。

Object Pascalを呼びます。

//----------------------------------------------------------+
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;

MQL5を呼びます。

#import "dll_mql5.dll"
    string SetArray(int &arr[],int len);
#import
   
   int arr[12];
   int len = ArraySize(arr);
// passing the array by reference to be filled by data in DLL
   s = SetArray(arr,len);
//output of result
   for(int i=0; i<len; i++) s = s + " " + IntegerToString(arr[i]);
   printf(s);
結果
フィボナッチの数列0 1 1 2 3 5 8 13 21 34 55 89


3.4ストリング連携

メモリ管理に戻ります。DLLでは、自分自身のメモリ管理を操作することが可能です。ただし、DLLとそれを呼ぶプログラムがしばしば異なるプログラム言語で書かれ、一般的システムメモリでなく作業に個別のメモリ管理が使われるため、 DLL とアプリケーションを共に使う際、メモリ操作の正確性に関する負荷はすべてプログラマが負うところとなります。

メモリ作業をするには、黄金律に従うことが大切です。それは、「メモリ割り当てをする者はそれを解き放つものである。」というものです。すなわち DLLに割り当てられた mql5プログラムコードでメモリを解放してはならない。その逆もしかり。

Windows API関数呼び出し法でメモリ管理の例を考察していきます。ここでの場合、mql5プログラムはメモリをバッファに割り当てます。DLLに PWideChar として渡されるバッファのポインタです。そしてDLLだけがこのバッファに必要な値を書きこみます。以下の例にそのことが示されています。

Object Pascalを呼びます。

//----------------------------------------------------------+
procedure SetString(const str:PWideChar) stdcall;
//----------------------------------------------------------+
begin
  StrCat(str,'Current time:');
  strCat(str, PWideChar(TimeToStr(Now)));
end;

MQL5を呼びます。

#import "dll_mql5.dll"
    void SetString(string &a);
#import

// the string must be initialized before the use
// the size of the buffer must be initially larger or equal to the string length
   StringInit(s,255,0); 
//passing the buffer reference to DLL 
   SetString(s);
// output of result 
   printf(s);

結果

現在時刻: 11: 48:51 

以下の例に示すように、ラインバッファ用のメモリは複数の方法でDLLから選択可能です。

Object Pascalを呼びます。

//----------------------------------------------------------+
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 data: %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';

     // pointer to the memory, that can be released when exit from the function
{D}  Result := @StrLocal[1];
end;
MQL5を呼びます。
#import "dll_mql5.dll"
    string GetStringBuffer(void);
#import

   printf(GetStringBuffer());

結果

現在日付: 2010年5月19日

すばらしいのは4つのオプションすべてが動作することです。最初の2つのオプションでは、グローバルに割り当てられたメモリによってラインに連携が行われます。

オプションAでは、メモリは独立して割り当てられます。オプションBでは、メモリ管理との連携は目盛マネージャによって行われると推測されます。

オプションCでは、ライン定数はメモリではなくコードセグメントに保存され、メモリマネージャはそのストレージに動的メモリを割り当てません。 オプションDは明確なプログラミングエラーです。ローカル変数に割り当てられたメモリは関数実行後すぐに解放される可能性があるからです。

また、メモリマネージャがこのメモリをすぐに解放せず、トラッシュで書き込みをする時間がなかったとしても、後者のオプションの使用はお薦めできません。


3.5デフォルトパラメータの使用

その他選択としてのパラメータ使用について述べます。それらが興味深いのは、プロシージャや関数を呼ぶとき、その値は指定される必要がないからです。とはいうものの、以下に例示するように、プロシージャや関数の宣言に際しすべての必須パラメータの後に必ず記述はされる必要があります。

Object Pascalを呼びます。

//----------------------------------------------------------+
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;
MQL5を呼びます。
#import "dll_mql5.dll"
    string SetOptional(int &a, int b=0);
#import

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

結果

デフォルトパラメータを呼びます。

デバッグを簡単にするために、上記例のコードはスクリプトとして生成される必要があります。それは、次のファイルに配置します。 Testing_DLL.mq5


4. 設計段階で発生しうるエラー

エラー: DLLロードは許可されていません。

状況:メニュー ' Tools-Options' によってMetaTrader 5設定に移動します。 そして図5に示すようDLL関数のインポートを許可します。

図5. DLL関数インポートの許可

図5 DLL関数インポートの許可

エラー:『DLL名』に『関数名』が見つかりません。
解決:DLLプロジェクトの「エクスポート」項目でコールバック関数が指定されているか確認します。指定されていれば、DLLで関数名が完全一致しているか確認する必要があります。大文字小文字の区別が必要です!

エラー: [メモリアドレス]書き込みアクセス障害
解決法:送信されたパラメータ記述が正しいか確認する必要があります。(表2参照)通常このエラーはライン処理に伴うもので、本稿3.4にあるライン連携の推奨に従うことが重要です。


5. DLLコード例

DLL使用の視覚的例として、3行で構成されるレグレッションチャンネルの計算パラメータに配慮します。canalのコンストラクションが正しいことを検証するのに、内蔵の『Canalレグレッション』を利用します。近似線のLS(最小二乗法)計算はサイト http://alglib.sources.ru/から取り入れています。 そこにはデータ処理アルゴリズムが集められています。アルゴリズムコードはDelphiを含め、数々のプログラム言語で紹介されています。

aおよびbの係数を近似線y = a + b * xで計算するには、LRLine linreg.pas.ファイルに記述されているプロシージャを使用します。

 procedure  LRLine (  const  XY: TReal2DArray;  / / Two-dimensional array of real numbers for X and Y coordinates 
                           N : AlglibInteger;  // number of points
                     var Info : AlglibInteger; // conversion status
                       var  A: Double;  / / Coefficients of the approximating line 
                        var  B: Double);
  

チャンネルのパラメータを計算するには、CalcLRChannel関数を使用します。

Object Pascalを呼びます。

//----------------------------------------------------------+
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);
    // copy the data to a 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 width of the channel 
    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;

MQL5を呼びます。

#import "dll_mql5.dll"
    int CalcLRChannel(double &rates[][2],int len,double &A,double &B,double &max);
#import

   double arr[][2], //data array for processing in the ALGLIB format
              a, b,  // Coefficients of the approximating line  
              max; // maximum deviation from the approximating line is equal to half the width of the channel
   
   int len = period; //number of points for calculation
   ArrayResize(arr,len);

// copying the 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++;
     }

// calculation of channel parameters
   CalcLRChannel(arr,len,a,b,max);

計算にCalcLRChannel関数を使用するインディケータコードは、 LR_Channel.mq5 と下記に配置されています。

//+------------------------------------------------------------------+
//|                                                   LR_Channel.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link      "https://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];
//+------------------------------------------------------------------+
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,max;
   static double save_max;
   int len=period;

   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++;
     }

// procedure of calculating the channel parameters
   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;
  }

インディケータ作業の結果、図6に示す青のリグレッション チャンネルを作成しました。チャンネルのコンストラクションが正確であることを確認するために、チャートには技術分析のインスツルメントであるMetaTrader 5のスタッフィング アーセナルから「リグレッションカナル」を表示し、赤でマークしています。

図にあるように、チャンネルの中央ラインは一つに結合しています。また、チャンネル(数ポイント)の幅にはかすかな違いがありますが、それは計算方法が異なるためです。

図6. リグレッションチャンネルの比較

図6 リグレッションチャンネルの比較


おわりに

本稿はDelphiアプリケーション開発プロットフォームを用いてDLLを書く機能について述べてきました。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/96

添付されたファイル |
mql5_sources.zip (276.43 KB)
dll_mql5_sources.zip (453.47 KB)
ろうそく足パターンの分析 ろうそく足パターンの分析
日本式のろうそく足チャートの構築とろうそく足パターンの分析は技術分析のすばらしい領域となっています。ろうそく足の利点はデータ内部の動きを追跡できるデータ表現になっていることです。本稿では、ろうそく足タイプとパターン分類を分析し、 またろうそく足パターンを決定するインディケータについてお伝えしていきます。
平均足インジケーターに基づくトレーディングシステムの例 平均足インジケーターに基づくトレーディングシステムの例
この記事は、トレーディングにおける平均足インジケーターの使用についての疑問を詳しく見ていきます。このインジケーターに基づき、簡単な取引システムが検討され、MQL55アドバイザーが記述されました。取引処理は、Standardクラスライブラリに基づき実行されます。トレーディング戦略のテスト結果は、履歴に基づき、内蔵MetaTrader5ストラテジーテスター使用し、取得されます。
かずかずのインスツルメントで取引を行うExpert Advisorの作成 かずかずのインスツルメントで取引を行うExpert Advisorの作成
ファイナンシャルマーケットにおける資産の多様性概念はかなり古いもので常に初心者のトレーダーを魅了してきました。本稿では、複数通貨対応Expert Advisorの構築をトレード戦略を扱う最初の導入として最大限にシンプルな手法で行います。
ポジション中心のMetaTrader5の環境での注文追跡管理機能付き注文マネージャー ポジション中心のMetaTrader5の環境での注文追跡管理機能付き注文マネージャー
このクラスライブラリは、MetaTrader5のエキスパートアドバイザーに追加し、MetaTrader5のポジション中心のアプローチと比べ、MetaTrader4と類似したオーダー中心のアプローチに書き換えることができます。各ポジションの保護のために、ブローカーによるストップを維持する一方、MetaTrader5のターミナルにて注文を管理することで、上記を実現します。