English Русский 中文 Español Deutsch Português
preview
MQL5での発注を理解する

MQL5での発注を理解する

MetaTrader 5トレーディング | 8 1月 2024, 15:57
697 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

はじめに

どのような取引システムにおいても、ポジションの開始、損切りや利益確定、注文の変更など、注文とその操作を扱う必要があります。したがって、MetaTrader5用の取引システムを作成する際には、mql5での注文操作の扱い方を理解することが非常に重要です。この記事の目的は、このトピックに関するすべてを効果的に扱うことができるように、ほとんどの注文とポジション操作の簡単なガイダンスを提供することです。この記事では以下のトピックを取り上げます。

MetaTrader5の取引システムを円滑に開発するために、この記事がお役に立ち、貴重な情報となることを願っています。この記事で紹介するアプリケーションはすべて、注文、取引、ポジションの操作に関する2つの異なる方法を使用して取引システムを作成する例を示すことを主な目的としています。使用する前には、利益が出るかどうか、またはご自分の取引に適しているかどうかをテストする必要があります。

免責条項:すべての情報は「現状有姿」で提供され、情報提供のみを目的としており、取引目的やアドバイスを目的としたものではありません。いかなる結果も保証するものではありません。読者がこれらの資料を自分の取引口座で使用する場合、自己責任でおこなってください。

注文、ポジション、取引条件

この部分では、注文を効果的に処理する方法を理解するための重要な用語についてお話します。MetaTrader 5の注文に関連する3つの用語の違いを理解します。これらの用語は、注文、取引、ポジションであり、取引を実行するためのステップと考えることができます。

注文:特定の価格で特定のロットまたは数量の売買取引を開始するために取引サーバーによって受信された要求です。注文には成行注文と指値注文の2種類があります。

  • 成行注文:現在の市場価格ですぐに約定できる注文
  • 指値注文:取引を実行する価格レベルおよび取引を実行する時間に関する所定の条件で取引を実行する注文 

これらの指値注文は、以下のいずれかになります。

    • 買い逆指値:市場の現在価格より高い特定の価格で買い指値注文を出します。
    • 買い指値:市場の現在価格より低い特定の価格で買い指値注文を出します。
    • 売り逆指値:市場の現在価格より低い特定の価格で売り注文を出します。
    • 売り指値: 市場の現在価格より高い特定の価格で売り注文を出します。

出された注文は、成行注文であるか指値注文であるかにかかわらず、MetaTrader 5のツールボックスの[取引]タブで確認できます。下はその例です。

1- 取引タブ


約定せずに決済またはキャンセルされた注文は、ツールボックスの[履歴]タブで確認できます。

2- 履歴タブ

MQL5で現在のポジションを変更する場合は、後で説明する注文の変更と同じように、これらの注文を処理する必要があります。

取引:取引注文が約定または満たされたときの結果です。取引の執行に基づくインとアウトのアクションとして見出すことができます。1ロットの買い注文が執行されたとしましょう。その後、ポジションの一部を0.5ロット決済し、残りの0.5ロットを決済したとします。これは、以下のような取引になります。

  • 1買
  • 0.5売
  • 0.5売

これらの取引は、MetaTrader 5のツールボックスの履歴タブで、右クリックして取引データを選択すると表示されます。

3- 取引

ポジション:これは、金融資産の売買に基づくロングまたはショートの取引の純額です。[取引]タブでアクティブな取引として、または[履歴]タブで表示するポジションを選択すれば、それを見つけることができます。

4ポジション

買い注文の約定可能価格はAsk価格であり、決済時の約定可能価格はBid価格であることを述べておきます。一方、売り注文の約定可能価格はBid価格であり、決済時の約定可能価格はAsk価格です。

OrderSend()

MetaTrader 5の取引執行に関する重要な用語を理解した後は、MQL5で注文を自動的に執行する方法を学ぶ必要があります。まず、アクティビティを管理するための関数については、MQL5のリファレンスにある「取引関数」をご覧ください。

ここでは、OrderSend()関数について説明します。OrderSend()関数は、取引サーバーにリクエストを送信して取引操作を実行するために使用できます。つまり、注文の発注、変更、決済に使用できます。

以下はこの関数のフォーマットです。

bool  OrderSend(
   MqlTradeRequest&  request,      
   MqlTradeResult&   result        
   );

ご覧の通り、この関数には2つのパラメータがあります。

  • MqlTradeRequest構造体: これには、注文パラメータと、取引に必要なすべてのフィールドまたは変数が含まれています。アンパサンドで参照渡しされるオブジェクト。TradeRequestは、注文を執行するためにクライアント端末と取引サーバーがやり取りするメソッドです。
  • MqlTradeResult構造体: TradeResultは、注文リクエストの結果を返します。参照渡しされるオブジェクトもあります。

MqlTradeRequest構造体

構造体とは、異なる型の関連データの集合です。MqlTradeRequest構造体の定義は以下の通りです。

struct MqlTradeRequest
  {
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type
   ulong                         magic;            // Expert Advisor ID (magic number)
   ulong                         order;            // Order ticket
   string                        symbol;           // Trade symbol
   double                        volume;           // Requested volume for a deal in lots
   double                        price;            // Price
   double                        stoplimit;        // StopLimit level of the order
   double                        sl;               // Stop Loss level of the order
   double                        tp;               // Take Profit level of the order
   ulong                         deviation;        // Maximal possible deviation from the requested price
   ENUM_ORDER_TYPE               type;             // Order type
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type)
   string                        comment;          // Order comment
   ulong                         position;         // Position ticket
   ulong                         position_by;      // The ticket of an opposite position
  };

MqlTradeRequestオブジェクトを宣言する場合は、以下のコードでおこなうことができます。

MqlTradeRequest request;

次に、以下の例のように、オブジェクトの後にドット(.)を追加することで、作成されたリクエストオブジェクトの変数に取引パラメータを割り当てることができます。

request.symbol = _Symbol;
request.volume = 0.01;
request.type = ORDER_TYPE_BUY;

以下は、MqlTradeRequest構造体のすべてのメンバーまたは変数と、その代入に受け入れられる値のリストです。

変数 詳細 割り当てに受け入れられる値
action 取引操作の種類

ENUM_TRADE_REQUEST_ACTIONSのいずれか(TRADE_ACTION_DEAL、TRADE_ACTION_PENDING、TRADE_ACTION_SLTP、TRADE_ACTION_MODIFY、TRADE_ACTION_REMOVE、TRADE_ACTION_CLOSE_BY)

magic EA ID(特定のエキスパートアドバイザー(EA)が発注した注文を識別するために使用) 任意のulong値
order 注文チケット(action変数でTRADE_ACTION_MODIFYまたはTRADE_ACTION_REMOVEを使用する場合に必要)  任意のulong値
symbol 指定された銘柄または取引商品(_SYMBOLは現在のもの) 任意の文字列記号
volume 取引量またはロット  任意の許容double値
price 始値 double値
stoplimit 指値注文の始値。actionはTRADE_ACTION_PENDING、typeはORDER_TYPE_BUY_STOP_LIMITまたはORDER_TYPE_SELL_STOP_LIMITが必要。指値注文に必要 double値
sl 取引の損切り価格 double値
tp 取引の利食い価格 double値
deviation 最大価格偏差(ポイント単位) ulong値
type 注文タイプ ENUM_ORDER_TYPEのいずれか(ORDER_TYPE_BUY、ORDER_TYPE_SELL、 ORDER_TYPE_BUY_STOP、 ORDER_TYPE_SELL_STOP、 
ORDER_TYPE_BUY_LIMIT、 ORDER_TYPE_SELL_LIMIT、 ORDER_TYPE_BUY_STOP_LIMIT、 ORDER_TYPE_SELL_STOP_LIMIT)
type_filling 注文の執行タイプまたは注文の充填方針 ENUM_ORDER_TYPE_FILLING(ORDER_FILLING_FOK、ORDER_FILLING_IOC、 ORDER_FILLING_BOC、ORDER_FILLING_RETURNのいずれか)
type_time 指値注文の種類 ENUM_ORDER_TYPE_TIME(ORDER_TIME_GTC、ORDER_TIME_DAY、 ORDER_TIME_SPECIFIED、 ORDER_TIME_SPECIFIED_DAYのいずれか)
expiration 指値注文の有効期限。type_timeがORDER_TIME_SPECIFIEDの場合は必須。 datetime値
comment 注文コメント string値
position ポジションのチケット。ポジションが変更または決済されたときに、そのポジションを特定するために必要です。 ulong値
position_by 反対ポジションのチケット。同じ銘柄に対して、反対方向のポジションでポジションが決済される場合に使用されます。 ulong値

では、MQL5で注文を出す際に必要な重要なアクションをいくつか挙げてみましょう。

  • 成行注文
  • 損切りと利食いの追加
  • 指値注文
  • 指値注文の変更
  • 指値注文の削除

成行注文

このタイプのアクションでは、注文が現在の市場価格で発注されることを意味する成行注文を発注する必要があり、TRADE_ACTION_DEALアクションを使用します。買い注文の場合、注文は現在の売呼値で発注され、売り注文の場合、注文は現在の買呼値で発注されます。その方法は次の通りです。 

MqlTradeRequestオブジェクトとMqlTradeResultオブジェクトを宣言した後、以下の変数に以下の値を代入することができます。

request.action = TRADE_ACTION_DEAL;                    &nbsthe p;   //market order palcement
request.type = ORDER_TYPE_BUY;                             //type of order is buy
request.symbol = _Symbol;                                  //applied for the cuurrent symbol
request.volume = 0.1;                                      //the lot size
request.type_filling = ORDER_FILLING_FOK;                  //the filling policy fill or kill
request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);      //the price is the current ask for buy
request.sl = 0;                                            //stop loss is 0
request.tp = 0;                                            //take profit is 0
request.deviation = 50;                                    //slippage is 50
OrderSend(request, result);                                //calling the OrderSend function

前のコードでわかるように、損切りと利食いの値を追加していません。その値を他の変数と一緒にコードに追加することもできるし、次のポイントで説明するように、別のアクションで追加することもできます。

損切りと利食いの追加

損切りと利食いを追加する必要がある場合、次の例に示すように、TRADE_ACTION_SLTPを変数actionに代入します。

request.action = TRADE_ACTION_SLTP;          //adding sl and tp
request.symbol = _Symbol;                    //applied for the cuurrent symbol
request.sl = 1.07000;                        //sl price
request.sl = 1.09000;                        //tp price
OrderSend(request, result);                  //calling the OrderSend function


指値注文

指値注文を出したい場合は、別のアクションTRADE_ACTION_PENDING)を使います。そして、注文の種類を決定します。指値注文の有効期限が必要な場合は、時間を設定することができます。

request.action = TRADE_ACTION_PENDING;          //pending order placement
request.type = ORDER_TYPE_BUY_STOP;             //type of order is buy stop
request.symbol = _Symbol;                       //applied for the cuurrent symbol
request.volume = 0.1;                           //the lot size
request.price = 1.07000;                        //opening price
request.sl = 1.06950;                           //stop loss
request.tp = 1.07100;                           //take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.08.31 00.00';       //expiration time - datetime constant          
request.type_filling = ORDER_FILLING_FOK;       //the filling policy fill or kill
request.stoplimit = 0;                          //for stoplimit order only
OrderSend(request, result);                     //calling the OrderSend function


指値注文の変更

指値注文を修正する必要がある場合、修正する必要のある指値注文の注文チケット番号を取得する必要があります。OrderGetTicket関数を使用して、注文のチケットを取得することができます。この関数は対応する注文のチケットを返すので、それを使って注文を選択し、作業することができます。

ulong  OrderGetTicket( 
   int  index      // Number in the list of orders 
   );

注文チケット番号を保持するticketという変数があるとします。この変数を使用して、注文のチケット番号をリクエストオブジェクトのorder変数に代入することができます。次の例と同じように、TRADE_ACTION_MODIFYアクショを使って注文を変更することができます。

request.action = TRADE_ACTION_MODIFY;           //pending order modyfying
request.order = ticket;                         //ticket variable that holds the pending order ticket to modify
request.price = 1.07050;                        //new opening price
request.sl = 1.07000;                           //new stop loss
request.tp = 1.07150;                           //new take profit
request.type_time = ORDER_TIME_SPECIFIED;       //to set an expiration time
request.expiration = D'2023.09.01 00.00';       //new expiration time - datetime constant        
OrderSend(request, result);                     //calling the OrderSend function

指値注文の削除

指値注文を削除する必要がある場合は、TRADE_ACTION_REMOVEアクションを使用して削除できます。削除したい指値注文のチケット番号も必要です。必要なチケット番号を保持していると仮定して、ticket変数を使用することができます。

request.action = TRADE_ACTION_REMOVE;           //pending order remove
request.order = ticket;                         //ticket variable that holds the pending order ticket to remove
OrderSend(request, result);                     //calling the OrderSend function

MqlTradeResult構造体

MqlTradeResult構造体は、OrderSend()関数によって注文が発注されると、注文が成功したかどうかの結果を返します。チケット番号、数量、価格など、取引サーバーからの取引情報が含まれています。

以下はMqlTradeResult構造体の定義です。

struct MqlTradeResult
  {
   uint     retcode;          // Operation return code
   ulong    deal;             // Deal ticket, if it is performed
   ulong    order;            // Order ticket, if it is placed
   double   volume;           // Deal volume, confirmed by broker
   double   price;            // Deal price, confirmed by broker
   double   bid;              // Current Bid price
   double   ask;              // Current Ask price
   string   comment;          // Broker comment to operation (by default it is filled by description of trade server return code)
   uint     request_id;       // Request ID set by the terminal during the dispatch 
   int      retcode_external; // Return code of an external trading system
  };

resultというオブジェクトを宣言して、OrderSend()関数呼び出しの最初のパラメータ(request)の後の2番目のパラメータとして渡すことができます。

MqlTradeResult result;

MqlTradeResult構造体の変数を見てわかるように、retcode変数は、リクエストが成功したかどうかを示すコードを取引サーバーから返すので、非常に重要です。

取引が成立しなかった場合、リターンコードはエラー状態を示します。詳細については、MQL5のリファレンスからリターンコードのリストを確認できます。次の例のように、エラーが返されたかどうかを報告するコードを取引システムに含めることが重要です。

   if(result.retcode == TRADE_RETCODE_DONE || result.retcode == TRADE_RETCODE_PLACED)
     {
      Print("Trade Placed Successfully");
     }
   else
     {
      Print("Trade Not Placed, Error ", result.retcode);
     }

前のコードでわかるように、リクエストの後に結果のメッセージを表示し、結果の変数を埋めます。取引が成立した場合は、その旨がメッセージで送られ、問題がある場合は、エラーが発生した旨のメッセージが表示され、エラーコードが返されます。

OrderSend()アプリケーション

OrderSend()関数を使用して取引を実行できる、単純な取引システムを作成する必要があります。作成する取引システムは単純な移動平均のクロスオーバーで、アクションは成行注文のみです。

ここでの目的は、OrderSend()とCTradeクラスを使って同じ取引システムを作成する場合の違いを理解することです。以下は、OrderSend()関数を使用して、このMAクロスオーバーを作成する手順です。

グローバルスコープで、2つの整数変数(simpleMA、barsTotal)を代入なしで作成し、後でOnInit部分で代入します。

int simpleMA;
int barsTotal;

simpleMAは、移動平均テクニカル指標のハンドルを返すiMA関数に代入されます。パラメータは次の通りです。

  • symbol:銘柄名(_Symbolは現在の銘柄)
  • period:時間枠(1時間を表すPERIOD_H1を使用)
  • ma_period:移動平均の期間(50を使用)
  • ma_shift:必要な水平シフト
  • ma_method:移動平均の種類(simpleを使用)
  • applied_price:MA計算に使用する価格の種類(終値を使用)

barsTotalは、バーの数を返すiBars関数に代入されます。パラメータは次の通りです。

  • symbol:銘柄名
  • timeframe:時間枠の期間
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);

OnTickでは、価格、出来高、スプレッドに関する情報を格納するMqlRates型を使用した価格用と、double変数型を使用した移動平均用の2つの配列を作成します。

   MqlRates priceArray[];
   double mySMAArray[];

売値と買値の定義

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

OrderSend()関数用に2つのオブジェクトを作成し、1つはMqlTradeReuestを使用したリクエスト用で、もう1つはMqlTradeResultを使用した結果用です。

ZeroMemory(request);

作成した2つの配列priceArrayとmySMAArrayに、ArraySetAsSeries関数を使ってAS_SERIESフラグを設定します。そのパラメータは次の通りです。

  • array[]:必要な配列
  • flag:配列のインデックス方向
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

CopyRates関数を使ってMqlRatesの履歴データを取得します。パラメータは次の通りです。

  • symbol:銘柄(現在の銘柄は_Symbol)または商品
  • time frame:時間枠の期間(現在の時間枠の期間は_period)
  • start position:始めのポジション
  • coun: コピーするデータ数
  • rates_array:コピー先の配列
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

CopyBuffer関数を使用して指標データバッファを取得します。そのパラメータは次の通りです。

  • indicator_handle:指標ハンドル(MA)
  • buffer_num:指標バッファ番号
  • start_pos:カウントを開始するポジション
  • count:コピーする量
  • buffer[]:対象の配列
CopyBuffer(simpleMA,0,0,3,mySMAArray);

前回、前々回終値、前回、前々回SMA値の定義

   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

整数bars変数を作成し、iBarsに代入します。

int bars=iBars(_Symbol,PERIOD_H1);

barsTotalがbars変数と等しくない場合、バーを確認します。

if(barsTotal != bars)

barsTotal値が互いに等しくない場合、バーと等しくなるように更新します。

barsTotal=bars;

前回の終値が前回のSMAの値より小さかった後、前回の終値が前回のSMAの値より大きければ、ストラテジーが取引を開始する条件を確認します。

if(prevClose<prevSMAVal && lastClose>SMAVal)

MqlTradeRequest関数に関連する適切な変数を使用して成行買い注文を開きます。

         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

前回の終値が前回のSMA値より大きかった後、前回の終値が前回のSMA値より小さかった場合、ストラテジーが売り取引を開始する条件を確認します。

if(prevClose>prevSMAVal && lastClose<SMAVal)
MqlTradeRequest関数に関連する適切な変数を使用した成行売り注文の開始
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);

以下は、OrderSend()関数を使用してこのタイプの取引システムを作成するための、1ブロック内の完全なコードです。

//+------------------------------------------------------------------+
//|                                     OrderSend_Trading_system.mq5 |
//+------------------------------------------------------------------+
int simpleMA;
int barsTotal;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_BUY;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         request.sl = Ask-(500*_Point);
         request.tp = Ask+(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         request.action = TRADE_ACTION_DEAL;
         request.type = ORDER_TYPE_SELL;
         request.symbol = _Symbol;
         request.volume = 0.1;
         request.type_filling = ORDER_FILLING_FOK;
         request.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         request.sl = Bid+(500*_Point);
         request.tp = Bid-(1000*_Point);
         request.deviation = 50;
         OrderSend(request, result);
        }
     }
  }

CTradeクラス

OrderSend()関数で注文を出す方法を学んだ後、取引関数にアクセスする簡単な方法があります。MQL5が提供するCTradeの既製クラスを使用することもできますし、より個人的な好みに合わせて独自のクラスを作成することもできます。では、CTradeの既成クラスをMQL5でどのように使うことができるかを説明しましょう。CTradeクラスについての詳細はMQL5リファレンスで確認できます。

まず、CTradeクラスのインクルードファイルは、MetaTrader 5のインストールファイルのincludeフォルダ内のTradeフォルダにあります。必要なのは、EAにこのファイルをインクルードし、以下のようにすべての取引関数を呼び出して使用することです。

#include <Trade\Trade.mqh>

CTradeクラスからオブジェクトを作成します

CTrade trade;

その後、ドット(.)と目的の関数の前にtradeを使用することで、CTradeクラスのすべての取引関数を使用できるようになります。注文を使った操作、ポジションを使った操作、最後のリクエストパラメータへのアクセス、最後のリクエスト確認結果へのアクセス、最後のリクエスト実行結果へのアクセスなど、すべての機能を使うことができます。

2つのメソッドの違いを理解するために、OrderSend()のときと同じように、いくつかの重要な関数について言及します。以下の方法について理解します。

  • 成行注文
  • 損切りと利食いの追加
  • 指値注文
  • 指値注文の変更
  • 指値注文の削除

成行注文

取引オブジェクトを作成したら、PositionOpen関数を使って成行注文を出します。

  • symbol:必要な銘柄
  • order_type:ポジションを建てる際の注文タイプ
  • volume:ロットサイズ
  • price:ポジションを開く価格
  • sl:損切り価格
  • tp:利食い価格
  • comment:コメントまたはNULLを指定

以下はその一例です。

trade.PositionOpen(
   _Symbol,             //to be applied for the current symbol
   ORDER_TYPE_BUY,      //to place buy order
   0.1,                 //lot size or volume
   Ask,                 //opening price of the order - current ask
   Ask-(500*_Point),    //sl
   Ask+(1000*_Point),   //tp
   NULL                 //NULL
);

PositionOpenの代わりにBuySellといったCTradeの追加メソッドを使って成行注文を出すこともできます。

損切りと利食いの追加

PositionModify関数を使用して、銘柄またはチケット番号でポジションを変更することができます。パラメータは次の通りです。

  • symbolまたはticket:銘柄で変更する場合は銘柄名を、チケットで変更する場合はチケット番号を指定
  • sl:新しい損切り価格
  • tp:利食い価格

次は、銘柄による変更の例です。

trade.PositionModify(
   EURUSD,       //the symbol name
   1.06950,      //the new sl
   1.07100,      //the new tp
);

次は、チケットによる変更の例です。

trade.PositionModify(
   ticket,       //the ticket variable that holds the needed ticket number to modify
   1.06950,      //the new sl
   1.07100,      //the new tp
);

指値注文

CTradeクラスを使用して保留注文を発注する必要がある場合は、OrderOpen関数を使用できます。パラメータは次の通りです。

  • symbol:銘柄名
  • order_type:指値注文のタイプ
  • volume:ロットサイズ
  • limit_price:ストップリミット価格
  • price:指値注文の執行価格
  • sl:損切り
  • tp:利食い価格
  • type_time:有効期限によるタイプの指定
  • expiration:有効期限
  • comment:必要に応じてコメントを指定

次の例は、OrderOpen関数を使用して買い指値の指値注文を発注する場合です。

         trade.OrderOpen(
            "EURUSD",                 // symbol
            ORDER_TYPE_BUY_LIMIT,     // order type
            0.1,                      // order volume
            0,                        // StopLimit price
            1.07000,                  // execution price
            1.06950,                  // Stop Loss price
            1.07100,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            ""                        // comment
         );

指値注文の変更

発注された指値注文を変更する必要がある場合は、CTradeクラスのOrderModify関数を使って変更することができます。パラメータは次の通りです。

  • ticket:変更する指値注文チケット
  • price:新しい執行価格
  • sl:新しい損切り価格
  • tp:新しい利食い
  • type_time:有効期限によるタイプの指定
  • expiration:期限切れdatatime変数
  • stoplimit:指値注文の価格

以下は、指値注文を変更する例です。

         trade.OrderModify(
            ticket,                   // ticket number of the pending order to modify
            1.07050,                  // execution price
            1.07000,                  // Stop Loss price
            1.07150,                  // Take Profit price
            ORDER_TIME_SPECIFIED,     // type by expiration
            D'2023.08.31 00.00',      // expiration
            0,                        // StopLimit price
         );

指値注文の削除

指値注文を削除する必要がある場合は、OrderDelete関数を使用します。削除するには指値注文のチケット番号が必要です。以下はその機能の例です。

         trade.OrderDelete(
            ticket,                 // tick number of the pending order to delete
         );

CTradeクラスアプリケーション

OrderSend()を使用して作成したのと同じ取引システムを作成する必要があります。両者の関数の動作の違いを理解するためにCTradeクラスを使用します。

以下は、CTradeクラスを使ってこの取引システムを作成するための唯一の異なるステップであり、残りのステップは前回と同じです。

プリプロセッサ#includeを使用したTradeインクルードファイルのインクルード

#include <Trade\Trade.mqh>

CTradeクラスから取引オブジェクトを作成

CTrade trade;

買い条件が満たされたら、PositionOpenを使用し、注文タイプをORDER_TYPE_BUYにするか、次のコードと同じ買いメソッドを追加します。

trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);

売り条件が満たされたら、注文タイプORDER_TYPE_SELLと共にPositionOpenを使用するか、以下のコードと同じように追加の売りメソッドを使用します。

trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);

以下はCTradeクラスを使って取引システムを作成する全コードである:

//+------------------------------------------------------------------+
//|                                        CTrade_Trading_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
int simpleMA;
int barsTotal;
CTrade trade;
int OnInit()
  {
   simpleMA = iMA(_Symbol, PERIOD_H1, 50, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,PERIOD_H1);
   return(INIT_SUCCEEDED);
  }
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double prevClose=(priceArray[2].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,PERIOD_H1);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.Buy(0.1,_Symbol,Ask,Ask-(500*_Point),Ask+(1000*_Point),NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.Sell(0.1,_Symbol,Bid,Bid+(500*_Point),Bid-(1000*_Point),NULL);
        }
     }
  }

結論

この記事を読み終えた方は、MQL5で注文、ポジション、取引がどのように機能するかを理解していると思われます。さらに、OrderSendメソッドとCTradeメソッドという2つの取引操作メソッドを使って、スムーズに取引システムを作る方法を理解します。

成行注文と指値注文の発注、損切りと利食いの追加、指値注文の修正、指値注文の削除を、2つの方法を使ってどのようにおこなうかを確認しました。

2つの方法を使って同じ移動平均クロスオーバー取引システムを作成する2つの簡単なアプリケーションを提供したので、アプリケーションを作成するために、前のすべてを適用する方法を理解したことになっています。

  • OpenSend_Trading_System
  • CTrade_Trading_System

ここで述べたアプリケーションの目的は、それらの違いを実践的に理解することです。

取引操作をおこなう際に、既製のCTradeクラスを使用することがいかに簡単か、ご理解いただけたと思います。一般的にプログラミングでクラスを使用する場合の他の機能に加えてに加えてです。

MQL5のオブジェクト指向プログラミングについてもっと知りたい方は、以前の「MQL5オブジェクト指向プログラミング(OOP)について」稿をお読みください。MQL5は、取引ソフトウェアをスムーズかつ簡単に開発作成するためのツールを私たちに提供するために、多大な労力と努力を払ってくれました。

この記事が役に立ち、多くの有益な見識を得て、これらの見識を理解し、仕事を簡単にこなせるようになることを願っています。私の記事をもっと読みたい場合は、最も人気のあるテクニカル指標を使った取引システムの作成方法などに関する多くの記事が私の出版リストに掲載されていますので、そちらをご覧ください。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13229

リプレイシステムの開発 - 市場シミュレーション(第16回):新しいクラスシステム リプレイシステムの開発 - 市場シミュレーション(第16回):新しいクラスシステム
もっと仕事を整理する必要があります。コードはどんどん大きくなっており、今やらなければ不可能になります。分割して征服しましょう。MQL5では、このタスクを実行するのに役立つクラスを使用することができますが、そのためにはクラスに関する知識が必要です。おそらく初心者を最も混乱させるのは継承でしょう。この記事では、これらのメカニズムを実用的かつシンプルな方法で使用する方法を見ていきます。
価格変動モデルとその主な規定(第3回):証券取引所の投機の最適なパラメータを計算する 価格変動モデルとその主な規定(第3回):証券取引所の投機の最適なパラメータを計算する
確率論に基づき著者が開発した工学的アプローチの枠組みの中で、利益を生むポジションを建てるための条件を見つけ、最適な(利益を最大化する)利食いと損切りの値を計算します。
MetaTrader 5でのモンテカルロ並べ替え検定 MetaTrader 5でのモンテカルロ並べ替え検定
この記事では、Metatrader 5のみを使用して、任意のエキスパートアドバイザー(EA)でシャッフルされたティックデータに基づいて並べ替え検定を実施する方法を見てみましょう。
リプレイシステムの開発 - 市場シミュレーション(第15回):シミュレーターの誕生(V) - ランダムウォーク リプレイシステムの開発 - 市場シミュレーション(第15回):シミュレーターの誕生(V) - ランダムウォーク
この記事では、私たちのシステムのシミュレーターの開発を完成させます。ここでの主な目的は、前回の記事で説明したアルゴリズムを設定することです。このアルゴリズムは、ランダムウォークの動きを作り出すことを目的としています。したがって、今日の資料を理解するためには、過去の記事の内容を理解する必要があります。シミュレーターの開発をフォローしていない方は、この一連の流れを最初から読まれることをお勧めします。さもないと、ここで説明されることがわからなくなるかもしれません。