ユニバーサルEA:戦略トレードモード(その1)

Vasiliy Sokolov | 19 7月, 2016

コンテンツ

 

イントロダクション

相場のシグナルを解釈と分析、およびポジションの決済を含む自動取引アルゴリズムの実装で、さまざまなタスクが必要です。別のタスクとして、EAの操作を制御、エラーの適切な処理があります。また、市場データとEAのトレーディング・ポジションにアクセスするタスクがありますが、これは簡単かつ便利です。すべてのこれらの作業は、EAのソースコードに直接実装されています。

一方、取引プロセスの技術的な部分と、カスタムEAで実装するアイデアは、離ける必要があります。オブジェクト指向のアプローチにより、これらの2つの本質的に異なる取引タスクを分離することができ、時には、取引エンジンと呼ばれる、すべての戦略に共通する特別なクラスに任せることができます。

この記事は、ユニバーサルEAを呼び出し、エンジンの動作を説明する初めての記事です。これは、ポジションのエントリーとイグジットの条件の一般的な取引アルゴリズムの開発を容易にするクラスを統一します。例えば、EAに必要なデータや取引ロジックを追加する必要はありません。ポジション検索などの - すべての必要な手順は、取引エンジンによって行われます。

この記事で提案される方法は、4つの部分に分割されていて、包括的です。それぞれのパートの紹介です。

パート1。戦略トレードモードは、ここに記載されています。最初の部分では、トレーディング・モードに基づいて、ポジション管理について説明します。EAの取引ロジックを容易に取引モードを使用して定義することができます。このスタイルで書かれたEAは、デバッグが容易です。これらのロジックはまた、このような管理を容易にしました。これで表現できるアイデアは、追加のオブジェクト指向プログラミングを必要としません。ライブラリのセットを使用するかどうかに関係なく、これは有用です。

パート2。イベントモデルと取引戦略プロトタイプこのセクションでは、中央集中型のイベント処理に基づいて、元のイベントモデルについて説明します。すべてのイベントが、一箇所に「集められている」ことを意味します。また、イベントは、多通貨対応です。たとえば、EAがEURUSDチャート上で実行されている場合でも、GBPUSDの新しいイベントを受信することが可能です。複数の金融商品の取引EAを開発するときに、このイベントモデルは非常に役立ちます。また、戦略取引のエンジンの基本クラスとメタトレーダー5のポジションを表すMT5クラスを記述します。

パート3。カスタム戦略と補助トレードクラス。カスタムEA開発のプロセスを有しています。この記事から、エントリーとイグジットの条件を簡単にすることにより、EAを簡単な方法で作成できるでしょう。このパートでも、様々な補助アルゴリズムを説明し、取引情報へのアクセスを大幅に簡素化することができます。

パート4。グループの取引と戦略のポートフォリオを管理。このパートは、単一のEX5モジュールにいくつかの取引ロジックを統合するための特別なアルゴリズムの記述が含まれています。また、XMLファイルを使用して、カスタム戦略のセットを生成するために使用する機構が記載されています。

 

新しいポジションを持つメソッドと決済の管理

この記事で提供される方法を理解するため、短期移動平均と長期移動平均線の、古典的な取引システムを説明します。このように、平均化周期の大きな移動平均は、小さい周期の移動平均よりも遅くなります。取引ルールは単純です。:移動平均が上向きにクロスした場合EAは買いエントリーします。逆に、下向きにクロスした場合売りエントリーです。以下に模式的に戦略を表示します。

図1。2つの移動平均値に基づいた取引システムのチャート

赤い線は50短期単純移動平均を示しています。青い線は120長期移動平均を示しています。交差するとき、EAのポジションの方向が逆転しました。(交差が青い点線でマークされている)非アルゴリズム的なアプローチから、トレードを理解するためにこの戦略で十分です。しかし、この戦略では、EAを作成に対して十分ではありません。

まずはMAは下側から長期MAをクロスするときに、EAが実行する必要があるものを考えてみましょう:

  1. EAはのMAが交差オープンショートポジションを持っている場合、このポジションは閉鎖されるべきです。
  2. 買いポジションの有無をチェックする必要があります。ロングポジションがない場合、ポジションを取ります。ロングポジションがすでに存在する場合、何も行われません。

逆のクロスの場合、逆のアクションを取ります。

  1. EAが買いポジションを持っている場合、このポジションはクローズされます。
  2. 売りポジションの有無をチェックする必要があります。ショートポジションがない場合、エントリーします。ショートポジションがすでに存在する場合、何も行われません。

戦略の取引プロセスを記述するため、4つの取引アクションがあります。2つのトレーディングアクションは、ロングポジション開き、ルールを維持することを記述しています。他の二つのアクションは、ショートポジション開き、ルールを維持することを記述しています。4つのアクションシーケンスは、このような単純な取引に対して説明過多に見えるかもしれません。実際には、ロングポジションエントリはショートポジションの決済と一致するので、取引にそれらを組み合わせた方が簡単でしょうか。しかし、それはないでしょう。これを証明するために、初期の戦略の条件を変更してみましょう。

現在、戦略は買いの移動平均を使用しています。例えば、50短期移動平均が120長期移動平均を横切るとき、ロングポジションを持ちます。20短期移動平均が70長期移動平均を横切るとき、ショートポジションを持ちます。この場合、買いシグナルは売りシグナルとは異なります。 - 異なる状況で、異なる時間に発生します。

このような例に対して、汎用性がありません。多くの場合、エントリーとイグジットの戦略は「鏡」の条件を使用します。つまり、ロングポジションをとると、その逆にショートをとることを意味します。しかし、他のケースも考えられ、汎用的なEAのプロトタイプを作成する場合、このことを考慮する必要があり、4つのルールが必要です。

さらに、別の角度からアクションを考察します。以下の表は、取引操作タイプ(売買)や取引アクションタイプ(オープンまたはクローズ)を示しています。表のセルには、アクションの特定のセットが含まれています。

Buy Sell
Open 1. ロング・ポジションがなく、50MAが120MAの上にあるとき、ロングポジションが開かれるべきです 2。ショート・ポジションがなく、20MAが70MAを下回っているとき、ショートポジションが開かれるべきです
Close 3. 短期50MAが120MAよりも下にあるとき、買いポジションは決済します。 4. 120MAが70MAよりも上にあるとき、売りポジションは決済します。

 

表1。取引アクションのセット

プログラミングの観点から、表ブロックとルールのセットは、関数またはメソッドになります。次のように、これら4つのメソッドに名前を付けます:

  • BuyInit - ロングポジションを開く場合、このメソッドは新しいロング・ポジションを開きます。
  • SellInit - ショートポジションを開く場合、このメソッドは新しいショート・ポジションを開きます。
  • SupportBuy - このメソッドは、パラメータとして、ロングポジションを受けます。渡されたポジションがクローズする場合、このメソッドはアクションを実行します。
  • SupportSell - このメソッドのパラメータがショートポジションを受けます。渡されたポジションがクローズする場合、このメソッドはアクションを実行します。

このアプローチをどう使いましょう?まず、EAがトレードタスクを適切に実行するために、実行する必要があるアクションを分類します。すべてのアクションは別々の独立したブロック、すなわち、通常のクラスメソッドに分割されています。これは、コード中で処理する場所について考える必要はないことを意味します。プログラミング作業は、4つのメソッドに低減されます。

EAのロジックを変更する場合、適切なメソッドに追加条件を含める必要があります。トレード・ロジックの提案は、シンプルで自然なトレーディング・モードでサポートされています。

 

戦略トレードモード

多くの場合、EAの取引行動が制限される必要があります。最も単純な例では、短期または長期取引からEAを防止するためです。MT4には、これらのモードの標準的なスイッチがあります。これは、EAの起動時に表示されるEAのプロパティウィンドウのタブの上に直接配置されています。

図2。メタトレーダーで取引モード4

しかし、これ以上のモードが可能です。さらに、これらのモードを設定するため、より柔軟なツールが必要な場合があります。例えば、一部の地域では、特定の時間に取引を一時停止する必要があります。外国為替市場での太平洋セッション中に、EAは新しいポジションエントリシグナルを無視すべきであるとします。このアプローチは、低活性状態の期間にEAの取引を制限する、古典的な方法です。このモードを実装するための最良の方法は、何でしょうか?取引の4ブロックの配置を介して行うことができます。

SellInitメソッドを一時的に利用できなくすることで、売りポジションを制限することができます。すべての取引のアクションが、このメソッドの内部で実行されるためです。同じことが買いポジションでも当てはまります。つまり、ロングポジションはBuyInitメソッドを省くことで停止できます。よって、これらのメソッドの特定の組み合わせは、EAの取引モードを適切に対応します。表2で、これらの方法について説明します。

トレーディングモード 説明 呼び出されるメソッド その呼び出しは無視されます
買いと売りの実行 売買の操作が許可されています。取引制限なし BuyInit
SellInit
BuySupport
SellSupport
買いのみ 買いのみ許可売り注文は実行なし決済するまで、以前に開かれたショート・ポジションは通常モードで管理されています。 BuyInit
BuySupport
SellSupport
SellInit
売り操作のみ 売り操作のみ許可買いは実行されません。決済するまで、以前に開かれたロング・ポジションは通常モードで管理されています。 SellInit
BuySupport
SellSupport
BuyInit
今すぐ新しいエントリー 新しい売買取引を実行することはできません。シグナルによって閉じられるまで、以前に開かれたショート・ポジションは、通常モードで管理されています。 BuySupport
SellSupport
BuyInit
SellInit
ポーズ 以前に開いたポジションが管理されていません。新しい売買取引の初期化が一時停止されています。市場が閉じられ、トレードアクションを実行できない場合、このモードは、通常使用されています。 BuyInit
SellInit
BuySupport
SellSupport
ストップ 前に開かれたポジションが閉じられています。売買の操作が初期化されません。 全てのポジションは、特別なメソッドを使用して閉じられています BuyInit
SellInit
BuySupport
SellSupport

 

表2。EAの取引モード

すべての取引モードは特殊なストラクチャ ENUM_TRADE_STATEを使用して、MQLでの実装を介して与えられています。その説明は次のとおりです。

//+------------------------------------------------------------------+
//|EAの取引状態を決定します。 |
//+------------------------------------------------------------------+
enum ENUM_TRADE_STATE
{
   TRADE_BUY_AND_SELL,              // 買いと売りが許可
   TRADE_BUY_ONLY,                  // 買いのみ許可売りは許可されていません
   TRADE_SELL_ONLY,                 // 売りのみ許可買いは許可されていません。
   TRADE_STOP,                      //トレードが許可されていない。すべてのポジションをすぐに決済新しいシグナルを受け付けない
   TRADE_WAIT,                      //保有ポジションの制御がロスト新しいシグナルを無視新しいリリースの間、有効
   TRADE_NO_NEW_ENTRY               //エントリーシグナルを無視しかし、保有ポジションは、トレーディングロジックに従って維持されています。
};

これらのモードは、柔軟に接続と切断に対応し、トレーディングモード「オン・ザ・フライ」に切り替わります。

 

CTradeStateトレーディングモードスイッチ

取引モードを使用すると、常に特定のアクションを実行するため、どの時点でもEAが把握できるようになります。しかし、この時点では、個別の各EAで決定されるべきです。MICEXの最初のセクションを取引する際、取引モードの制御が特に要求されます。取引は14:00から14:03(中間クリア)に1日2回行われ、18:45から07:00(メインクリア)にクリアされます。EAは、クリア時にトレーディングを実行できないようにすることをお勧めします。

もちろん、EAが足の形成のタイミングで実行するタイプの場合、相場が止まっている間は稼働しません。これは、新しいクオートが受け取れないからです。しかし、多くのEAは、(タイマーを使用して)指定した間隔で動作します。このように、取引行動の制御が不可欠です。また、いくつかの外国為替ブローカーでは、週末の取引が可能です。しかし、このような日は低活性状態なので、これらの日はスキップされるべきです。

とにかく、取引モードの制御は、プロのアルゴリズムトレーダーのために必要な手順です。このタスクは、特別なCTradeStateモジュールに委託することができます。このモジュールは、MQL5クラスとして実装され、タスクは現在の時刻に対応する取引モードを返すことです。たとえば、現在時刻がクリア時間に対応している場合モジュールは、TRADE_WAITの状態を返します。すべてのポジションをクローズする場合、モジュールはTRADE_STOPが返されます。それでは、より詳細にその動作や設定方法を見ていきましょう。ここでは、このクラスのヘッダーは次のとおりです。

//+------------------------------------------------------------------+
//|                                                  TimeControl.mqh |
//|                                 Copyright 2015, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#include "Strategy.mqh"
#define ALL_DAYS_OF_WEEK 7
//+------------------------------------------------------------------+
//| Module of trading states TradeState                              |
//+------------------------------------------------------------------+
class CTradeState
{
private:
   ENUM_TRADE_STATE  m_state[60*24*7];  // トレード状態のマスク
public:
                     CTradeState(void);
                     CTradeState(ENUM_TRADE_STATE default_state);
   ENUM_TRADE_STATE  GetTradeState(void);
   ENUM_TRADE_STATE  GetTradeState(datetime time_current);
   void              SetTradeState(datetime time_begin, datetime time_end, int day_of_week, ENUM_TRADE_STATE state);
};

このクラスの主なタスクは、SetTradeStateメソッドを呼び出す戦略のモードに戻すことです。モジュールが状態を返す前に、SetTradeStateメソッドを使用して追加する必要があります。

モジュールの動作アルゴリズムは、MT5テストエージェントの「スケジュール」タブに似ています。

図3。MT5のテストエージェントのスケジュールタブ

このウィンドウには、エージェントがMQL5クラウドネットワークからのタスクを実行することができ、曜日を設定することができます。CTradeStateクラスは、同様の方法で動作しますが、各範囲のENUM_TRADE_STATEの5つの値の1つを設定することができます。

よりCTradeStateを理解するために、取引状態のモジュールを設定しましょう。次の設定を使用しています。

タイミング モード 説明
10:00-10:01 TRADE_WAIT 市場が開く時間。相場が開くとき、高いボラティリティと価格のジャンプがあります。これらの瞬間における取引は高リスクなので、EAを待機モードに設定する必要があります。
午後2時00分 - 午後2時03分 TRADE_WAIT 中間のクリア時。EAを同様にTRADE_WAITモードに設定する必要があるので、この時間では動作しません。
18時45分 - 18時49分 TRADE_WAIT メインクリア時。この時点で、市場も閉鎖され、そして取引が無効になっています。TRADE_WAITモードがアクティブです。
23時50分 - 午前9時59分 TRADE_WAIT 市場が閉じて、取引は無効に設定されています。EAはTRADE_WAITモードです。
金曜午前15時から TRADE_NO_NEW_ENTRY 金曜日 - 週の最後の取引日。週末にポジションを保持したままにしないために、取引の最終日で決済する必要があります。そのため、わずか数時間後に相場がしまるため、最後の取引日に新しいポジションを開くポイントがありません。これらの理由からNO_NEW_ENTRYが使用されます。毎週金曜日は、午前15時から開始して、新しいエントリシグナルは無視されます。既存のポジションのみ閉じることができます。
金曜日、23:40-23:50 TRADE_STOP 市場がしまる時間すべてのポジションがクローズされなければならない時間です。EAは、夜11時40時にTRADE_STOPモードに切り替わり、ポジションを閉じ、待機モードに切り替わります。
土曜日と日曜日 TRADE_WAIT 取引は週末に行われません。祝日の影響で、土曜日でも稼働することがあります。交換は、このような日に起こります。これは非常にまれなケースであり、そのような「ワーク」の日は、低いボラティリティと統計的不確実性を避けなければなりません。これらの日に関係なく、無効にする必要があります。

 

表3。時間に応じた取引モード

表からわかるように、必要な設定はかなり大変な作業ですが、CTradeStateクラスでは、モードのような組み合わせを作成することができます。下の表からモードを設定し、特定の時間に一致するモードを要求するサンプルスクリプトです。

//+------------------------------------------------------------------+
//|                                               TestTradeState.mq5 |
//|                                 Copyright 2015, Vasiliy Sokolov. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Vasiliy Sokolov."
#property link      "http://www.mql5.com"
#property version   "1.00"
#include <Strategy\TradeState.mqh>

CTradeState TradeState(TRADE_BUY_AND_SELL);  // 買いと売りのモード
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   TradeState.SetTradeState(D'15:00', D'23:39', FRIDAY, TRADE_NO_NEW_ENTRY);
   TradeState.SetTradeState(D'10:00', D'10:01', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'14:00', D'14:03', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'18:45', D'18:59', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'23:50', D'23:59', ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'0:00',  D'9:59',  ALL_DAYS_OF_WEEK, TRADE_WAIT);
   TradeState.SetTradeState(D'23:40', D'23:49', FRIDAY, TRADE_STOP);
   TradeState.SetTradeState(D'00:00', D'23:59', SATURDAY, TRADE_WAIT);
   TradeState.SetTradeState(D'00:00', D'23:59', SUNDAY, TRADE_WAIT);
   
   printf("10:00 - " + EnumToString(TradeState.GetTradeState(D'10:00')));
   printf("14:01 - " + EnumToString(TradeState.GetTradeState(D'14:01')));
   printf("18:50 - " + EnumToString(TradeState.GetTradeState(D'18:50')));
   printf("23:50 - " + EnumToString(TradeState.GetTradeState(D'23:51')));
   printf("Friday, > 15:00 - " + EnumToString(TradeState.GetTradeState(D'2015.11.27 15:00')));
   printf("Saturday - " + EnumToString(TradeState.GetTradeState(D'2015.11.28')));
   printf("Sunday - " + EnumToString(TradeState.GetTradeState(D'2015.11.29')));
   printf("Default State - " + EnumToString(TradeState.GetTradeState(D'11:40')));
}
//+------------------------------------------------------------------+

スクリプトの出力は次のようになります。

Default State - TRADE_BUY_AND_SELL
Sunday - TRADE_WAIT
Saturday - TRADE_WAIT
Friday, > 15:00 - TRADE_NO_NEW_ENTRY
23:50 - TRADE_STOP
18:50 - TRADE_WAIT
14:01 - TRADE_WAIT
10:00 - TRADE_WAIT

取引モードが設定されているフォーマットに注意してください。 (D'15:00' or D'18:40').日付コンポーネントを使用しないでください。、時間と分だけです。例えば、日付を渡す場合:

TradeState.SetTradeState(D'2015.11.27 15:00', D'2015.11.27 23:39', FRIDAY, TRADE_NO_NEW_ENTRY);

日付コンポーネントは依然として無視されます。

注意すべき第二の点は、SetTradeState呼び出しのシーケンスです。シーケンスは重要です!CTradeStateモジュールは、要素の数が週(10,080要素)の分数に等しいENUM_TRADE_STATEの配列のマスクを格納します。渡された日付を使用して、SetTradeStateメソッドは、この配列の要素の範囲を計算し、適切な状態でそれらを埋めます。これは、以前の状態を新しいものと交換することを意味します。このように、最新のアップデートは、最終的な状態として設定されています。このメソッドのコードは以下の通りです。:

//+------------------------------------------------------------------+
//||CTradeStateを設定します。
//| INPUT:                                                           |
//|time_begin - 取引の状態がある時間、|
//|               valid.                                             |
//| time_end - 時間、取引状態が有効まで|
//| day_of_week - 曜日、取引の設定|
//|状態が適用されます。修飾子に一致     |
//|ENUM_DAY_OF_WEEKまたは修飾子ALL_DAYS_OF_WEEK|
//|状態 - トレード状態。|
//|注:時間の日付コンポーネントのtime_begin、time_endは無視されます。|
//+------------------------------------------------------------------+
void CTradeState::SetTradeState(datetime time_begin,datetime time_end, int day_of_week, ENUM_TRADE_STATE state)
{
   if(time_begin > time_end)
   {
      string sb = TimeToString(time_begin, TIME_MINUTES);
      string se = TimeToString(time_end, TIME_MINUTES);
      printf("Time " + sb + " must be more time " + se);
      return;
   }
   MqlDateTime btime, etime;
   TimeToStruct(time_begin, btime);
   TimeToStruct(time_end,  etime);
   for(int day = 0; day < ALL_DAYS_OF_WEEK; day++)
   {
      if(day != day_of_week && day_of_week != ALL_DAYS_OF_WEEK)
         continue;
      int i_day = day*60*24;
      int i_begin = i_day + (btime.hour*60) + btime.min;
      int i_end = i_day + (etime.hour*60) + etime.min;
      for(int i = i_begin; i <= i_end; i++)
         m_state[i] = state;
   }
}

GetTradeStateは簡単に動作します。要求された時間に対応し、その要素の値を返す配列要素のインデックスを計算します。

//+------------------------------------------------------------------+
//||予め設定された取引の状態を返します。
//| time.                                                            |
//+------------------------------------------------------------------+
ENUM_TRADE_STATE CTradeState::GetTradeState(datetime time_current)
{
   MqlDateTime dt;
   TimeToStruct(time_current, dt);
   int i_day = dt.day_of_week*60*24;
   int index = i_day + (dt.hour*60) + dt.min;
   return m_state[index];
}

CTradeStateクラスのソースコードはTradeState.mqhファイルで提供されており、ソースコードに含まれています。このクラスが取引エンジンでどのように機能するかを次の記事で紹介します。

 

結論

簡単かつ迅速に、ほぼすべてのEAのロジックを定義することが可能な4つの主要な取引ルールを記載しました。各取引ルールは、別の関数やクラスメソッドです。メソッドの呼び出しの様々な組み合わせが戦略の特定のモードを決定します。したがって、柔軟なEAの管理システムは、最小限のリソースを用いて実現されます。

取引ロジックの基本的なメソッドは、トレードイベントが発生したかを理解するもので、 - このシリーズの次では、集中型のイベントモデルについて説明します。また、トレード情報の補助アルゴリズムを説明します。

コンピュータに「ユニバーサルEA」ライブラリの完全なコードをダウンロードし、インストールすることができます。ライブラリのソースコードは、この記事に添付されています。このライブラリの複数のクラスの説明は、このシリーズの次の記事で与えられます。