English Русский 中文 Español Deutsch Português
エキスパートアドバイザーを使って自分ルールでシグナルをコピーするには?

エキスパートアドバイザーを使って自分ルールでシグナルをコピーするには?

MetaTrader 5 | 20 7月 2016, 09:09
1 201 0
Vladimir Karputov
Vladimir Karputov

目次

 

リスクについての警告

コピー係数の増加はリスクの増加にもつながる為、この方法を適用する前に何よりも常識に基盤に置くことが大切です。

コピー時に、システムは時々プロバイダのポジションと購読者のポジションが一致しているかを調べます。もし、ポジションの一部のみコピーされているなど、一致していないことがわかった場合、システムはそれを修正しようと試み、残りの部分をコピーします。その際の最初の同期化との違いは、プロバイダの含み益はチェックされません。もし購読者が購読を開始した場合、購読者は最大限にプロバイダの取引戦略に注意を向ける必要あります。特定のポジションだけをコピーするということはできません。

もし購読者のアカウントにシグナルによって開かれたものではないポジションが検出された場合、システムは設定『確認なしにポジションを同期する』によってそれらを閉じるように提案を行うか、もしくは自動的に閉じます。

シグナルコピーの係数を増やす方法は、プロバイダが最小ロットでトレードを行っていて、貴方の証拠金使用率が95%に設定されている(つまり、最大証拠金使用率)、そしてシグナルコピーを使う意味があるようにトレードコピー係数が少なすぎない場合に適用することができます。貴方が気に入ったシグナルの購読をする際に、今後のトレードコピー係数をシグナル計算機を使うことで事前に知ることができます。

この記事で紹介するトレードシグナルコピーのエキスパートアドバイザは、無料でマーケットからダウンロードすることができます。


1. 準備

作業を開始する前に、チュートリアルビデオをご覧ください。

  1. トレードシグナルの選択
  2. シグナルのサブスクリプション
  3. バーチャルホスティングのレンタル
  4. 購読とエキスパートアドバイザのバーチャルホスティングへの移行


1.1. コピー概念

コピーはシグナルの購読をしている取引口座でバーチャルホスティング上で動作します。その主なタスクは、『シグナル』サービスで保有したポジションを指定した回数増やすことにあります。図1では両建て口座でのコピーの概念を表しています。


図1. 両建て口座でのコピー概念

図2ではネッティング取引口座でのコピー概念を表しています。

 

図2 ネッティング口座でのコピー概念 

このように『シグナル』サービスが購読者の口座上でトレードの実行に成功すると、コピー機能はすぐさまトレードを実行し、その数量は以下の式に基づき決定されます。

(実行する『シグナル』サービスの取引数量) ×『Deal multiply by

どれくらいの回数トレードを増やす必要があるかを決めるパラメータ"Deal multiply by"は、入力パラメータで設定されます。

inputs

図3. 入力パラメータ 

MetaTrader 5のネッティング口座での動作では、コピー機能はコピーしたポジションの数量を増やします。MetaTrader 5の両建て口座では、コピー機能は数量を増やした新しいポジションを保有します。"Deal multiply by"を5に設定した場合のMetaTrader 5のネッティング口座と両建て口座のコピー機能の動作例は以下の通りです。:

『シグナル』サービスの動き コピー機能の動作
(両建て)
コピー機能の動作
(ネッティング)
コピーしたトレード BUY EURUSD 0.01ロット 新しいポジション BUY EURUSD 0.05 — 購読者の下にはBUY EURUSD 0.01ロットとBUY EURUSD 0.06ロットの二つのポジションがあることにあります。 新しいポジション BUY EURUSD 0.05ロット— 購読者の下にはBUY EURUSD 0.06ロットのポジションがあることになります。

 

2. 『シグナル』サービスの特徴

2.1. 自分のか他人のか

『シグナル』サービスが行う全てのトレードはコピー機能が追跡を行う為、いくつかの『シグナル』サービスの動作の特徴を把握しておく必要があります。例えば、このサービスはサービスを通してコピーした『自分の』ポジションだけを追跡します。

『シグナル』サービスは購読者の下にポジションを建てることに成功した場合に、トレードへのコメント欄にはコピーしたシグナル名を、トレードのマジックナンバーの欄にはIDを記載します。

次の購読の同期の際に、このIDに基づいて『シグナル』サービスを通して発注したトレードを認識します。

『ツールボックス』の『履歴』タブでコピーされたトレードにカーソルを合わせると、シグナル"Test3443431"からコピーしたBUY 0.01 EURUSDのトレードはこのように表示されます。

 

図4. コピーしたトレードのコメント(『履歴』タブ)

この図の中で、

  1. "#69801797"—トレードチケット
  2. "Test3443431"—このトレードがコピーしたシグナル名
  3. "361104976048745684"—マジックナンバーでトレードのID

『取引』タブでは、購読者の現在のポジションも同じように記載されますが、チケットだけがないことが分かります。


図5.コピーしたトレードのコメント(『取引』タブ)

別の言葉で言い換えれば、『シグナル』サービスはトレードマジックナンバーの欄を介して、購読者側でポジションの登録を行います。登録されたポジションは『自分のもの』として識別されます。『シグナル』サービスは『自分のもの』とされたポジションでのみ、ポジション数量を変えたりポジションを決済したりという取引動作を行うことができます。

未登録ポジションは『他人のもの』として識別されます。このようなポジションは、『シグナル』サービスは扱うことができません。

2.2. マジックナンバーを置き換えるか置換えないか?

MetaTrader 5ターミナルでは、購読者のネッティング口座も両建て口座も接続することができます。接続した口座タイプによって、コピーしたポジションのマジックナンバーの置換えにおけるコピー機能の動作は根本的に異なってきます。この問題に答える為に、次の図をご覧ください。


図6. マジックナンバーの置換えをしないネッティング口座 

ネッティング口座では、コピー機能マジックナンバーの置換えをしないでポジションを増やしていることが分かります。これは『シグナル』サービスにとってポジションが『他人のもの』になったということです。つまり、ネッティング口座でマジックナンバーの置換えをしないのは間違いであるということで、ネッティング口座ではポジションを増やす時には、コピー機能はいつもマジックナンバーを置き換える必要があるということです。しかし両建て口座での動作時には全て逆で、ポジションを増やす時には、コピー機能は自分のマジックナンバーを入れる必要があります。

2.3. プロバイダがポジションを決済したら、『他人の』ポジションには何が起こる?

両建ての例では、購読者の取引口座にはBUY 0.01 EURUSDのポジションがコピーされました。それから購読者はサービスの動作に介入することに決めて、BUY 0.01 EURUSDのポジションを持ちました。直近の同期の時に、『シグナル』サービスはこのようなエラーを出しました。

Signal  '3447880': local positions do not correspond to signal provider [#85639429 buy 0.04 EURUSD 1.11697]

つまり、購読者が手動で持ったBUY 0.01 EURUSDのポジションを、『シグナル』サービスは『他人のもの』として認識したわけです。ここでプロバイダが自分のポジションを決済するとどうなるかを見てみましょう。『シグナル』サービスも同様に『自分の』ポジションを決済しますが、手動で発注したBUY 0.01 EURUSDのポジションはターミナルに残ったままです。ちなみに、『シグナル』サービスの動作への手動での妨害は、ルール内にも記載されています。

IV. シグナルの購読

   20. シグナルを購読しているアカウントでの自分の取引の実行は、干渉であり、予想できない結果が生じる場合もあります。


3. どうやってトレードの発生を特定するか

トレード発生を識別する方法の選択は、コピーへのリアクションの速度に影響を与える一方、間違って数量を増やしたトレードを行った場合に余分なスプレッドの支払いが生じる可能性があります。

シグナルの購読をしているということは、シグナルのプロバイダの取引イベントを『シグナル』サービスが追跡しているということを覚えておく必要があります。必要に応じて、このサービスはポジションを持ったり決済したりします。どんなポジションの発注/決済も、購読者の取引口座に変化をもたらします。この変化を私達は追跡し、この事についてOnTradeTransaction()が私達に知らせてくれるのです。

3.1. OnTradeTransaction()を介したトラッキング

なぜOnTrade()ではなく、OnTradeTransaction()なのか?それはOnTradeTransaction()が、取引トランザクションタイプというとても有益な情報を持っているからです。全てのトランザクションタイプのうち、私達に興味を抱かせるのは一つだけです。

TRADE_TRANSACTION_DEAL_ADD — 履歴にトレードを追加します。注文の実行または口座残高を用いた操作の結果で実行されます。

つまり、コピー機能は履歴に取引が追加されるのを待ち(これは購読者の口座で取引操作が正常に実行されたという保証になる)、その後にのみ状況の処理を開始します。 


4. 購読ができる時とできない時

両方の口座が同じタイプの口座を持っている場合のみ、購読者は成功を収めることができます。

購読 結果
プロバイダ — ネッティング、購読者 — 両建て

ネッティング取引のプロバイダを両建て取引の口座が購読をする試みは失敗に終わります。 

2016.05.11 11:15:07.086 Signal  '*******': subscribe to signal [*****] started
2016.05.11 11:15:07.141 Signal  '*******': subscription/renewal prohibited

プロバイダがネッティング取引で、購読者が両建て取引の場合、シグナル購読の手続きをすることはできません。

プロバイダが両建て取引で、購読者が1つのネッティング取引

両建て取引のプロバイダをネッティング取引の口座が購読をする試みは失敗に終わります。 

2016.05.11 11:39:54.506 Signal  '*******': subscribe to signal [******] started
2016.05.11 11:39:54.560 Signal  '*******': subscription/renewal prohibited

プロバイダが両建て取引で、購読者がネッティング取引の場合、シグナル購読の手続きをすることはできません。

プロバイダ — 両建て、購読者 — 両建て 購読は成功します。 
プロバイダ — ネッティング、購読者 — ネッティング 購読は成功します。 

5. コピーに関する情報を保存しよう

実行したコピー情報をどこに保存すべきか?またよりグローバルな問題として、こういった問題はまず保存すべきなのかどうか?このコピー機能のバージョンでは、私はコピーに関する情報を構造内に保存することにしました。構造の宣言:

//+------------------------------------------------------------------+
//| Structure of congruences of positions of the terminal and        |
//| positions of the copier                                          |
//+------------------------------------------------------------------+
struct correlation
  {
   long              POSITION_IDENTIFIER_terminal; // Position identifier (terminal)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   double            POSITION_VOLUME_terminal;     // Volume of the position opened by the Signals service
   long              POSITION_IDENTIFIER_copier;   // Position identifier (copier)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   ulong             DEAL_ticket;                  // Deal ticket, if the deal is executed.
  };

構造内には全部で4つの要素があります。  

  1. "POSITION_IDENTIFIER_terminal" — この要素にはターミナル(『シグナル』サービス)が発注したポジションのIDが保存されます。
  2. "POSITION_VOLUME_terminal" —  こちらにはターミナル(『シグナル』サービス)が発注したポジションの数量が保存されます。
  3. "POSITION_IDENTIFIER_copier" — この要素にはコピー機能が発注したポジションのIDが保存されます。
  4. "DEAL_ticket" — ここにはトレードに成功した場合に、コピー機能が発注するトレードチケットが記録されます。

コピー機能のアクションは、全てOnTradeTransaction関数からのみ、また取引トランザクションタイプがTRADE_TRANSACTION_DEAL_ADDと同じの時のみ行われます。これらの条件下での実行時、私達はいつもこのトランザクションを生じさせたトレードを探し、そのパラメータを取得します。

//+------------------------------------------------------------------+ 
//| TradeTransaction function                                        | 
//+------------------------------------------------------------------+ 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_volume       =0;
      string   deal_symbol       ="";
      long     deal_type         =0;
      long     deal_magic        =0;
      long     deal_positions_id =0;
      string   deal_comment      ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_positions_id=HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
         deal_comment=HistoryDealGetString(trans.deal,DEAL_COMMENT);
         //if(deal_magic==0 && SignalInfoGetString(SIGNAL_INFO_NAME)!=HistoryDealGetString(trans.deal,DEAL_COMMENT))
         //   return;
        }
      else
         return;
...

以下の表には両建て及びネッティング口座でのコピー機能の動作原理が示されています。

のマークは、構造のこの要素に記録されたということです

のマークは、コピー機能が構造の要素に変化を加えなかったということです

ターミナル POSITION_IDENTIFIER terminal POSITION_VOLUME terminal POSITION_IDENTIFIER copier deal_ticket
両建てネッティング DEAL_ENTRY_IN
deal_ticket構造要素でtrans.dealを検索します。
一致がない場合、構造を1増やします・・・ 0 0 0 0
サービスのトレードとして評価をするので、ポジションを保有し(DEAL_VOLUME×係数)、もしCTrade.ResultDeal() != 0である場合、POSITION_IDENTIFIER_terminal要素にDEAL_POSITION_ID値を記録し、CTrade.ResultDeal()値はdeal_ticket要素に記録し、deal_volumeはPOSITION_VOLUME_terminalに記録します。 0
検出された場合、つまりこれはコピー機能によって保有されたトレードなので、そのDEAL_POSITOIN_IDPOSITION_IDENTIFIER_copier要素に記録します。

両建てネッティング DEAL_ENTRY_OUT
DEAL_POSITION_IDPOSITION_IDENTIFIER_terminalPOSITION_IDENTIFIER_copier構造要素での検索。 
両建て
・・・DEAL_POSITION_IDを検出・・・
・・・POSITION_IDENTIFIER_copier要素では何もせずに終了します  ✔  ✔  ✔  ✔
・・・POSITION_IDENTIFIER_terminal要素内・・・  ✔  ✔  ✔  ✔
・・・・・・このポジションはまだあるか?まだある場合は、コピー機能によって保有されたポジションを決済します・・・  ✔  ✔  ✔  ✔
... ... ... ...ポジションを保有し(検出されたポジション数量×係数)、CTrade.ResultDeal() != 0である場合、CTrade.ResultDeal()値をdeal_ticket要素に記録します。  ✔  ✔  ✔  ✔
... ... ...このポジションは既にありません。コピー機能によって保有されたポジションを決済します。  ✔  ✔  ✔  ✔
ネッティング
・・・DEAL_POSITION_IDを検出・・・
... ...POSITION_IDENTIFIER_terminal要素では(構造には現時点では『シグナル』サービスによって保有した前の数量が保存されます)新しい数量を計算しCTrade.ResultDeal() != 0である場合、CTrade.ResultDeal()値をdeal_ticket要素に記録します。  ✔  ✔  ✔  ✔

まとめ

貴方がトレードシグナルを購読し、内蔵バーチャルホスティングをレンタルしたのに、プロバイダが最小(または非常に小さい)ロットでトレードをしているなら、この記事で検証したコピー機能の内蔵バーチャルホスティングに送信し、全てのトレードをコピー機能の設定に比例して増量することができます。

ご注意:コピー機能のファイル"copier.mq5"と添付ファイル"languages.mqh"は、同じフォルダ内に置く必要があります。


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

添付されたファイル |
Copier.mq5 (18.85 KB)
Languages.mqh (6.19 KB)
ユニバーサルEA:イベントモデルと取引ストラテジープロトタイプ(パート2) ユニバーサルEA:イベントモデルと取引ストラテジープロトタイプ(パート2)
この記事は、ユニバーサルEAのシリーズです。このパートでは、データ処理に基づいて、オリジナルのイベント・モデルについて解説し、エンジンのストラテジーの基本クラスの構造を扱います。
ユニバーサルEA:戦略トレードモード(その1) ユニバーサルEA:戦略トレードモード(その1)
EAの開発者は、プログラミングのスキルに関係なく、信頼性の高い取引プロセスを整理するため、同じタスクとアルゴリズムの問題に直面しています。この記事では、これらのタスクの解決に着手し、トレードアイデアを記述するための便利なCStrategyエンジンの可能性を説明します。
ユニバーサルEA:カスタムストラテジーと補助トレードクラス(その3) ユニバーサルEA:カスタムストラテジーと補助トレードクラス(その3)
この記事では、ストラテジーの取引エンジンのアルゴリズムを分析していきます。シリーズの3番目の部分は、このアプローチを使用して、特定の取引ストラテジーを開発する方法の詳細な分析があります。特別な注意が補助アルゴリズムに必要です - EAは、従来のインデクサーを使用して、システムとデータへのアクセスをログに記録します(Close[1]、Open[0]など)
エキスパートアドバイザの自己最適化:進化的遺伝的アルゴリズム エキスパートアドバイザの自己最適化:進化的遺伝的アルゴリズム
この記事では、進化的アルゴリズムにある主要な原理と、その多様性および特徴について検証します。実験を使用した簡単なエキスパートアドバイザの例では、最適化が私達の取引システムに何をもたらすかを見ていきます。遺伝的、進化的、またその他のタイプの最適化を実装するプログラムのセットを検証し、取引システムのパラメータの最適化や予測変数のセットの最適化時の適用例をご紹介します。