MetaTrader5でカスタム MOEX シンボルを作成およびテストする方法

6 2月 2019, 07:27
Dmitrii Troshin
0
113

イントロダクション

金融相場の2つの基本的なタイプは、交換相場と店頭相場があります。 近代的なツールであるメタトレーダーとエディターツールを使用すれば、 OTC 外国為替トレードを楽しむことができます。 トレードの自動化に加えて、これらのツールは、ヒストリーデータを使用したトレードアルゴリズムの包括的なテストを可能にします。

取引に自身のアイデアを使用してはどうでしょうか。 一部の取引ターミナルには、プログラミング言語が組み込まれています。 例えば、人気の Transaq ターミナルは ATF (高度なトレード機能) プログラミング言語を特徴とします。 しかし、もちろん、MQL5 と比較することはできません。 さらに, 任意の戦略テスト関数を持っていません. 良い解決策は、MetaTrader ストラテジーテスターで交換データを取得し、トレードアルゴリズムを最適化することです。

これは、カスタムシンボルを作成することによって行うことができます。 カスタムシンボル作成のプロセスについて詳しくは、 MetaTrader5 でのカスタムシンボルの作成とテストを参照してください。 必要なのは、CSV (TXT) 形式でデータを取得し、記事に記載されているステップに従って価格ヒストリーをインポートすることだけです。

データ形式の差がない場合は簡単です。 たとえば、一般的なweb リソース finam.ru について考えてみましょう。 クオートはここでダウンロードすることができます:



モスクワ証券トレード所からのクオートをエクスポート


Finam によって提供されるデータ形式は次のとおりです。




使用可能な日付形式: "yyyymmdd", "yymmdd", "ddmmyy", "dd/mm/yy", "mm/dd/yy"の各フォーマットを指定します。 形式:



形式 "yyyy.mm.dd" は使用できません。 finam.ru は、多種多様なフォーマットの提供しますが、必要とするものがありません。 

さらに、他の多くの交換リソースがあります。 他のサイトで提供されている形式も不適切な場合があります。 特定のデータのオーダーが必要です。 ただし、クオートは、始値、終値、高値、安値など、異なるオーダーで格納することができます。 

したがって、今回のタスクは、ランダムなオーダーで提供されたデータと、異なるフォーマットをリクエストされた形式に変換することです。 任意のリソースから MetaTrader5 のデータを受け取るリソースを作ります。 次に、MQL5 ツールを使用して受信したデータに基づいてカスタムシンボルを作成し、テストを実行できるようにします。

クオートのインポートに関連する問題がいくつかあります。

為替は、スプレッド、Ask、Bidをサポートしています。 ただし、これらの値はすべて、マーケットデプスの "一瞬" にのみ存在します。 その後、約定価格のみが、その約定価格、すなわち ask または bid に関係なく書き込まれます。 ターミナルのスプレッド値が必要です。 ここでは、相場深度スプレッドを復元することは不可能であるため、固定スプレッドを追加します。 スプレッドが不可欠要素である場合は、シミュレートすることができます。 その方法の1つは、「指定された分布法則に従ってカスタムシンボルを使用して時系列をモデリングする」で説明されています。 または、ボラティリティスプレッド = f (高低)にスプレッドの依存性を示すシンプルな関数を記述することもできます。

複数の時間枠で機能する場合、固定スプレッドの使用は許容されます。 このエラーは、大規模な期間では重要ではありません。 ただし、ティックにはスプレッドモデリングが重要です。 交換ティックの形式:


形式:



ここでは、LASTに加えて ASK と BID を設定する必要があります。 データはミリ秒の精度でソートされます。 為替は価格の流れだけを提供します。 最初のページのデータは、大きなロットを分割するようなものです。 fx用語としてのティックはありません。 Bid、Ask、または両方です。 さらに、時間単位でトレードを人為的にランク付けし、ミリ秒を追加する必要があります。

したがって、この記事では、データのインポートではなく、前述の記事と同様にデータのモデル化について説明します。 したがって、誤解しないように、 ASK=BID(+spread)=LASTの原則に従って動作するアプリケーションをインポートするティックを発行しないことにしました。 スプレッドはミリ秒で機能する場合に重要であるため、テストでは適切なモデリング方法を選択する必要があります。

ティックの修正後のコードのインポートには数分かかります。 MqlRates 構造体を MqlTick に置き換える必要があります。 CustomRatesUpdate () 関数はCustomTicksAdd()で置き換える必要があります。

次のポイントは、すべての可能なデータ形式を考慮することができません。 たとえば、番号は、区切りシンボル 1 000 000 または3、14のような小数点の区切りシンボルの代わりに使用するコンマで記述できます。 またさらに悪いことに、データの区切りシンボルと小数点の両方がドットまたはコンマである場合 (区別する方法)。 最も一般的な形式のみがここで考慮されます。 標準以外の形式を扱う必要がある場合は、自分で処理しなければなりません。

さらに、トレード所にはティックヒストリーはありません—トレード量のみを提供します。 したがって、この記事では、volume =VOL=TICKVOLを使用します。

この記事は2つのパートに分かれています。 パート1では、コードの説明を行います。 これより、コードに慣れることができるため、後で標準以外のデータ形式の操作に対して編集できるようになります。 パート2には、ステップバイステップガイド (ユーザーマニュアル) があります。 プログラミングに興味がなく、実装された関数のみを使用する必要があるユーザーを対象とします。 標準データ形式で操作する場合 (特に、finam.ru web サイトをソースとして使用する場合)、すぐにパート2に進むことができます。

パート1. コードの説明

ここでは、コードの一部のみを提供します。 完全なコードは、添付ファイルで使用できます。

まず、文字列内のデータのポジション、ファイルパラメータ、シンボル名など、必要なパラメータをインプットしてみましょう。

input int SkipString        =1;                               //スキップする文字列の数
input string mark1          ="Time position and format";      //時間
input DATE indate           =yyyymmdd;                        //ソース日付の形式
input TIME intime           =hhdmmdss;                        //ソース時刻の形式
input int DatePosition      =1;                               //日付のポジション
input int TimePosition      =2;                               //時間ポジション
//------------------------------------------------------------------+
input string mark2          ="Price data position";           //価格
input int OpenPosition      =3;                               //始値ポジション
input int HighPosition      =4;                               //高値のポジション
input int LowPosiotion      =5;                               //安値価格ポジション
input int ClosePosition     =6;                               //終値ポジション
input int VolumePosition    =7;                               //ボリュームのポジション
input string mark3          ="File parameters";               //ファイル
//-------------------------------------------------------------------+
input string InFileName     ="sb";                            //ソースファイル名
input DELIMITER Delimiter   =comma;                           //区切り シンボル
input CODE StrType          =ansi;                            //文字列型
input string mark4          ="Other parameters";              //他
//-------------------------------------------------------------------+
input string spread         ="2";                             //ポイントの固定スプレッド
input string Name           ="SberFX";                        //作成するシンボルの名前


一部のデータに対して列挙が作成されます。 たとえば、日付と時刻の形式の場合:

enum DATE
{
yyyycmmcdd, // yyyy.mm.dd
yyyymmdd,   //Yyyymmdd
yymmdd,     //yymmdd
ddmmyy,     //ddmmyy
ddslmmslyy, //dd/mm/yy
mmslddslyy  // mm/dd/yy
//追加のフォーマットはここに追加する必要があります
};

enum TIME
{
hhmmss,     //Hhmmss
hhmm,       //hhmm
hhdmmdss,   //Hh:mm:ss
hhdmm       //hh: mm
//追加のフォーマットはここに追加する必要があります
};


必要な形式が使用できない場合は、追加します。

次に、ソースファイルを開きます。 フォーマットされたデータの編集に、CSV ファイルに保存することをお勧めします。 同時に、カスタムシンボルの自動作成を可能にするために、データを MqlRates 構造体に書き込む必要があります。

//ファイルで開く
    
  int out =FileOpen(InFileName,FILE_READ|StrType|FILE_TXT);
  if(out==INVALID_HANDLE)
  {
   Alert("Failed to open the file for reading");
   return; 
  }
//ファイルを開く
  int in =FileOpen(Name+"(f).csv",FILE_WRITE|FILE_ANSI|FILE_CSV);
  if(in==INVALID_HANDLE)
  {
   Alert("Failed to open the file for writing");
   return; 
  }
  //---キャプション文字列の挿入  
  string Caption ="<DATE>\t<TIME>\t<OPEN>\t<HIGH>\t<LOW>\t<CLOSE>\t<TICKVOL>\t<VOL>\t<SPREAD>";
  FileWrite(in,Caption);
//-----------------------------------------------------------
string fdate="",ftime="",open="";
string high="",low="",close="",vol="";
int left=0,right=0;

string str="",temp="";
for(int i=0;i<SkipString;i++)
   {
   str =FileReadString(out);
   i++;
   }
MqlRates Rs[];
ArrayResize(Rs,43200,43200);  //43200分/月
datetime time =0;


ソースファイルは MQL5/Files ディレクトリに保存する必要があります。 SkipString 外部変数は、スキップするファイルヘッダーの行数を示します。 区切り文字としてスペースとタブを使用できるようにするには、flag  FILE_TXT でファイルを開きます。

次に、文字列からデータを抽出する必要があります。 場所はインプットパラメータで指定されます。 番号は1から始まります。 例としてズベルバンク株式相場を使用してみましょう。



ここで、日付のポジションは1、時間は2です。 SkipString=1.

文字列を解析するには、StringSplit() 関数を使用します。 しかし、ソースファイルのエラーをより便利に監視するために、独自の関数を開発することをお勧めします。 そのような関数にデータ分析を加えることができます。 ただし、StringSplit() コードを使用する方が簡単です。 データの境界を検索する最初の関数は、文字列、区切りシンボル、およびポジションを受け取ります。 境界は、参照によって渡される a および b 変数に書き込まれます。

//---データポジションの境界を検索-----------------------------+
bool SearchBorders(string str,int pos,int &a,int &b,DELIMITER delim)
{
//補助変数
int left=0,right=0;
int count=0;
int start=0;
string delimiter="";
//-------------------------------------------------------------------+

switch(delim)
{
case comma : delimiter =",";
   break; 
case tab : delimiter ="/t";
   break;
case space : delimiter =" ";
   break;
case semicolon : delimiter =";";
   break;
}

while(count!=pos||right!=-1)
   {
   right =StringFind(str,delimiter,start);
      
   if(right==-1&&count==0){Print("Wrong date");return false;} //不正なデータ
   
   if(right==-1)
      {
      right =StringLen(str)-1;
      a =left;
      b =right;
      break;
      }
   
   count++;
      if(count==pos)
      {
      a =left;
      b =right-1;
      return true;
      }
   left =right+1;
   start =left;
   }

return true;
}


次に、 StringSubstr()を使用して適切なデータを取得します。 受信した値は、目的の形式に変換する必要があります。 そに、日付と時刻の変換関数を書きましょう。 たとえば、日付変換関数を次に示します。

//---日付の書式設定-------------------------------------------------+
//2017.01.02
string DateFormat(string str,DATE date)
{

string res="";
string yy="";
 
switch(date)
  { 
   case yyyycmmcdd :  //形式
      res =str;
      if(StringLen(res)!=10)res=""; //日付形式の確認
   case yyyymmdd :
      res =StringSubstr(str,0,4)+"."+StringSubstr(str,4,2)+"."+StringSubstr(str,6,2);
      if(StringLen(res)!=10)res=""; //日付形式の確認
      break;
   case yymmdd :
      yy =StringSubstr(str,0,2);
      if(StringToInteger(yy)>=70)
         yy ="19"+yy;
      else
         yy ="20"+yy;
      res =yy+"."+StringSubstr(str,2,2)+"."+StringSubstr(str,4,2);
      if(StringLen(res)!=10)res=""; //日付形式の確認
      break;
//---その他の形式 (完全なコードがファイルにあります)-------------
//必要に応じて他の形式の解析を追加する      
   default :
      break; 

  }

return res;
}


必要な形式が利用できない場合 (たとえば、1月18日のような日付)、追加する必要があります。 ここでは、受信したデータが必要なフォーマット (ソースファイルにエラーがある場合) に対応しているかどうかのチェックが行われます(StringLen! =10)徹底的なチェックではないことを理解します。 しかし、データ分析は簡単なタスクではないので、より詳細な分析に別のプログラムが必要になります。 エラーが発生した場合、関数は res =、 "" を返し、適切な行はスキップされます。

次の変換は、年が2桁として書き込まれる ddmmyy 型の形式に対して提供されます。 70以上 の値は19yy に変換され、70未満は20yy に変換されます。

フォーマット変換後、適切な変数にデータを書き込み、最終的な文字列をコンパイルします。

while(!FileIsEnding(out))
   {
   str =FileReadString(out);
   count++;
//---fdate-----------------------------
   if(SearchBorders(str,DatePosition,left,right,Delimiter))
   {
   temp =StringSubstr(str,left,right-left+1);
   fdate =DateFormat(temp,indate);
   if(fdate==""){Print("Error in string   ",count);continue;}
   }
   else {Print("Error in string   ",count);continue;}
//---他のデータも同様に処理


関数 SearchBorders、DateFormat、または TimeFormat でエラーが検出された場合、ストリングはスキップされ、そのシーケンス番号は Print() 関数を使用して書き込まれます。 すべての列挙と形式変換関数は、別のインクルードファイル FormatFunctions にあります。 

次に、生成された文字列を作成して書き込みます。 データは、MqlRates 構造体の適切な要素に割り当てられます。

//-------------------------------------------------------------------+
   str =fdate+","+ftime+","+open+","+high+","+low+","+close+","+vol+","+vol+","+Spread;
   FileWrite(in,str);
//---Filling MqlRates -----------------------------------------------+
   Rs[i].time               =time;
   Rs[i].open               =StringToDouble(open);
   Rs[i].high               =StringToDouble(high);
   Rs[i].low                =StringToDouble(low);
   Rs[i].close              =StringToDouble(close);
   Rs[i].real_volume        =StringToInteger(vol);
   Rs[i].tick_volume        =StringToInteger(vol);
   Rs[i].spread             =int(StringToInteger(Spread));
   i++;
//-------------------------------------------------------------------+   
   }


すべての文字列を読み取った後、動的配列は最終的なサイズを取得し、ファイルが閉じられます。

   ArrayResize(Rs,i);
   FileClose(out);
   FileClose(in);

すべてのカスタムシンボルを作成する準備が整いました。 さらに、メタエディタで直接編集できる CSV ファイルもあります。 CSV ファイルに基づいて、MetaTrader5 ターミナルの標準メソッドを使用してカスタムシンボルを作成できます。



MQL5 を使用したカスタムシンボルの作成

すべてのデータが準備されたので、カスタムシンボルを追加するだけで済みます。

   CustomSymbolCreate(Name);
   CustomRatesUpdate(Name,Rs);

クオートはCustomRatesUpdate()関数を使用してインポートされ、プログラムはシンボルの作成だけでなく、新しいデータの追加にも使用できることを意味します。 シンボルが既に存在する場合、 CustomSymbolCreate()は-1 (マイナス 1) を返し、プログラムの実行は続行されるため、 CustomRatesUpdate()関数を使用してクオートが更新されます。 シンボルはマーケットウォッチウィンドウに表示され、緑色でハイライトされます。



すべてが正しく動作することを確認するためにチャートを開きます:


EURUSD チャート


設定仕様 (シンボルプロパティ)

シンボルをテストする際には、その特性 (仕様) を設定する必要があるかもしれません。 シンボルプロパティの便利な編集を可能にする別の仕様インクルードファイルを書きます。 このファイルでは、SetSpecifications() 関数でシンボルのプロパティが設定されています。 ENUM_SYMBOL_INFO_INTEGER、ENUM_SYMBOL_INFO_DOUBLE、ENUM_SYMBOL_INFO_STRING列挙体のすべてのシンボルプロパティがここで収集されました。

void SetSpecifications(string Name)
   {  
//---整数プロパティ-------------------------------------
//   CustomSymbolSetInteger(Name,SYMBOL_CUSTOM,true);            bool シンボルがカスタムであることを示す
//   CustomSymbolSetInteger(Name,SYMBOL_BACKGROUND_COLOR,clrGreen);        マーケットウォッチでシンボルに使用する背景色を色分けする
//その他の整数プロパティ
//---ダブルプロパティ---------------------------------------------------   
//CustomSymbolSetDouble (Name、SYMBOL_BID、0	));                             Bid、銘柄を売りできる最高の価格 
//  CustomSymbolSetDouble(Name,SYMBOL_BIDHIGH,0);                          1日あたりの最高Bid単価
//   CustomSymbolSetDouble(Name,SYMBOL_BIDLOW,0);                       1日あたりの最低Bid単価
//その他のDoubleプロパティ
//---文字列プロパティ-----------------------------------------------+
//   CustomSymbolSetString(Name,SYMBOL_BASIS,"");                           カスタムシンボルの覆いアセットの名前
//   CustomSymbolSetString(Name,SYMBOL_CURRENCY_BASE,"");                  銘柄の基本通貨
//   CustomSymbolSetString(Name,SYMBOL_CURRENCY_PROFIT,"");             利益通貨
//その他の文字列プロパティ
}


この関数は、CustomSymbolCreate 関数の後に実行されます。 先物、ストックまたはオプション、ほとんどのプロパティは必須ではなく、コメントアウトされているシンボルの種類を事前に知られていません。 一部の行のみがソースコードにコメントます。

   CustomSymbolSetInteger(Name,SYMBOL_CUSTOM,true);                     //bool シンボルがカスタムであることを示す
   CustomSymbolSetInteger(Name,SYMBOL_BACKGROUND_COLOR,clrGreen);         //マーケットウォッチでシンボルに使用する背景色を色分けする
   CustomSymbolSetInteger(Name,SYMBOL_SELECT,true);                      //bool 銘柄が気配値表示で選択されていることを示す
   CustomSymbolSetInteger(Name,SYMBOL_VISIBLE,true);                       //bool 銘柄がマーケットウォッチに表示されていることを示します。


次のパラメータは、テスト目的でコメントされます: 最小ボリューム、ボリュームステップ、価格ステップ、ポイントサイズ、最も必要な特性です。 この特性は、Sberbank株の典型的なものです。 プロパティのセットとその特性は、シンボルごとに異なります。

   CustomSymbolSetDouble(name,SYMBOL_POINT,0.01);               //1点の値
   CustomSymbolSetDouble(name,SYMBOL_VOLUME_MIN,1);             //トレードの最小数量
   CustomSymbolSetDouble(name,SYMBOL_VOLUME_STEP,1);            //最小ボリューム変更ステップ
   CustomSymbolSetInteger(name,SYMBOL_DIGITS,2);                //int 小数点以下の桁数
   CustomSymbolSetInteger(name,SYMBOL_SPREAD,2);                //int スプレッド値 (ポイント単位)
   CustomSymbolSetInteger(name,SYMBOL_SPREAD_FLOAT,false);      //浮動スプレッドの表示
   CustomSymbolSetDouble(name,SYMBOL_TRADE_TICK_SIZE,0.01);	//最安値変更


目的のプロパティを設定するたびにコードを再コンパイルする必要がない場合は、この方法が適しています。 必要なパラメータをインプットするだけで行うことができれば、より便利になります。 したがって、このアプローチを変更する必要がありました。 シンボルプロパティは、新しいシンボルごとに手動で編集できるプレーンテキストファイルの仕様 .txt で提供されます。 ソースコードの再コンパイルを必要としません。

メタエディタでテキストファイルを編集する方が便利です。 主に、メタエディタはパラメータとデータの強調表示を提供します。 プロパティは、次の形式で記述されます。




データはカンマで区切られます。 文字列は次のように解析されます。

   while(!FileIsEnding(handle))
     {
     str =FileReadString(handle);
//---行のスキップ-----------------------+     
     if(str=="") continue;
     if(StringFind(str,"//")<10) continue;
//------------------------------------------+     
     sub =StringSplit(str,u_sep,split);
     if(sub<2) continue;
     SetProperties(SName,split[0],split[1]);
     }


行が空の場合、または先頭にコメントシンボル "//" がある場合はスキップされます (position<10). その後、文字列はStringSplit()関数を使用してサブストリングに分割されます。 その後、文字列は SetProperties() 関数に渡され、そこでシンボルプロパティが設定されます。 関数コードの構造:

void SetProperties(string name,string str1,string str2)
   {
   int n =StringTrimLeft(str1);
       n =StringTrimRight(str1);
       n =StringTrimLeft(str2);
       n =StringTrimRight(str2);
       
   if(str1=="SYMBOL_CUSTOM")
      {
      if(str2=="0"||str2=="false"){CustomSymbolSetInteger(name,SYMBOL_CUSTOM,false);}
      else {CustomSymbolSetInteger(name,SYMBOL_CUSTOM,true);}
      return;
      }
   if(str1=="SYMBOL_BACKGROUND_COLOR")
      {
      CustomSymbolSetInteger(name,SYMBOL_BACKGROUND_COLOR,StringToInteger(str2));
      return;
      }
   if(str1=="SYMBOL_CHART_MODE")
      {
      if(str2=="SYMBOL_CHART_MODE_BID"){CustomSymbolSetInteger(name,SYMBOL_CHART_MODE,SYMBOL_CHART_MODE_BID);}
      if(str2=="SYMBOL_CHART_MODE_LAST"){CustomSymbolSetInteger(name,SYMBOL_CHART_MODE,SYMBOL_CHART_MODE_LAST);}
      return;
      }
//---その他のシンボルプロパティ
}


ユーザーが編集時にスペースまたはタブを離れる場合は、 StringTrimLeft()  StringTrimRight()の2つの関数が追加されます。

完全なコードはインクルードファイルPropertiesSet.mqh.にあります。

追加の再コンパイルが必要なときに、すべてのシンボルプロパティが添付テキストファイルを介して設定されます。 以下に添付されている両方のコードの亜種をチェックすることができます。 インクルードファイルを介してプロパティ設定を必要とする最初の亜種はコメントアウトされます。


インターフェース

コード編集の便宜に、設定はインプットパラメータを使用して指定されます。 編集するものがない場合は、インターフェイスについて考えることができます。 最終版として、インプットパネルを開発しました:


パネルコードについて ここでは、次のインクルードファイルの標準コントロールセットを使用します。

#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Button.mqh>
#include <Controls\ComboBox.mqh>

[OK] ボタンのイベントハンドラが作成されました。

//+------------------------------------------------------------------+ 
//| Event Handling                                                   | 
//+------------------------------------------------------------------+ 
EVENT_MAP_BEGIN(CFormatPanel) 
ON_EVENT(ON_CLICK,BOK,OnClickButton) 
EVENT_MAP_END(CAppDialog)

void CFormatPanel::OnClickButton(void) 
  { 
//上述のプログラム
  } 

上記のプログラムのほぼすべてのコードがこのイベントハンドラに移されます。 外部パラメータは local variables になります。

long SkipString        =1;                              //スキップする文字列の数
DATE indate           =yyyymmdd;                        //ソース日付の形式
TIME intime           =hhdmmdss;                        //ソース時刻の形式
int DatePosition      =1;                               //日付のポジション
int TimePosition      =2;                               //時間ポジション
//その他のパラメータ

Create() 関数は各コントロールに対して記述されるため、実行後に適切な値がコントロールのリストに追加されます。 たとえば、次のように日付の形式が行われます。

//-----------コンボボックスの日付形式------------------------------------+     
    if(!CreateComboBox(CDateFormat,"ComDateFormat",x0,y0+h+1,x0+w,y0+2*h+1))
     {
      return false;
     }
   CDateFormat.ListViewItems(6);
   CDateFormat.AddItem(" yyyy.mm.dd",0);
   CDateFormat.AddItem(" yyyymmdd",1);
   CDateFormat.AddItem(" yymmdd",2);
   CDateFormat.AddItem(" ddmmyy",3);
   CDateFormat.AddItem(" dd/mm/yy",4);
   CDateFormat.AddItem(" mm/dd/yy",5);
   CDateFormat.Select(1);
     }

これらの値は、インプットフィールドから対応する変数に返されます。

long sw;  
SkipString =StringToInteger(ESkip.Text());

sw =CDateFormat.Value();
switch(int(sw))
{
   case 0 :indate =yyyycmmcdd;
      break;
   case 1 :indate =yyyymmdd;
      break;
   case 2 :indate =yymmdd;
      break;
   case 3 :indate =ddmmyy;
      break;
   case 4 :indate =ddslmmslyy;
      break;
   case 5 :indate =mmslddslyy;
      break;                
}
//その他の変数

 

このバージョンは、より大きな実装があるので、コードを編集する必要がある場合は、インプットバージョンを使用する必要があります。


パート2. ステップバイステップガイド

このパートでは、カスタム交換シンボルの作成に必要なアクションについて、段階的に説明します。 このガイドは、使用可能なクオートに標準フォーマットがあり、コードを編集する必要がない場合に使用できます。 たとえば、クオートがサイト finam.ru サイトから取得される場合です。 クオートが非標準形式である場合は、パート1で説明されているコードを編集する必要があります。

さて、金融商品の為替相場を持つソースファイルがあります。 記事の冒頭で説明されているように、Finam サイトから取得したとしましょう。 1分の時間枠のクオートを必要とすることを忘れないでください。

この記事では、2つのデータインポートオプションについて説明しました。 CreateCustomSymbol スクリプトと、インプットパネルを持つ CreateSymbolPanelEAのどちらかを使用できます。 どちらのEAもまったく同じように動作します。 たとえば、インプットパネルでの操作を考えてみましょう。 ここで提供されている例では、Moscow Exchange からのズベルバンク株式相場を使用します。 クオートは、sb .csv ファイルの下に添付されています。

1. ファイルの配置

まず、クオートファイルを MQL5/Filesに保存する必要があります。 MQL5 プログラミングの概念に関連しており、セキュリティ上の理由からファイルの操作が厳密に制御されています。 目的のディレクトリを見つけるための最も簡単な方法は、MetaTrader からを開くことです。 「ナビゲータ」ウィンドウで、「ファイル」フォルダを右クリックし、コンテキストメニューから「フォルダを開く」を選択します。



ソースデータファイルは、このフォルダに保存する必要があります (プログラムファイルの場所は、以下のファイルの章で説明されています)。 このファイルをメタエディタで開くことができるようになりました。



指定した .txt を同じフォルダに追加します。 シンボルプロパティを設定します。

2. インプット

次のステップでは、データの形式とポジションを決定し、[ファイルのプロパティ] を選択して、カスタムシンボルの名前を設定します。 フィールドのインプット方法の例を次に示します。



データはパネルに転送する必要があります。 このバージョンでは、ポイントの固定スプレッドが使用するため、フローティングスプレッドはモデル化されません。 したがって、適切なスプレッド値をここにインプットする必要があります。



拡張子を含む完全なファイル名を書き込みます。

ここで、[OK] をクリックする前に、必要なシンボル仕様を指定します。 以前 MQL5/Filesに置かれた仕様 .txt ファイルで利用可能です。

メタエディタでテキストファイルを編集するのは便利です。 主な理由は、メタエディタでサポートされているデータのハイライトです。 いずれのプロパティも理解できない場合は、カーソルをその上に置いて F1 キーを押します。



プロパティは赤で強調表示され、値は緑色で表示されます。 使用されていないコメント付きプロパティ (//) は緑色で表示されます。 データの分離にはコンマが使用することに注意してください。 編集中はプロパティを削除しないでください。 エラーを回避するためには、既存の形式を維持する必要があります。

プロパティを編集するには、必要なもの (削除 "//") のコメントを外して、該当する値を設定します。 添付ファイルに設定されているプロパティの最小セット: 価格ステップ、ポイント値、最小ロットなど

(ソースファイル内の) すべての特性は、モスクワ証券トレード所のSberbank株式に必要です。 他の金融商品には異なる特性が必要なため、プロパティを編集する必要があります。 

最低限必要なプロパティのセットは、ファイルの先頭にあります。

通常、株価は小数点以下2桁 (SYMBOL_DIGITS) で、ポイント値は0.01 ルーブルに相当します。 株価先物価格の小数点以下の桁数は0で、ポイントの値は1ルーブルです。 moex.comの仕様を参照してください。

必要なプロパティをすべて設定したら、[OK] をクリックします。 作成したカスタムシンボルが「ナビゲータ」ウィンドウに表示されます。 例では、緑で強調表示されています。


チェックするチャートを開きます。



すべて問題なく、カスタムシンボルを Strategy Tester でテストできるようになりました。

カスタムシンボル設定は、標準シンボルと同様に実行されます。 ここで重要な点は、シンボルの仕様を適切に設定することです。

例として、データを使用して、ターミナル (ここでは移動平均) で利用可能な任意の標準EAをテストしてみましょう:

 


すべてが期待どおりに動作します。 新しいクオートを追加したり、プロパティを変更したりする必要がある場合は、既存のシンボルに対して説明されているアクションを繰り返します。 仕様が変更されていない場合は、プロパティを編集せずに [OK] をクリックします。


ファイル

添付ファイルは、コンピュータに保存する方法でフォルダに配置されます。

  • CreateCustomSymbol スクリプトとコード: MQL5\Scripts
  • CreateSymbolPanelEAとコード: MQL5\Experts
  • インクルードファイル FormatFunctions, PropertiesSet, Specification: MQL5\Include
  • シンボル設定を含むテキストファイル: MQL5\Files


MetaQuotes Software Corp.によりロシア語から翻訳された
元の記事: https://www.mql5.com/ru/articles/5303

添付されたファイル |
MQL5.zip (526.52 KB)
PropertiesSet.mqh (35.55 KB)
Specification.mqh (21.21 KB)
Specifications.txt (8.04 KB)
確率をトレードギャップに適用する 確率をトレードギャップに適用する

この記事では、トレード戦略の作成とテストに確率と数学的統計手法を適用します。 また、価格とランダムウォークの差を使用して、最適なトレードリスクを探します。 価格がゼロドリフトランダムウォークのように振る舞うならば、収益性の高いトレードは不可能であることが証明されています。

MQL5 と MQL4 でのシンボル選択とナビゲーションユーティリティの開発 MQL5 と MQL4 でのシンボル選択とナビゲーションユーティリティの開発

経験豊富なトレーダーが認識している事実として、トレードにおいて最も時間のかかるものはポジションを開いたり追跡したりするのではなく、シンボルを選択してインプットポイントを探すことというものがあります。 この記事では、ブローカーが提供するトレード商品のインプットポイントの検索を簡素化するEAを開発します。

MQL5 と MQL4 の選択とナビゲーションユーティリティ: 「ホームワーク」タブの追加とグラフィックオブジェクトの保存 MQL5 と MQL4 の選択とナビゲーションユーティリティ: 「ホームワーク」タブの追加とグラフィックオブジェクトの保存

この記事では、必要なシンボルを選択するためのタブを追加することで、以前に作成されたユーティリティの関数を拡張していきます。 また、特定のシンボルチャートで作成したグラフィカルオブジェクトを保存する方法についても説明します。 また、特定のウェブサイトを使用して事前に選択されたシンボルだけで機能する方法を提案します。

トレンドとフラットの戦略を個別に最適化する トレンドとフラットの戦略を個別に最適化する

この記事では、さまざまな市場条件に対して個別に最適化する方法について説明しています。個別最適化とは、上昇トレンドと下降トレンドを別々に最適化して取引システムの最適なパラメータを決定することです。誤ったシグナルの影響を減らして収益性を向上させるために、システムは柔軟に作られています。つまり、市場の動きは常に変化を伴う為、システムには特定の設定や入力データのセットがあります。