English Русский 中文 Español Deutsch Português
銘柄とEAのORDER_MAGICによるバランス/エクイティチャートの分析

銘柄とEAのORDER_MAGICによるバランス/エクイティチャートの分析

MetaTrader 5統計と分析 | 19 6月 2017, 10:43
1 295 0
Vladimir Karputov
Vladimir Karputov

内容


タスクの設定

MetaTrader 5のヘッジ導入は、複数のエキスパートアドバイザー(または戦略)を1つの取引口座で同時に取引する絶好の機会を提供します。シグナル サービスでは、統計データを受け取って取引口座全体を追跡することができます。しかし、1つの重要な問題が残っています。それは、それぞれの戦略の貢献をバランスチャートとエクイティチャートでどのように視覚化するかということです。

1番目の戦略が利益を上げている一方で2番目の戦略が損失を生み出していることは取引では珍しいことではありません。結果として、全体的な結果が0あたりに表示されます。この場合、各取引戦略のバランスチャートとエクイティチャートを別々に作成することが便利です。


1. 手数料、スワップ、利益

全体的な取引結果は、下記のように3つのパラメータを合計することによって定義されます。

 結果 = 約定手数料 + 決済時の累積スワップ + 約定利益

これらの取引プロパティはHistoryDealGetDouble()で以下のIDを使用して受信されます。

DEAL_COMMISSION

約定手数料

double

DEAL_SWAP

累積スワップ

double

DEAL_PROFIT

約定利益

double


下記はHistoryDealGetTicket.mq5 スクリプトで、指定された期間の取引履歴から取引プロパティを受け取る例です。

スクリプトの演算結果(取引結果がないためDEAL_ENTRY_IN型の取引を除く)は以下の通りです。

...
  4: deal #36774600 at 2017.02.15 10:17:50 Entry out, sell vol: 0.01 comm: 0 swap: 0.02 profit: 1.52 NZDUSD.m (order #47802989, position ID 47770449)
...
12: deal #36798157 at 2017.02.15 16:44:17 Entry out, buy vol: 0.01 comm: 0 swap: -0.01 profit: 2.98 EURUSD.m (order #47827771, position ID 47685190)
13: deal #36798161 at 2017.02.15 16:44:17 Entry out, buy vol: 0.01 comm: 0 swap: -0.02 profit: 5.99 EURUSD.m (order #47827785, position ID 47665575)
14: deal #36798176 at 2017.02.15 16:44:17 Entry out, buy vol: 0.01 comm: 0 swap: -0.02 profit: 5.93 EURUSD.m (order #47827805, position ID 47605603)
15: deal #36798185 at 2017.02.15 16:44:18 Entry out, buy vol: 0.01 comm: 0 swap: -0.03 profit: 5.98 EURUSD.m (order #47827821, position ID 47502789)
16: deal #36798196 at 2017.02.15 16:44:18 Entry out, buy vol: 0.01 comm: 0 swap: -0.03 profit: 8.96 EURUSD.m (order #47827832, position ID 47419515)
17: deal #36798203 at 2017.02.15 16:44:18 Entry out, buy vol: 0.01 comm: 0 swap: -0.06 profit: 8.92 EURUSD.m (order #47827835, position ID 47130461)
18: deal #36798212 at 2017.02.15 16:44:19 Entry out, sell vol: 0.01 comm: 0 swap: -0.48 profit: -21.07 EURUSD.m (order #47827845, position ID 46868574)
...
25: deal #36824799 at 2017.02.15 19:57:57 Entry out, sell vol: 0.01 comm: 0 swap: 0 profit: 2.96 NZDUSD.m (order #47855548, position ID 47817757)
26: deal #36824800 at 2017.02.15 19:57:58 Entry out, sell vol: 0.01 comm: 0 swap: 0 profit: 3.01 NZDUSD.m (order #47855549, position ID 47790966)
27: deal #36824801 at 2017.02.15 19:57:58 Entry out, sell vol: 0.01 comm: 0 swap: 0.02 profit: 3.07 NZDUSD.m (order #47855550, position ID 47777495)
28: deal #36824802 at 2017.02.15 19:57:58 Entry out, sell vol: 0.01 comm: 0 swap: 0.02 profit: 3 NZDUSD.m (order #47855551, position ID 47759307)
29: deal #36824803 at 2017.02.15 19:57:59 Entry out, sell vol: 0.01 comm: 0 swap: 0.02 profit: 1.52 NZDUSD.m (order #47855552, position ID 47682775)
...
33: deal #36832775 at 2017.02.16 00:58:41 Entry out, sell vol: 0.01 comm: 0 swap: 0.05 profit: 2.96 NZDUSD.m (order #47863883, position ID 47826616)
34: deal #36832776 at 2017.02.16 00:58:41 Entry out, sell vol: 0.01 comm: 0 swap: 0.05 profit: 3.05 NZDUSD.m (order #47863884, position ID 47803010)
35: deal #36832777 at 2017.02.16 00:58:41 Entry out, sell vol: 0.01 comm: 0 swap: 0.05 profit: 2.98 NZDUSD.m (order #47863885, position ID 47792294)
36: deal #36832778 at 2017.02.16 00:58:42 Entry out, sell vol: 0.01 comm: 0 swap: 0.07 profit: 2.88 NZDUSD.m (order #47863886, position ID 47713741)
        ...

これからわかるように、スワップと利益は"+"または"-"のいずれかの符号を持つことができるので、合計取引結果を表す式ではスワップと利益が加算されます。


2. 履歴でのバランスとエクイティの計算

一般的に、運用原則には「ポジション」リストの作成が含まれます。取引履歴は5〜15分のセグメントに分割され(このパラメータは後でより正確に定義されます)、セグメントごとに下記を行います。

  • 市場エグジット取引を検索し、検出された場合には、そのような取引の総結果に基づいて、バランスチャートとエクイティチャートの値を再計算する。「ポジション」リストを修正する。
  • ポジションを使用してエクイティチャートの値を計算する。 

2.1. ポジションリスト

選択されたセグメントのポジションを検討するための取引クラスとして、HistoryDeal.mqhインクルードファイルにCHistoryDealクラスを実装します。

メソッド
TicketDeal "Deal ticket"(約定チケット)プロパティの取得/設定
PosIDDeal "Position ID"(ポジションID)プロパティの取得/設定
SymbolDeal "Deal symbol"(約定銘柄)プロパティの取得/設定
TypeDeal ENUM_DEAL_TYPE 列挙からの"Deal type"(約定タイプ)プロパティの取得/設定
EntryDeal ENUM_DEAL_ENTRY列挙からの"Trade direction"(取引方向)プロパティの取得/設定
VolumeDeal "Trade volume"(取引量)プロパティの取得/設定
PriceDeal "Trade open price"(取引始値)プロパティの取得/設定


2.2. 浮動利益の方程式

利益の方程式は ENUM_SYMBOL_CALC_MODE列挙型の記述から取得されます。この際には、銘柄の利益計算に使われる通貨を常に念頭に置いてください。この通貨は以下のように得られます。

SymbolInfoString(m_name,SYMBOL_CURRENCY_BASE);

  • 単にターミナルで銘柄仕様を開く

rts仕様

図1 RTS-3.17仕様

2.3. 問題回避:すべての銘柄が利用可能か?

考えられる問題: 

  • 取引履歴の銘柄が「気配値表示」に表示されていない(検索は共通の銘柄リストで実行される)
  • 銘柄利益の通貨を預金通貨に再計算することができない、つまり、「気配値表示」に再計算される銘柄がない

プログラムの(ターミナルではありません!) グローバル変数でこれらのエラーを考慮するために、 利益の通貨を預金口座に再計算することは不可能な銘柄や気配値表示にはない銘柄を表す 「不良」銘柄の配列を導入します。

string m_arr_defective_symbols[];                        // 不良銘柄の配列

条件を満たすシーケンス(全段階はSearchDefectiveSymbols関数内)は下記です。

  1. 「気配値表示」にあるすべての銘柄の一時的な(補助的な)配列を作成する
  2. すべての取引履歴銘柄の一時的な(補助的な)配列を作成する(指定された日付範囲)
  3. 「気配値表示」の取引履歴から銘柄を検索し、見つからない場合は「不良」銘柄のリストに送信する
  4. 取引履歴の銘柄を「気配値表示」に追加(表示)し、操作が失敗した場合は「不良」銘柄のリストに送信する
  5. 銘柄プロパティから銘柄の利益通貨を取得し、預金通貨と異なる場合はサブステップ5.1に移動する
    1. 再計算のために 「気配値表示」銘柄を検索する。銘柄は「預金通貨」+「利益通貨」または「利益通貨」+「預金通貨」に対応する必要がある。操作が失敗した場合は、銘柄を「不良」銘柄のリストに送信する。

"SearchDefectiveSymbols" 関数が終了した後には取引履歴の「不良」銘柄の配列が形成され、「不良」銘柄は、後の計算(バランスチャートとエクイティチャート)では使用されません。

2.4. 履歴でのポジションと決済済みポジションの考慮

バランスの変化はすべてm_arr_balance_equity 2次元配列に表示されます。

EA入力の "from date"と"to date"で日付の履歴をリクエストし、"timer (minutes)"の期間を持つサイクル数で割ります。この操作は"CreateBalanceEquity"関数で行われます。取引はすべて"ArrOpenPositions"動的ポインタ配列に書き込まれ、後に配列からは、約定が追加/削除されます。

バランスチャートとエクイティチャートの計算法は"Deal direction"パラメータのENUM_DEAL_ENTRYによって 違います。ポジションのオープン、決済、部分決済、逆転の際にヘッジおよびネット勘定で動作をチェックするには、 HistorySelect.mq5 スクリプトを起動します。

  • ‌DEAL_ENTRY_IN — 市場参入。取引をArrOpenPositions配列に書き入れます。
  • DEAL_ENTRY_OUT - 市場エグジット。 ArrOpenPositions 配列で、同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 検索で'false'が返された場合は、バランスチャートとエクイティチャートは変更されません。
    • 'true'の場合は、取引量(ロット単位)を確認します。
      • 取引量が同じ場合は、ArrOpenPositions 配列から取引を削除し、バランスチャート( m_arr_balance_equity 配列)を変更します
      • ArrOpenPositions配列の取引量がより大きい場合はArrOpenPositions配列での取引量を修正してバランスチャートm_arr_balance_equity配列)を変更します。
      • ArrOpenPositions配列の取引量がより小さい場合は、取引をArrOpenPositions配列から削除してバランスチャートm_arr_balance_equity配列)を変更します。
  • DEAL_ENTRY_INOUT - 反転。 ArrOpenPositions 配列で、同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 検索で'false'が返された場合は、バランスチャートとエクイティチャートは変更されません。
    • 'true'の場合は、取引量を変更してArrOpenPositions配列に書き入れてバランスチャート(m_arr_balance_equity配列)を変更します。
  • DEAL_ENTRY_OUT_BY — 反対ポジションによる決済。ArrOpenPositions 配列で、同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 取引量が同じ場合は、ArrOpenPositions 配列から取引を削除してバランスチャート(m_arr_balance_equity配列)を変更します。
    • 取引量が異なる場合は、ArrOpenPositions配列で取引量を変更して バランスチャート(m_arr_balance_equity配列)を変更します。

2.5. 浮動利益(エクイティ)の測定の仕方

ArrOpenPositions配列内のすべての取引について浮動利益を計算する必要があります。ArrOpenPositions配列に存在する取引にはそれぞれ特定のデータがあり、以下が最も重要なものです。

  • 銘柄
  • 種類(売りまたは買い)
  • 取引量
  • 約定価格

最後は、要求された取引履歴の最終日です。欠落している唯一のデータは、取引履歴が要求された最終日現在の取引の銘柄価格です。価格はCalculationFloatingProfitCopyTicksを使って受信されます。前述したように、利益の方程式はENUM_SYMBOL_CALC_MODE列挙型の記述から取得されます。 

プロファイリング中に、CalculationFloatingProfit 配列に単一の銘柄の複数の取引が含まれている場合は特に、 CopyTicksメソッドは非常に時間がかかることがわかりました。このような場合、銘柄と日付が同じであるため、同じデータが複数回要求されます。この過程を高速化するために結果のキャッシュ化 (CopyTicks) を実装しました。 

//--- "CopyTicks"結果をキャッシュ
   static string arr_name[];
   static double arr_ask[];
   static double arr_bid[];
   static datetime prev_time=0;
   int number=-1;
   if(time>prev_time)
     {
      prev_time=time;
      ArrayFree(arr_name);
      ArrayFree(arr_ask);
      ArrayFree(arr_bid);
     }
   found=false;
   size=ArraySize(arr_name);
   if(size>0)
      for(int i=0;i<size;i++)
        {
         if(name==arr_name[i])
           {
            number=i;
            found=true;
            break;
           }
        }
   if(found)
     {
      ArrayResize(ticks_array,1);
      ticks_array[0].ask=arr_ask[number];
      ticks_array[0].bid=arr_bid[number];
     }
   else
     {
      //---
      int copy_ticks=-1;
      int count=0;
      while(copy_ticks==-1 && count<5)
        {
         copy_ticks=CopyTicks(name,ticks_array,COPY_TICKS_INFO,1000*(ulong)time,1);
         //if(copy_ticks==-1)

ビッドとアスクの結果はローカル配列に保存されます。その時間間隔内の銘柄のティックがすでに受信されている場合、これらのティックは単にローカル配列から取得されます。このアプローチによって過程が10-15倍速くなります。 


3. EAのダイアログボックス(パネル)への統合

EAの基本が準備されたので、インタフェースをより使いやすくすることにしましょう。本稿の題が「銘柄とEAのORDER_MAGICによるバランス/エクイティチャートの分析」であることを考慮すると、いくつかのフィルタリング機能を提供する必要があります。

  • すべて/ 1つ/ 複数の選択された銘柄を表示する
  • すべてのマジックナンバーを1つまたは複数の選択された銘柄で表示する

すべての取引銘柄を考慮するには、すでにm_arr_all_trade_symbols配列があります。これはグローバルプログラムレベルで宣言されています。すべてのマジックナンバーを考慮するために、さらに別の m_arr_all_magics配列を紹介しましょう。これには FillArrayTradeSymbols関数をアップグレードし、m_arr_all_magics配列も同様に書き入れられるようにします。

3.1. ダイアログボックスの一般的な表示

パネル

図2 パネルの一般的な表示

すべての「不良」銘柄の配列を形成した後、取引銘柄とマジックナンバーの2つのリストがパネルに記入されます(CComboBoxクラスに基づく要素)。左のリストにはすべての取引銘柄、 右のリストにはすべてのマジックナンバーが見られます。リストでは初めにすべての銘柄とマジックナンバーが選択されます。

パネルコンボボックス

図3 ドロップダウンリスト

パネルのEA操作ロジックは、システムはStartボタンが押された後で初めての2つのドロップダウンリストで何が選択されたかを確認するようになっています。選択されたパラメータに応じて、リストには取引履歴に基づいたバランスチャートとエクイティチャートがプロットされます。

3.2. ボックスとの対話

パネルクラス( APHDialog.mqh )にEAコード全体を移し替えるには時間がかかると判断しました。m_ready、m_symbolおよびm_magic内部変数をパネルクラスに導入する代替ソリューションが下記です。

//+------------------------------------------------------------------+
//| CAPHDialogクラス                                                  |
//| 使用法:コントロールアプリケーションのメインダイアログ                  |
//+------------------------------------------------------------------+
class CAPHDialog : public CAppDialog
  {
private:
   CLabel            m_label_symbols;                 // ラベルオブジェクト
   CComboBox         m_combo_box_symbols;             // コンボボックスオブジェクト
   CLabel            m_label_magics;                  // ラベルオブジェクト
   CComboBox         m_combo_box_magics;              // コンボボックスオブジェクト
   CButton           m_button_start;                  // ボタンオブジェクト
   //---
   bool              m_ready;                         // true -> グラフィックを構築する
   string            m_symbol;
   ulong             m_magic;

public:

Startボタンがクリックされるとm_ready変数ステータスが決定されます。

//+------------------------------------------------------------------+
//| イベントハンドラ                                                   |
//+------------------------------------------------------------------+
void CAPHDialog::OnClickButtonStart(void)
  {
   if(m_combo_box_symbols.Select()!=" " && m_combo_box_magics.Select()!=" ")
      m_ready=true;
   else
      m_ready=false;
//Comment(__FUNCTION__+" ButtonStartclick"+"\n"+
//        "Symbols: "+"\""+m_combo_box_symbols.Select()+"\""+"\n"+
//        "Magic: "+"\""+m_combo_box_magics.Select()+"\""+"\n"+
//        "m_ready: "+IntegerToString(m_ready));
  }

強調表示にご注意ください。ドロップダウンリスト(m_combo_box_symbolsおよびm_combo_box_magics)を作成して入力した直後に、 " " 値(スペース)を持つ要素がリストに設定されます。

適切なドロップダウンリストをクリックするとm_symbol およびm_magic変数ステータスが決定されます。

//+------------------------------------------------------------------+
//| イベントハンドラ                                                   |
//+------------------------------------------------------------------+
void CAPHDialog::OnChangeComboBoxSymbols(void)
  {
//Comment(__FUNCTION__+" \""+m_combo_box_symbols.Select()+"\"");
   if(m_combo_box_symbols.Select()=="All symbols")
      m_symbol="";
   else
      m_symbol=m_combo_box_symbols.Select();
  }
//+------------------------------------------------------------------+
//| イベントハンドラ                                                   |
//+------------------------------------------------------------------+
void CAPHDialog::OnChangeComboBoxMagics(void)
  {
//Comment(__FUNCTION__+" \""+m_combo_box_magics.Select()+"\"");
   if(m_combo_box_magics.Select()=="All magics")
      m_magic=-1;
   else
      m_magic=StringToInteger(m_combo_box_magics.Select());
  }

よって、Start ボタンを押すとm_ready、m_symbol m_magicの3つの変数が書き入れられます。 後はパネルでパラメータが選択されたことをEAに知らせるだけです。解決策は簡単です。EAで、3秒間隔でタイマーを開始するのです。このタイマーはパネルを監視します。このために、パネルにCAPHDialog::IsReadyメソッドを書きましょう。

//+------------------------------------------------------------------+
//| パネル上で選択されたパラメータ                                       |
//+------------------------------------------------------------------+
bool CAPHDialog::IsReady(string &symbol,ulong &magic)
  {
   if(m_ready)
     {
      symbol=m_symbol;
      magic=m_magic;
      m_ready=false;
      return(true);
     }
   else
      return(false);
  }

このメソッドでは、内部変数の値を参照渡しの変数に書き込み、内部変数m_ready をリセットします。

3.3. 微調整 - 選択したマジックナンバーの考慮

GetHistoryでは、取引が指定された条件によって銘柄、銘柄とマジックナンバー、マジックナンバーによって選択されます。

//--- すべての約定
   for(int i=0;i<deals;i++)
     {
      deal_ticket          = HistoryDealGetTicket(i);
      deal_position_ID     = HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
      deal_symbol          = HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
      deal_type            = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
      deal_entry           = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
      deal_volume          = HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
      deal_price           = HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
      deal_commission      = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
      deal_swap            = HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
      deal_profit          = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
      deal_magic           = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
      if(sSymbol!="")
         if(deal_symbol!=sSymbol)
            continue;
      if(uMagic!=ULONG_MAX)
         if(deal_magic!=uMagic)
            continue;
      //--- onle BUY or SELL

ULONG_MAXはuMagic変数では「すべてのマジック」、sSymbolでは「すべての銘柄」を意味します。

下記は取引履歴に基づいてバランスと浮動利益をプロットします(最初はすべての銘柄、その後は1つの銘柄のみで)。


ビデオ


4. MFEおよびMAE分布チャート

それぞれの注文では、決済前に最大利益(MFE) と最大損失(MAE)の値が記録されます。これらのパラメータは、最大未実現ポテンシャルおよび最大許容リスクの値を使用して、決済された注文のそれぞれをさらに特徴付けます。MFE/利益チャートとMAE/利益分配チャートでは、注文は、X軸が利益/損失値、Y軸が潜在利益(MFE)及び潜在的損失(MAE)の最大表示値を持つ点として プロットされます。

4.1. MFEとMAEの会計原則

ポジション会計のためのm_arr_pos_id、MFE考慮のためのm_arr_mfe_mae配列、全体的な取引結果、MAEはグローバルプログラムレベルで宣言されています。 

long   m_arr_pos_id[];
double m_arr_mfe_mae[][3];  // [][0] - mfe、[][1] - 取引結果、[][2] - mae

続いて、m_arr_mfe_mae配列に基づいて、MFEおよびMAE配布ポイントチャートがプロットされます。

ポジション計算のための m_arr_pos_id配列とMFEを検討するためのm_arr_mfe_mae配列の1次元目はのサイズは1つです。 したがって、明らかに、 "i" でのポジション(m_arr_pos_id [i])は常にm_arr_mfe_mae[i][][][]と一致します。これらの2つの配列のサイズはGetHistoryで設定されています。

         if(deal_symbol=="")
            DebugBreak();
         ArrOpenPositions.Add(HistoryDeal);
         //--- mfe、mae
         int size=ArraySize(m_arr_pos_id);
         ArrayResize(m_arr_pos_id,size+1,10);
         ArrayResize(m_arr_mfe_mae,size+1,10);
         m_arr_pos_id[size]=deal_position_ID;
         // [][0] - mfe、[][1] - 取引結果、[][2] - mae
         m_arr_mfe_mae[size][0]=0.0;
         m_arr_mfe_mae[size][1]=0.0;
         m_arr_mfe_mae[size][2]=0.0;
         continue;
        }
      //--- 
      if(deal_entry==DEAL_ENTRY_OUT)

下記は各ポジションの最大損益を記録するための関数です。

//+------------------------------------------------------------------+
//| 結果のMfeとMae の和算                                              |
//+------------------------------------------------------------------+
void AddResultMfeMae(const long pos_id,const double floating_profit,const double financial_result)
  {
// [][0] - mfe(利益)、 [][1] - 最終的な取引結果、[][2] - mae(損失)
//--- pos_idを検索する
   int position=-1;
   int size=ArraySize(m_arr_pos_id);
   for(int i=0;i<size;i++)
      if(m_arr_pos_id[i]==pos_id)
        {
         position=i;
         break;
        }
   if(position==-1)
      return;

//---
   if(floating_profit==0.0)
      return;

   if(floating_profit>0.0) // 利益
     {
      if(m_arr_mfe_mae[position][0]<floating_profit)
         m_arr_mfe_mae[position][0]=floating_profit;
     }
   else // 損害
     {
      if(m_arr_mfe_mae[position][2]>floating_profit)
         m_arr_mfe_mae[position][2]=floating_profit;
     }
   m_arr_mfe_mae[position][1]=financial_result;
  }

3つのパラメータすべてを渡す必要があります。言い換えれば、仮想ポジションがまだ未確定ポジションのArrOpenPositions リストにあって浮動利益が-20.2である場合の呼び出しは次のようになります。

    AddResultMfeMae(pos_id,-20.2,0.0);

仮想ポジションがまだArrOpenPositionsポジションリストにあって浮動利益が+5.81の場合の呼び出しは次のようになります。

    AddResultMfeMae(pos_id,5.81,0.0);

仮想ポジションがArrOpenPositionsポジションリストから削除されていて取引結果が-3.06の場合の呼び出しは下記です。

    AddResultMfeMae(pos_id,0.0,-3.06);

言い換えれば、浮動利益があれば取引結果は0になり、ポジションが決済されていれば取引結果は0になります。

4.2. ポジションの処理

  • ‌DEAL_ENTRY_IN - 市場参入。ArrOpenPositions配列に取引を書き入れ、m_arr_pos_id及びm_arr_mfe_mae配列に新しい要素を作成します。
  • DEAL_ENTRY_OUT - 市場エグジット。 ArrOpenPositions 配列で同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 検索で'false'が返された場合は、バランスチャートとエクイティチャートは変更されません。
    • 'true'の場合は、取引量(ロット単位)を確認します。
      • 取引量が同じ場合は、ArrOpenPositions 配列から取引を削除してバランスチャート(m_arr_balance_equity配列)を変更し、m_arr_mfe_mae配列に[浮動利益0.0] [総取引結果]を書き込みます。
      • ArrOpenPositions配列からの取引量がより大きい場合は、ArrOpenPositions配列での取引量を変更してバランスチャート(m_arr_balance_equity配列)を変更し、 m_arr_mfe_mae 配列に[浮動利益0.0] [取引結果]を書き込みます。
      • ArrOpenPositions配列からの取引量がより小さい場合は、ArrOpenPositions配列から取引を削除してバランスチャート(m_arr_balance_equity配列)を変更し、m_arr_mfe_mae 配列に[浮動利益0.0] [取引結果]を書き込みます。
  • DEAL_ENTRY_INOUT - 反転。 ArrOpenPositions 配列で、同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 検索で'false'が返された場合は、バランスチャートとエクイティチャートは変更されません。
    • 'true'の場合は取引量を変更してArrOpenPositions配列に書き入れてバランスチャート( m_arr_balance_equity配列)を変更し、m_arr_mfe_mae配列に[浮動利益0.0] [総取引結果]を書き込みます。
  • DEAL_ENTRY_OUT_BY - 反対ポジションによる決済。ArrOpenPositions 配列で、同じDEAL_POSITION_IDを持つDEAL_ENTRY_IN型の取引を検索します。
    • 取引量が同じ場合は、ArrOpenPositions 配列から取引を削除してバランスチャート(m_arr_balance_equity配列)を変更し、m_arr_mfe_mae配列に[浮動利益0.0] [総取引結果]を書き込みます。
    • 取引量が異なる場合は、 ArrOpenPositions配列で取引量を変更してバランスチャート(m_arr_balance_equity配列)を変更し、 m_arr_mfe_mae 配列に[浮動利益0.0] [総取引結果]を書き込みます。

また、浮動利益を再計算したい場合には、GetHistoryで、各ポジションの m_arr_mfe_mae配列に[浮動利益] [総取引結果0.0] を書き入れます。

4.3. 変更されたボックス

バランス/エクイティとMFE / MAEチャートの両方を表示するには、ボックスを少し変更する必要があります。

パネル2

図4 変更されたボックス

MFE(最大利益)とMAE(最大損失)は、X座標の合計取引結果、Y座標のMFEまたはMAE値の2つの座標を使用して構築されます。

MFE

図5 MFE

MAE

図6 MAE


終わりに

複数のEAを同時に適用すると、各銘柄ごとのバランス/エクイティバランス統計とヘッジアカウントのマジックナンバーを確認できることがわかりました。言い換えれば、各EA(ORDER_MAGIC)の全体的なバランスと各EAのドローダウンに対する貢献度を視覚的に定義することができます。

以下は本稿で使用されているプログラムです。

#
 名称
種類
説明
1
HistoryDeal.mqh ライブラリ  選択したセグメントのポジションを考慮するクラス
2
HistoryDealGetTicket.mq5 EA  指定された時間間隔内に取引履歴から取引プロパティを受け取る例
3
APHDialog.mqh ライブラリ  EAダイアログボックスクラス
4
Accounting_positions_on_history.mq5 EA  本稿で記述されているメインEA
5
MQL5.zip アーカイブ  メインEAとそのインクルードファイルを含むアーカイブ


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

添付されたファイル |
HistoryDeal.mqh (6.66 KB)
APHDialog.mqh (28.62 KB)
MQL5.zip (26.34 KB)
人工知能を用いたTDシーケンシャル(トーマス デマークのシーケンシャル) 人工知能を用いたTDシーケンシャル(トーマス デマークのシーケンシャル)
本稿では、よく知られている戦略とニューラルネットワークを融合させた成功裡の取引方法を説明します。これは、人工知能システムを用いたトーマス デマークのシーケンシャル戦略に関するもので、「セットアップ」シグナルと「インターセクション」シグナルを使用して、戦略の最初の部分のみが適用されます。
クロスプラットフォームEA: シグナル クロスプラットフォームEA: シグナル
この記事では、クロスプラットフォームEAで使用される CSignal および CSignals クラスについて解説します。 MQL4 と MQL5 の違いについて、トレードシグナルの評価に必要なデータがどのようにアクセスされるかを調べ、記述されたコードが両方のコンパイラと互換性があることを確認します。
Wolfe波動 Wolfe波動
このBill Wolfe氏によって提案された視覚的手法は、市場参入の瞬間と方向を特定するためのパターンを検出することを可能にし、価格目標とその到達時間を予測するのに役立ちます。本稿では、Wolfe波動を検索するジグザグに基づいた指標を作成する方法と、この指標に基づいた簡単なエキスパートアドバイザーで取引する方法について説明します。
MQL5クックブック - スライディングウィンドウ内指標の高速計算のためのリングバッファの作成 MQL5クックブック - スライディングウィンドウ内指標の高速計算のためのリングバッファの作成
リングバッファは、スライディングウィンドウで計算を実行するときにデータを配置するのに最も簡単で効率的な方法です。本稿では、そのアルゴリズムを説明し、同アルゴリズムが如何にスライディングウィンドウでの計算を単純化して効率を向上させるかを示します。