MQL5 クックブック:Position プロパティの取得
はじめに
前稿『MQL5 クックブック:異なるプリントモードの使用』でゃすばやくスクリプトを書き異なるモードによって必要な情報をプリントする方法をお伝えしました。今回はユーザーにすべてのpositionプロパティを取得するスクリプトを作成します。
ユーザーがスクリプトの外部パラメータで適切なオプションを選択できるような方法でそれを実装する必要があります。シンボル1個(現)の position プロパティのみ取得するか、オープンしているポジション(あれば)すべてのシンボルについて一つずつすべてに当たるかです。今回は必要な情報をひじょうに便利なダイアログボックス内で閲覧します。みなさんの中にはこの方法の方がよ便利だと思う方がいるかもしれません。
スクリプトの書き込み
プログラムの初めはいくぶん前稿に似ています(下記コードを参照)。プログラムのプロパティから始めます。それに#define 命令が続き、その後 MQLInfoString() 関数とそれが指定するMQL5_PROGRAM_NAME を用いて SCRIPT_NAME 変数にプログラム名を割り当てます。MQLInfoString() 関数の可能性ある全変数の詳細情報は MQL5 参考資料にあります。
モードの列挙を続けます。各識別子に対するコメントを書くなら、外部パラメータのドロップダウンリストにそのコメントのテキストが表示されます。選択肢を2種類実装します。
- 現シンボル -現シンボルについてのみ position プロパティを表示します。
- 全シンボル - 全シンボルについて position プロパティを表示します。
外部パラメータは1個だけ(モード)使用し適切なモードを選択します。外部パラメータに従ったコメントも外部パラメータウィンドウに表示されます。これにより意味を成すパラメータ名をつけることができます。同時にコードに関しては変数名は短い方が都合が良いでしょう。
#property copyright "Copyright 2012, http://tol64.blogspot.com" #property link "http://tol64.blogspot.com" #property description "email: hello.tol64@gmail.com" #property version "1.0" #property script_show_inputs //--- #define SCRIPT_NAME MQLInfoString(MQL_PROGRAM_NAME) // Script name //--- // ENUMERATION OF MODES enum ENUM_SYMBOLS_MODE { CURRENT_SYMBOL =0, // Current symbol ALL_SYMBOLS =1 // All symbols }; //--- // INPUT PARAMETERS input ENUM_SYMBOLS_MODE mode=CURRENT_SYMBOL; // Mode
コードはグローバル変数を伴って続きます。グローバル変数がスクリプトの任意の部分からアクセスできるようにそれを関数の外に置きます(通常プログラムの冒頭)。
// GLOBAL VARIABLES long pos_magic=0; // Magic number string pos_symbol=""; // Symbol string pos_comment=""; // Comment double pos_swap=0.0; // Swap double pos_commission=0.0; // Commission double pos_price=0.0; // Current price of the position double pos_cprice=0.0; // Current price of the position double pos_profit=0.0; // Profit/Loss of the position double pos_volume=0.0; // Position volume double pos_sl=0.0; // Stop Loss of the position double pos_tp=0.0; // Take Profit of the position datetime pos_time=NULL; // Position opening time long pos_id=0; // Position identifier ENUM_POSITION_TYPE pos_type=NULL; // Position type //---
メインプログラムの関数ではユーザー定義関数を1個だけ呼びます。 PrintPositionProperties()関数がそれで必要な処理をすべて行います。
//+------------------------------------------------------------------+ //| MAIN FUNCTION | //+------------------------------------------------------------------+ void OnStart() { PrintPositionProperties(); }
順を追ってユーザー定義関数 PrintPositionProperties() を見ていきます。まず今後の作業の基礎を形作ります。ひじょうにシンプルで、以下がその実装です。
//+------------------------------------------------------------------+ //| OPENING A DIALOG BOX WITH SYMBOL DATA | //+------------------------------------------------------------------+ void PrintPositionProperties() { int err=0; // Variable for handling errors //--- // If you need to get position properties on the current symbol only if(mode==CURRENT_SYMBOL) { } //--- // If you need to get position properties on all symbols if(mode==ALL_SYMBOLS) { } }
ブランチは2つとエラー処理をして関数の初めで宣言されるローカル変数 err を持つだけです。ここで各オプションのユースケースのシナリオを書きます。1番目、すなわち『現シンボルのみについてposition プロパティを取得する必要がある場合』を書くことから始めます。
ひじょうにシンプルです。まず現シンボルにポジションがあるか確認する必要があります。これは唯一のパラメータとしてシンボル名を取る MQL5 で利用可能な PositionSelect() 関数によって行われます。現シンボル名を渡すには Symbol() 関数またはすでに現シンボル名を持つ定義済み変数 _Symbol のどちらかを使います。PositionSelect() 関数はシンボルに対するポジションが存在すればポジティブな結果を返します。またポジションが存在しないかエラーが起こるとネガティブな結果を返します。
以下は詳細コメントを伴う1番目のオプションのコードです。
//--- // If a position exists, then... if(PositionSelect(_Symbol)) { // ...get its properties GetPositionProperties(); //--- // Open a dialog box to display all the data we obtained MessageBox("Symbol : "+pos_symbol+"\n"+ "Comment : "+pos_comment+"\n"+ "Magic Number : "+IntegerToString(pos_magic)+"\n"+ "Price Open : "+DoubleToString(pos_price,_Digits)+"\n"+ "Current Price : "+DoubleToString(pos_cprice,_Digits)+"\n"+ "Stop Loss : "+DoubleToString(pos_sl,_Digits)+"\n"+ "Take Profit : "+DoubleToString(pos_tp,_Digits)+"\n"+ "Type : "+PositionTypeToString(pos_type)+"\n"+ "Volume : "+DoubleToString(pos_volume,2)+"\n"+ "Commission : "+DoubleToString(pos_commission,2)+"\n"+ "Swap : "+DoubleToString(pos_swap,2)+"\n"+ "Profit : "+DoubleToString(pos_profit,2)+"\n"+ "Time : "+TimeToString(pos_time)+"\n"+ "Identifier : "+IntegerToString(pos_id)+"", //--- "Message Box",MB_ICONASTERISK); //--- return; } // If there is no position or an error has occurred, report it else { err=GetLastError(); // Get the code of the last registered error //--- if(err>0) // If there is an error { // Print the relevant message MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+_Symbol+") !\n\n"+ "It is possible that there is no position on this symbol. If this is not the case, please try again.", "Error", MB_ICONWARNING); //--- return; // Exit the function } } //---
上記コードではユーザー定義関数をもう2個見ることができます。 GetPositionProperties()と PositionTypeToString()です。プログラム全体をとおしてposition プロパティはさまざまな点で取得することになるため、コードの分量を減らすために個別の関数を作成するのが好都合で、それによりプログラムが読みやすくなります。下記はこの関数のコードです。MQL5 関数とGetPositionProperties()で使用される識別子のそれ以上の情報については MQL5 参考資料を必ず確認してください。
//+------------------------------------------------------------------+ //| GETTING SYMBOL PROPERTIES | //+------------------------------------------------------------------+ void GetPositionProperties() { pos_symbol =PositionGetString(POSITION_SYMBOL); pos_comment =PositionGetString(POSITION_COMMENT); pos_magic =PositionGetInteger(POSITION_MAGIC); pos_price =PositionGetDouble(POSITION_PRICE_OPEN); pos_cprice =PositionGetDouble(POSITION_PRICE_CURRENT); pos_sl =PositionGetDouble(POSITION_SL); pos_tp =PositionGetDouble(POSITION_TP); pos_type =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); pos_volume =PositionGetDouble(POSITION_VOLUME); pos_commission =PositionGetDouble(POSITION_COMMISSION); pos_swap =PositionGetDouble(POSITION_SWAP); pos_profit =PositionGetDouble(POSITION_PROFIT); pos_time =(datetime)PositionGetInteger(POSITION_TIME); pos_id =PositionGetInteger(POSITION_IDENTIFIER); }
ユーザー定義関数 PositionTypeToString() は文字列に対して返される整数のポジションタイプを読む形式に変換します。以下のコードに記述されているとおりです。
//+------------------------------------------------------------------+ //| CONVERTING POSITION TYPE TO A STRING | //+------------------------------------------------------------------+ string PositionTypeToString(int position_type) { string str=""; //--- if(position_type==0) { str="buy"; } if(position_type==1) { str="sell"; } //--- return(str); }
現シンボルのみのposition プロパティを閲覧できる1番目のオプションのコードはこれでできました。本稿で説明されているすべてのステップに従えばいますぐそれを検証することができます。標準ツールを用いてMetaTrader 5 でポジションをオープンします。それにはF9 を押すとオープン前に position プロパティを設定するのに必要なオプションがすべてあるオーダーウィンドウが開きます。
図1 MetaTrader 5 クライアントターミナルのオーダーウィンドウ
プロパティがすべて設定できたら、「売り」または「買い」のどちらかを選択しダブルクリックかチャートにドラッグしてスクリプトを実行します。スクリプトウィンドウが開きます。モード パラメータの必要な値(現シンボル)はデフォルトですでに設定済みです。OK ボタンをクリックすると現シンボルについての position プロパティをすべて表示するダイアログボックスが開きます。
図2 現シンボルのposition プロパティを持つダイアログボックス
それ以外、現シンボルにposition プロパティがなければ警告ボックスが表示されます。
図3 警告ボックス
すべて予定どおりコードに実装されているとおり動作しているようです。
それではすべてのpositionプロパティを閲覧する選択の場合に使用されるプログラムコードを検討しましょう。以下は詳細コメントを付けられたコードです。
//--- int digits=0; // Number of decimal places int mb_res=-1; // Variable with the option selected in the dialog box int pos_total=PositionsTotal(); // Number of open positions in the terminal //--- // View properties of all positions in a loop one by one for(int i=0; i<pos_total; i++) { ResetLastError(); // Reset the last error //--- pos_symbol=PositionGetSymbol(i); // Get the symbol name digits=(int)SymbolInfoInteger(pos_symbol,SYMBOL_DIGITS); // Get the number of digits in the price //--- // If a position on this symbol exists, then... if(PositionSelect(pos_symbol)) { // ...get its properties GetPositionProperties(); //--- // Open a dialog box to display all position properties obtained mb_res=MessageBox("Total Positions/Current: "+IntegerToString(pos_total)+"/"+IntegerToString(i+1)+"\n"+ "---------------------------------\n"+ "Symbol: " +pos_symbol+"\n"+ "Comment: " +pos_comment+"\n"+ "Magic Number: " +IntegerToString(pos_magic)+"\n"+ "Price Open: " +DoubleToString(pos_price,digits)+"\n"+ "Current Price: " +DoubleToString(pos_cprice,digits)+"\n"+ "Stop Loss: " +DoubleToString(pos_sl,digits)+"\n"+ "Take Profit: " +DoubleToString(pos_tp,digits)+"\n"+ "Type: " +PositionTypeToString(pos_type)+"\n"+ "Volume: " +DoubleToString(pos_volume,2)+"\n"+ "Commission: " +DoubleToString(pos_commission,2)+"\n"+ "Swap: " +DoubleToString(pos_swap,2)+"\n"+ "Profit: " +DoubleToString(pos_profit,2)+"\n"+ "Time: " +TimeToString(pos_time)+"\n"+ "Identifier: " +IntegerToString(pos_id)+"", //--- "Message Box",MB_CANCELTRYCONTINUE|MB_ICONASTERISK); //--- if(mb_res==IDCANCEL) // If you have clicked Cancel or Close { Print("The program ("+SCRIPT_NAME+") has been terminated by the user!"); return; } // Exit the function //--- // If you have clicked Retry if(mb_res==IDTRYAGAIN) { i--; } // Reset the counter to retry } else // If there is no position or an error has occurred, report it { err=GetLastError(); // Get the code of the last registered error //--- if(err>0) // If there is an error { // Print the relevant message MessageBox("Error ("+IntegerToString(err)+") when selecting a position ("+pos_symbol+") !\n\n"+ "It is possible that there is no position on this symbol. If this is not the case, please try again.", "Error", MB_ICONWARNING); } } } //---
ここではこのオプションを検証するだけです。たとえば2種類のシンボル(AUDUSD と EURUSD)についてポジションをオープンします。スクリプトを実行すると、外部パラメータのドロップダウンリストから全シンボルモードを選択しOKをクリックすると以下のようなダイアログボックスが開きます。
図4 2番目のオプションに対するPosition プロパティを持つダイアログボックス
おわりに
上図にあるようにダイアログボックスにはボタンが3個あります。リトライをクリックするとループカウンターがリセットされ、現在ダイアログボックスに表示されているシンボルに対する position プロパティがリフレッシュされます。続けるをクリックするとプログラムが次のシンボルに進みます。キャンセルボタンでプログラムは終了します。
position プロパティリストの1行目にはオープンしているポジションの合計数(Total Positions)とポジションカウンターの現在数(Current)に関する情報があります。
これでおしまいです。添付のソースコードファイル(MetaEditor でコンパイル必要)はご自由にダウンロードください。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/639
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索