MQL4ブック MT4

オーダーの終了と削除

スポンサードリンク

オーダーの終了と削除

 

マーケット注文の終了

市場受注を終了するための取引要求は、OrderClose()関数を使用して形成されます。

関数 OrderClose()

 bool OrderClose ( int ticket , double lots , double price , int slippage , color Color = CLR_NONE )

これは、市場の注文を閉じるために使用される関数です。 取引が正常に実行されると、この関数はTRUEを返します。 取引が失敗した場合はFALSEを返します。

パラメーター:

ticket - オーダーの一意の番号

lots - 閉じられるロットの量。 注文のロットの利用可能な量よりも少ない値を指定することは許可されています。 この場合、取引要求が正常に実行された場合、注文は部分的に閉鎖されます。

Price - クローズ価格。 このパラメータは、取引を実行するために受け入れられる要件および制限に従って設定されます(取引注文の特性とルール、および付録3を参照)。 価格の流れで市場の注文を終了するために要求された価格がない場合、またはそれが時代遅れである場合、この取引要求は却下される。 価格が時代遅れであるが価格の流れで見つかったと同時に、スリッページ価値内の現在の価格範囲からの逸脱である場合、取引要求はクライアント端末によって受け入れられ、取引サーバに送られる。

Slippage - 注文を終了するために要求された価格の、市場価格からの許容最大偏差(ポイント単位)。

Color - チャート内の閉じる矢印の色。 このパラメータが使用できない場合、またはその値がCLR_NONEの値と等しい場合、矢印はグラフに表示されません。

 

プログラムに、閉鎖される注文のタイプ、その固有の番号、閉鎖されるロットの金額に関する情報が含まれている場合、注文を閉じるのは非常に簡単です。 このためには、プログラムコード内でプリセットパラメータを使用してOrderClose()関数呼び出しを使用する必要があります。 たとえば、注文Buyの一意の番号が12345で、0.5ロットを閉じる場合は、注文を閉じる関数の呼び出しは次のようになります。

  OrderClose ( 12345, 0.5, Bid, 2 ) ;

どのような注文とどのような順序で閉じなければならないかを決定するためには、現状で開かれたすべての注文のデータを持たなければなりません。 MQL4には、任意の順序を特徴付けるさまざまなデータを取得するために使用できるいくつかの関数があります。 たとえば、関数OrderOpenPrice()は、注文オープン価格(または保留中の注文の要求価格)を返し、関数OrderLots()はロット数を返し、関数OrderType()は注文の種類を返し、 OrderSelect()関数によって選択されたオーダーへの実行時に、オーダー特性呼び出しの値を返すすべての関数。

 

関数OrderSelect()

注文のパラメータ(マーケットや保留中、未決済、または未決済)を取得するには、まずOrderSelect()関数を使用してパラメータを選択する必要があります。

  bool OrderSelect  int index, int select, int pool = MODE_TRADES 

OrderSelectは、それ以降の操作のための注文を選択する関数です。 関数が正常に実行された場合、TRUEを返します。 それ以外の場合は、FALSEを返します。

パラメーター:

index - 順序の位置または数.2番目のパラメータによって異なります。

select - 選択メソッドのフラグ パラメータ 'select'は、次の2つの値のいずれかをとります。

SELECT_BY_POS - パラメータ 'index'で、リスト内の注文番号が返されます(番号付けは0から始まります)。

SELECT_BY_TICKET - パラメータ 'index'にチケット番号(一意の注文番号)が返されます。

pool - 選択するデータソース パラメータ 'select'がSELECT_BY_POSの値と等しい場合、パラメータ 'pool'が使用されます。 注文番号がチケット番号(SELECT_BY_TICKET)で選択されている場合、パラメータ 'pool'は無視されます。 パラメータ 'pool'には、次の2つの値があります。

MODE_TRADES(デフォルトでは) - 注文は、未決済注文、すなわち、「ターミナル」ウィンドウの「取引」タブに表示されている注文の中から選択されます。

MODE_HISTORY - 注文は、閉じられた注文や削除された注文、つまり、[端末]ウィンドウの[アカウント履歴]タブに表示された注文の中から選択されます。 この場合、閉じられた注文と削除された注文を表示するためにユーザーが指定した履歴の深さが重要です。

 

市場の注文を閉じるために取引関数を使用する方法を実証するために、問題を解決しよう:

問題28アカウントで利用可能なマーケット注文の1つをクローズするスクリプトを書く。 スクリプトの実行によって、マウスを使用してシンボルウィンドウにアタッチされたスクリプトの場所に最も近い注文が閉じられる必要があります。

記号Eur / UsdとUsd / Chfに対して開かれている保留中の注文について、端末に3つの市場注文が開かれていると仮定する。

イチジク。 90.異なるシンボルに対して開いた複数の注文を端末ウィンドウに表示する。

マウスでドラッグして「ナビゲータ」ウィンドウからシンボルウィンドウにドラッグできるスクリプトを作成すると、マーケットオーダーの1つ、つまりカーソルに最も近い順序(つまり、ユーザーがマウスボタンを放した)。 Fig。 91の場合、カーソルが売り注文4372889に最も近い代替案を見ることができます。これは、スクリプト実行の結果として閉じなければならない注文です。

イチジク。 91.選択した注文を閉じるために使用されるcloseorder.mqのスクリプト。

この問題を解決するには、スクリプトがドロップされたウィンドウ内で、シンボルに対して開いたものだけをすべての注文の中から選択する必要があります(OrderSymbol()関数を使用)。 次に、選択されたすべての市場指図のオープン価格を見つける(つまり、各注文に対してOrderOpenPrice関数を連続して実行する)。注文のオープンプライスを知っているので、我々は問題のステートメントに対応するそれらの1つを簡単に選択することができます。 関数OrderClose()のパラメータの適切な値を指定するには、選択した注文に関する他のデータも知っておく必要があります:ロットの量(関数OrderLots()によって決まる)と一意の注文番号関数OrderTicket())。 さらに、双方向見積もりの​​1つまたは別の価格を見つけるためには、注文のタイプ(関数OrderType()によって決定される)を知る必要があります。

上記の注文特性を得るために、どのパラメータをOrderSelect()関数で指定しなければならないかを考えてみましょう。

まず、注文選択方法を選択する必要があります。 私たちの問題では、選択方法は問題文そのものによって決まります。注文番号に関するデータは、実行スクリプトを起動する瞬間にはプログラムで使用できないと考えられます。つまり、プログラムにはブロックが含まれているとみなされます。それらの注文番号を決定します。 つまり、「端末」(図64.1)に表示されるすべての注文を1つずつ確認する必要があるため、パラメータSELECT_BY_POSを使用する必要があります。

注文の選択源も明白です。 この問題を解決するには、クローズと削除された注文を分析する必要はありません。 この場合、マーケットオーダーにのみ関心がありますので、OrderSelect()関数でMODE_TRADESパラメータを使用して検索します。 パラメータ 'pool'では、MODE_TRADESのデフォルト値が関数ヘッダーに指定されているので、スキップすることができます。

市場および未決注文を分析するためのブロックを構築する方法を以下に示します。

  for  int i = 1 ; i <= OrdersTotal () ; i ++  //すべての注文のサイクル。 
  { //端末に表示される 
  if  OrderSelect  i - 1  SELECT_BY_POS  == true  //次のものがあれば 
  { 
  //特性を注文します。 
  // ..ここで分析する必要があります 
  } 
  } //サイクルボディの終わり

サイクル演算子の見出しでは、初期値はi = 1として指定されますが、サイクルを終了する条件は式i <= OrdersTotal()です。 関数OrdersTotal()は、市場および保留中の注文の合計金額、つまり[端末]ウィンドウの[取引]タブに表示されている注文を返します。 これは、多くの受注が取引に参加するのと同じくらい多くの繰り返しが周期内に存在する理由です。

各反復で、条件が演算子 'if'で計算されると、関数OrderSelect(i-1、SELECT_BY_POS)が実行されます。 以下の重要事項をここに記載しなければなりません:

市場および保留中の注文のリスト内の注文の番号付けはゼロから始まります。

これは、リスト(図90)の最初の注文がゼロの位置に置かれ、2番目の注文の位置が1、3番目の注文の番号が2などであることを意味します。これが、関数OrderSelect()を呼び出すと、indexの値はi-1として与えられます。 したがって、選択されたすべての注文について、このインデックスは常に変数iの値よりも1少ない(次の繰り返しの数と一致する)。

関数OrderSelect()は、注文が正常に選択された場合にtrueを返します。 注文選択が失敗する可能性があることを意味します。 これは、処理中に注文量が変更された場合に発生します。 MQL4でプログラミングする場合は、アプリケーションプログラムがリアルタイムモードで動作し、いくつかのパラメータを処理している間に、これらのパラメータの値が変化する可能性があることを忘れないでください。 例えば、受注の開閉と未受注の受注の変更の結果、市場の受注額が変わる可能性があります。 注文処理をプログラミングする際には、次のルールを守る必要があります。注文はできるだけ早く処理する必要がありますが、この処理を担当するプログラムブロックは、可能であれば冗長なプログラム行を含むべきではありません。

図1に示すコードによれば、 64.3、演算子 'if'のヘッダで、プログラムは、選択された瞬間に次の注文が注文リストで利用可能かどうかを分析します。 次の注文が利用可能であれば、コントロールは注文パラメータを処理するために演算子 'if'の本体に渡されます。 このような構成は、競合の可能性がある場合には、パラメータの処理中に順序が失われる可能性があるため、あまり役に立たないことに注意する必要があります。 しかし、その選択の瞬間に、注文がもう利用できない場合、この解決策は最も効率的であることが分かります。 演算子 'if'の本体で、選択された注文のパラメータが分析されます。 OrderOpenPrice()、OrderTicket()、OrderType()などの関数を実行すると、関数OrderSelect()の実行結果として選択された順序の特定の特性の値が返されます。

問題28を解決するプログラムでは、上記の推論がすべて使用されました。

マーケットオーダーのクローズを意図した単純なスクリプトの例。公開価格は他の注文のオープンプライス( closeorder.mq4 )よりもスクリプトの添付ファイルの場所に近い。

 

 // ------------------------------------------------ -------------------------------------- 
  // closeorder.mq4 
  // コードは教育目的でのみ使用する必要があり ます。 
  // ------------------------------------------------ --------------------------------- 1  -  
  int start () //特別な関数 'start' 
  { 
  string Symb = Symbol () ;  //シンボル 
  double Dist = 1000000.0 ;  //プリセット 
  int Real_Order =  - 1 ;  //まだマーケット注文はありません 
  double Win_Price = WindowPriceOnDropped () ;  //スクリプトはここにドロップされます 
  // ------------------------------------------------ -------------------------------- 2  -  
  for  int i = 1 ; i <= OrdersTotal () ; i ++  //検索サイクルの順序 
  { 
  if  OrderSelect  i - 1  SELECT_BY_POS  == true  //次のものが利用可能な場合 
  { //注文分析: 
  // ------------------------------------------------ ----------------------- 3  -  
  if  OrderSymbol () != Symb  続きます   //シンボルは私たちのものではありません 
  int Tip = OrderType () ;  //オーダータイプ 
  if  Tip > 1 )を 続ける   //保留中の注文 
  // ------------------------------------------------ ----------------------- 4  -  
  double Price = OrderOpenPrice () ;  //注文価格 
  if  NormalizeDouble  MathAbs  Price - Win_Price   Digits  < / / Selection 
  NormalizeDouble  Dist  Digits )) //最も近い順序の// 
  { 
  Dist = MathAbs  Price - Win_Price  ;  //新しい値 
  Real_Order = ヒント   //利用可能な市場の注文 
  int Ticket = OrderTicket () ;  //チケットを注文する 
  double Lot = OrderLots () ;  //ロット数 
  } 
  // ------------------------------------------------ ----------------------- 5  -  
  } //終了時の分析 
  } //オーダー検索の終了 
  // ------------------------------------------------ -------------------------------- 6  -  
  while  true  //注文終了サイクル 
  { 
  if  Real_Order ==  - 1  //マーケット注文が利用できない場合 
  { 
  Alert ( "    "  Symb  " no market orders available " ) ; 
  break;  //終了サイクルを終了する 
  } 
  // ------------------------------------------------ -  -  -  -  -  -  -  -  -  -  -  -  -  7  -  
  switch  Real_Order  //注文タイプ別 
  { 
      case 0  double Price_Cls = Bid ;  //注文を購入する 
          string Text = " 購入 " ;  //購入用のテキスト 
          break;  //Изswitch 
      case 1  Price_Cls = Ask ;  // 注文 販売 
          Text = " 売る " ;  // 販売の ためのテキスト 
  } 
  Alert ( "閉じようとする", Text, Ticket,  " 応答を待っている.. " ) ; 
  bool Ans = OrderClose ( Ticket, Lot, Price_Cls, 2 ) ;  //注文の終了 
  // ------------------------------------------------ -------------------------- 8  -  
  if  ( Ans == true ) //見つかりました!  :) 
  { 
  Alert ( "クローズドオーダー ", Text, Ticket ) ; 
  break;  // 終了サイクルを終了する 
  } 
  // ------------------------------------------------ -------------------------- 9  -  
  int Error = GetLastError () ;  //失敗しました:( 
  switch  Error  //オーバーフロー可能なエラー 
  { 
  ケース 135  アラート  " 価格が変更されました。再試行します.. "  ; 
  RefreshRates () ;  //データを更新する 
  続ける ;  //次の繰り返しで 
  ケース 136  アラート  " 価格がない。新しいチックを待っている.. "  ; 
  while  RefreshRates () == false  //新しいチックに 
  睡眠  1  ;  //サイクルスリープ 
  続ける ;  // 次の繰り返しで 
  ケース 146  アラート   取引サブシステムはビジー状態です  
  睡眠  500  ;  //単純な解 
  RefreshRates () ;  // データを更新する 
  続ける ;  // 次の繰り返しで 
  } 
  switch  エラー  //重大エラー 
  { 
  ケース 2  アラート   一般的なエラー    
  休憩   // exit 'switch' 
  ケース 5  アラート  " クライアント端末の古いバージョン "  ; 
  休憩   // exit 'switch' 
  ケース 64  警告  " アカウントはブロックされています。 "  ; 
  休憩   // exit 'switch' 
  ケース 133  アラート   取引が禁止されています    
  休憩   // exit 'switch' 
  デフォルト  アラート   発生エラー   エラー    //その他の選択肢 
  } 
  休憩   // 終了サイクルを終了する 
  } 
  // ------------------------------------------------ ------------------------------- 10  -  
  アラート   スクリプトは操作を完了しました-----------------------------   ; 
  return ;  // Exit start() 
  } 
  // ------------------------------------------------ ------------------------------- 11  - 

closeorder.mqプログラムの全コードは、特殊関数start()に集中しています。 ブロック1-2では、いくつかの変数が初期化される。 変数Distは、スクリプトがドロップされた場所から最も近い順序までの距離です。 変数Real_Orderは、クライアント端末に少なくとも1つのマーケットオーダーの利用可能性(非負の値)を表示するフラグです。 変数Win_Priceは、ユーザーがスクリプトをシンボルウィンドウに添付した価格です。 ブロック2-6では、注文が分析される。利用可能な注文のうちの1つが閉鎖されるように割り当てられる。 ブロック6-10は注文を終了し、取引の実行中に発生する可能性のあるエラーを処理するブロックである。

ユーザがスクリプトを記号ウィンドウに添付した瞬間から、変数の値はブロック1-2で計算され、変数Win_Priceはユーザがスクリプトを添付したレベルで価格の値をとる。 この場所に最も近い注文(その特性とともに)を見つける必要があります。

'for'サイクル(ブロック2-6)では、注文が検索されます。ブロック2-3では、プログラムは「端末」の次の行に注文があるかどうかをチェックします。 注文が見つかった場合、その注文の特性を取得して分析するために、コントロールは演算子 'if'の本体に渡されます。 ブロック3-4において、間違った記号(プログラムが実行されている記号ではない)に対して開かれた注文は、フィルタリングされて取り除かれる。 私たちの場合、それはUsd / Chfのために開かれた注文4372930です。 関数OrderSymbol()は、選択した注文のシンボル名を返します。 このシンボル名がプログラムの実行中のもの以外の場合、現在の反復は中断され、別のシンボルに対して開かれた順序が処理されなくなります。 分析中の注文が「私たちの」シンボルのために開かれていると判明した場合、もう1つのチェックが行われます。 注文タイプは、関数OrderType()を使用して決定されます( 取引のタイプを参照)。 注文タイプが1より大きい場合は、注文が保留中であることを意味します。 この場合、保留中の注文には関心がないので、現在の繰り返しも中断されます。 この例では、このような順序がありますが、別のシンボルのために開かれているので、すでにフィルタされています。 ブロック3-4を成功裏に通過した注文は全て市場のものです。

ブロック4-5は、先行するブロックを首尾よく通過したすべてのマーケット注文のうちの1つの注文のみを選択することを意図している。 この注文は、事前定義された価格(変数Win_Priceの値)に最も近いものでなければなりません。 ユーザーはマウスカーソルで注文行を「特定」する必要はありません。 実行のためにスクリプトを起動する時点で他の注文よりもカーソルに近い注文が選択されます。 処理された注文のオープンプライスは、OrderOpenPrice()関数を使用して検索されます。 現在の注文の価格と「カーソル価格」との間の距離の絶対値が前の注文の同じ距離よりも小さい場合、現在の注文が選択される(距離の絶対値は、オーダーラインの下または上のカーソル位置の影響)。 この場合、この注文は、閉鎖のためのフロントランナーとしての 'for'サイクルの現在の反復で記憶される。 この注文については、ブロック4-5の最後に、チケット番号(注文の個数)とロットの金額が計算されます。 この例(図90)では、受注総額が4つ(市場3つと保留の1つの注文)であるため、 'for'サイクルで4回の繰り返しが実行され、閉じるために必要なすべてのデータが検索されます選択された1つの注文の

次に、実行中のプログラムの制御がサイクル演算子 'while'に渡される(ブロック6-10)。 ブロック6-7において、発見された市場注文が利用可能かどうかが検査される。ブロック2-4でマーケット注文が見つからない場合(これはかなり可能である)、Real_Orderフラグの値は-1のままであり、市場注文が利用できないことを意味する。 ブロック6-7でのチェックがマーケット注文を検出しなかった場合、サイクル「while」の実行は破られ、プログラムはその動作を終了する。 変数Real_Orderの値が0または1に等しいことが判明した場合、これはマーケットがクローズのためにあらかじめ定義されており、クローズする必要があることを意味します。

ブロック7-8において、注文タイプにしたがって注文の終値が計算される。 これは、買い注文のための入札の値、および売り注文のためのAskの値です( 取引行う際の要件と制限を参照)。

ブロック7-8において、補助変数Textの値が計算される。 注文完了のための取引要求は、以下の行のOrderClose()関数で形成されます。

 bool Ans = OrderClose  Ticket  Lot  Price_Cls  2  ;  //注文の終了

Trade関数OrderClose()は、取引が成功した場合はtrueを返し、成功しなかった場合はfalseを返します。 取引要求がサーバー上で正常に実行されると、値 'true'が変数Ans(answer)に割り当てられます。 この場合、ブロック8-9を実行するとき、プログラムはユーザに注文完了の成功を知らせる。 その後、サイクル演算子 'while'の実行が停止され、プログラムの動作は終了します。 そうでなければ、制御はブロック9-10に進み、クライアント端末からプログラムに返されたエラーを分析する。

ブロック9-10の開始時に、エラーコードが計算される。 その後、エラーコードに従って、プログラムの終了または繰り返し動作が実行される。 第1のオペレータ 'スイッチ'では、プログラムが暗黙的に耐え難いエラーを処理します。つまり、エラーは取引を実行する際に一時的な困難とみなすことができます。 このようなエラーごとにすべての必要なアクションが実行され、現在の反復が停止され、サイクル 'while'の実行が再開されます。 (この例では、演算子 'continue'の使用の結果として出て来る演算子 'switch'をエラー処理するために使用することに注意してください。この構成は、オペレータ 'スイッチ'が外部サイクルオペレータ 'while'の内容の一部であり、オペレータ 'continue'がオペレータ 'のヘッダに制御を渡すことによって現在の反復を中断するという理由だけで機能する' )。

エラーコードが最初の演算子 'switch'で処理されない場合、このエラーは重大であるとみなされます。 この場合、コントロールは、第2のオペレータ 'スイッチ'に渡され、これは、ユーザに1つまたは別の重大なエラーが発生したことを知らせるために実行されます。 さらに、プログラムは、 'while'サイクルの実行を中断する演算子 'break'を使用します。 何らかの理由でサイクル 'while'を終了すると、プログラム動作の終了に関するメッセージを生成するブロック9-10に制御が渡される。 演算子 'return'は、特殊関数start()の実行を停止し、プログラムはその操作を終了します。

指定された条件(図90と91を参照)でスクリプトを起動した後の実際の結果を以下に示します。 貿易はサーバー上で正常に行われました。

イチジク。 92. closeorder.mq4スクリプトが正常に実行された結果として受信されたメッセージ。

注文の1つが終了した結果、Eur / Usdのウィンドウに2つの注文が残っています。

イチジク。 スクリプトcloseorder.mq4を実行すると、注文の1つが終了します。

注文終了は、「ターミナル」ウィンドウにも表示されています。

イチジク。 94. closeorder.mq4スクリプトの実行後、2つのマーケット注文が「ターミナル」ウィンドウに表示されます。

後で、このスクリプトを使用して他の2つの注文もクローズされます。

 

保留中の注文の削除

保留中の注文を削除するための取引要求は、OrderDelete()関数を使用して形成されます。

関数OrderDelete()

  bool OrderDelete  int ticket  color arrow_color = CLR_NONE 

この関数は、以前に配置された保留中の注文を削除します。 正常に処理された場合はTRUEを返します。 それ以外の場合は、FALSEを返します。

パラメーター:

ticket - オーダーの一意の番号

arrow_color - グラフ内の矢印の色です。 このパラメータが使用できない場合、またはその値がCLR_NONEの値と等しい場合、矢印はグラフに表示されません。

関数OrderDelete()に、ボリュームの指定と、削除される注文の終了価格が含まれていないことは容易に分かります。

市場価格に関係なく注文は削除されます。 注文の部分的な削除も不可能です。 保留中の注文のロット数を2段階で減らすことができます。既存の注文を削除し、減少した(任意の)ロット数で新しい保留オーダーを配置します。

保留中の注文を削除するプログラムのアルゴリズムは、マーケットオーダーの締め切りと全く同じです。 保留中の注文を削除するために近い価格が必要ないという点でわずかな違いがあるため、以下のプログラムには市場価格を更新するブロックが含まれていません。

保留中の注文を削除するための単純なスクリプトの例。要求された価格は、他の保留中の注文( deleteorder.mq4 )の価格よりもスクリプトの添付ファイルの場所に近い。

 

 // ------------------------------------------------ ------------------------------------- 
  // deleteorder.mq4 
  // コードは教育目的でのみ使用する必要があり ます。 
  // ------------------------------------------------ -------------------------------- 1  -  
  int start () // 特別な関数 'start' 
  { 
  文字列 Symb = Symbol () ;  //シンボル 
  double Dist = 1000000.0 ;  //プリセット 
  int Limit_Stop = -1 ;  // まだ保留中の注文はありません 
  double Win_Price = WindowPriceOnDropped () ;  // スクリプトはここにドロップされます 
  // ------------------------------------------------ -------------------------------- 2  -  
  for  int i = 1 ; i <= OrdersTotal () ; i ++  // 検索サイクルの順序 
  { 
  if  OrderSelect  i - 1  SELECT_BY_POS  == true  // 次のものが利用可能な場合 
  { // 注文分析  
  // ------------------------------------------------ ----------------------- 3  -  
  if  OrderSymbol () != Symb  続きます   // シンボルは私たちのものではありません 
  int Tip = OrderType () ;  // オーダータイプ 
  if  Tip > 2 )を 続ける   //マーケットオーダー 
  // ------------------------------------------------ ----------------------- 4  -  
  double Price = OrderOpenPrice () ;  // 注文価格 
  if  NormalizeDouble  MathAbs  Price - Win_Price   Digits  > // 選択 
  NormalizeDouble  Dist  Digits )) // 最も近い順序の //        
  { 
  Dist = MathAbs  Price - Win_Price  ;  // 新しい値 
  Limit_Stop = ヒント   //利用可能な保留中の 注文 
  int Ticket = OrderTicket () ;  // チケットを注文する 
  } //終わりの 'if' 
  } // 終了時の分析 
  } // オーダー検索の終了 
  // ------------------------------------------------ -------------------------------- 5  -  
  switch  Limit_Stop  // 注文タイプ別 
  { 
  ケース 2  文字列 Text = " BuyLimit " ;  // BuyLimitのテキスト 
  休憩   // exit 'switch' 
  ケース 3  テキスト = " SellLimit " ;  // SellLimitのテキスト 
  休憩   // exit 'switch' 
  ケース 4  Text = " BuyStopt " ;  // BuyStoptのテキスト 
  休憩   // exit 'switch' 
  ケース 5  テキスト = " SellStop " ;  // SellStopのテキスト 
  休憩   // exit 'switch' 
  } 
  // ------------------------------------------------ -------------------------------- 6  -  
  while  true  // 注文終了サイクル 
  { 
  if  Limit_Stop ==  - 1  // 使用可能な保留オーダーがない場合 
  { 
  アラート  " For "  Symb  " no pending orders available "  ; 
  休憩   // 終了サイクルを終了する         
  } 
  // ------------------------------------------------ -  -  -  -  -  -  -  -  -  -  -  -  -  7  -  
  アラート   削除を試みます    "  テキスト  "    "  チケット  "   応答を待っている.. "  ; 
  ブール Ans = OrderDelete  Ticket  ;  //注文の削除 
  // ------------------------------------------------ ---------------------- 8  -  
  if  Ans == true  // 見つかりました!  :) 
  { 
  アラート   削除された注文   テキスト     "  Ticket  ; 
  休憩   // 終了サイクルを終了する 
  } 
  // ------------------------------------------------ -------------------------- 9  -  
  int Error = GetLastError () ;  // 失敗しました :( 
  switch  Error  // オーバーフロー可能なエラー 
  { 
  ケース 4  アラート   取引サーバーがビジー状態です。再試行します..    
  スリープ  3000  ;  // 単純な解 
  続ける ;  // 次の繰り返しで 
  ケース 137  アラート  「ブローカーがビジー状態 です。再試行します..   ; 
  スリープ  3000  ;  // 単純な解 
  続ける ;  // 次の繰り返しで 
  ケース 146  アラート  "   取引サブシステムがビジー状態です。  再試行 .. "  ; 
  睡眠  500  ;  // 単純な解 
  続ける ;  // 次の繰り返しで 
  } 
  switch  エラー  // 重大エラー 
  { 
  ケース 2  アラート  "   一般的なエラー   "  ; 
  休憩   // exit 'switch' 
  ケース 64  警告  " アカウントはブロックされてい ます。 "  ; 
  休憩   // exit 'switch' 
  ケース 133  アラート  "   取引は禁止されて  ます  
  休憩   // exit 'switch' 
  ケース 139  アラート  「注文がブロックされ、処理中です。   "  ; 
  休憩   // exit 'switch' 
  ケース 145  アラート   変更禁止   
  "注文は市場に近すぎる   "  ; 
  休憩   // exit 'switch' 
  デフォルト  アラート  " 発生エラー    "  Error  ; // その他の選択肢    
  } 
  休憩   // 終了サイクルを終了する 
  } 
  // ------------------------------------------------ ------------------------------- 10  -  
  アラート   スクリプトは操作を完了しました -----------------------------   ; 
  return ;  // Exit start() 
  } 
  // ------------------------------------------------ ------------------------------- 11  - 

エラー処理ブロックも若干変更されています。 市場の注文を閉じる際に価格の変更(エラー135および136)に関連するエラーの可能性を考慮する必要がありますが、保留中の注文を削除するときはこのようなエラーは発生しません。 同じ理由で、関数RefreshRates()はプログラムのどこにも使われません。

エラー4やエラー137( エラーコード参照)などのエラーを処理するのは少し難しいかもしれません。 たとえば、エラー137が発生した場合、プログラムは「ブローカがビジー」であることを考慮に入れることができます。 しかし、自然な問題が発生します:ブローカーはいつ無料ですか、ユーザーは彼または彼女の取引を続行する? エラー137はそのような情報を提供しません。 このため、プログラマは、このようなエラーを適切に処理するプログラムを構築する方法を自分で決定する必要があります。単純なケースでは、要求はある休止(この例では3秒後)後に繰り返すことができます。 一方、一連の注文を削除しようとしても(または一般的には、閉じる、開いたり変更したりする)、サーバーはエラー141を返す可能性があります。 このエラーにより、 deleteorder.mq4スクリプトが機能しなくなります。 一般に、このような紛争はプログラミングの問題ではありません。 そのような場合は、ディーリングセンターのサポートサービスに連絡して、拒否理由を明らかにする必要があります。

保留中の注文(一般的には、市場注文の停止注文となり得る)が市場価格に近すぎると、エラー145が発生する可能性があります。 あなたが静かな市場で着実に取引している場合、このエラーは発生しません。 価格が急激に変化した場合、ブローカーは特定の注文がすぐに開かれると判断して、ブローカーがその注文を削除または変更することを許可しません。 このエラーは、スクリプト内で重要なものとみなされ、プログラムの終了につながります(取引要求でブローカを悩ますことは意味がありません)。 しばらくして価格が変更された場合は、再度実行するためにスクリプトを起動して注文を削除しようとすることができます。

通常、取引センターによって設定された凍結レベルを考慮すると、エラー145の発生を防ぐことができます。 フリーズレベルは、オーダーが「凍結」とみなされる価格帯を決​​定する値です。つまり、それを削除することは禁止されています。 たとえば、保留中の注文が1.2500に、凍結レベルが10ポイントに等しい場合、価格が1.2490から1.2510の範囲であれば、保留中の注文の削除は禁止されていることを意味します。 要求識別子MODE_FREEZELEVELを使用してMarketInfo()関数を実行したフリーズレベル値を取得できます。

 

反対注文のクローズ

反対注文は、同じシンボルに対して開かれた別の市場指図の方向とは反対の方向に開かれた市場注文です。

特定のシンボルに対して2つの反対の注文がある場合は、OrderCloseBy()関数を使用してそれらを同時に閉じることができます。 このような操作を実行すると、1つのスプレッドを保存します。

関数OrderCloseBy()

 bool OrderCloseBy ( int ticket , int opposite , color Color = CLR_NONE )

この関数は、同じシンボルに対して反対方向に開かれた別の市場指図によって1つの市場指図を終了します。 この関数は、正常に完了するとTRUEを返し、失敗した場合はFALSEを返します。

パラメーター:

ticket - 閉じる順序の一意の番号

opposite - 反対の順序の一意の番号。

Color - チャート内の閉じる矢印の色。 このパラメータが使用できない場合、またはその値がCLR_NONEの値と等しい場合、矢印はグラフに表示されません。

逆の注文が同じ音量である必要はありません。 逆の注文で注文を締め切ると、取引量は、注文量の少ない注文量で実行されます。

例を考えてみましょう。 クライアント端末には同じボリュームの2つのマーケットオーダー、BuyとOne Sellがあります。 OrderClose()関数を使ってそれぞれを別々に閉じると、我々の経済生産は各注文から得られた利益の合計になります:

イチジク。 OrderClose()関数を使用して注文を別々に処理した結果。

しかし、このような状況でOrderCloseBy()関数を使用して注文を反対に処理しようとすると、経済的生産は(1つの注文の広がりのコストに比例する)

イチジク。 96. OrderCloseBy()関数を使用して他の注文による注文を終了した結果。

ターミナルで反対の注文がクローズされる場合、OrderClose()ではなくOrderCloseBy()関数を使用することは経済的に妥当であることは明らかです。

逆の注文を締め切る際のスプレッドの節約については、より一般的な説明をする必要があります。 実際には、注文(例えば、買い注文)を開くことは、注文を閉じるのと同程度に反対方向(すなわち、売り注文)で注文を開くこととは反対の取引であることを意味する購入注文)。 言い換えれば、市場の秩序を崩すか、同じボリュームの反対の注文を開く(そして、両方の注文をお互いに閉じる)ことは、経済的に同じです。 これらの2つの選択肢の違いは、市場受注を支援するために転用する資金を計算するために、異なる取引センターで使用されるさまざまな方法でしか成立しない場合があります( 図85および図88を参照)。

逆の注文を閉じるには、OrderCloseBy()関数で近い価格を指定する必要がないこともわかります。 2つの反対注文の利益と損失が相互に返済するので、これは不要です。したがって、総経済生産量は市場価格に依存しません。 もちろん、このルールは同じ数量の注文に対してのみ有効です。 たとえば、1つのシンボルに対して2つの注文:1ロットの買い注文と0.7ロットの売り注文がある場合、この取引は0.3ロットの買い注文部分に関連する市場価格にのみ依存し、0.7ロット両方の注文はシンボル価格に依存しません。

反対の注文はトータルの取引結果に影響を与えません。 このため、反対注文の開設に基づく取引戦術には非公式の内容が含まれていない(このため、一部の取引センターは、一致したロット内の反対の注文を強制的に終了する)。 そのような戦術の唯一の(否定的な)影響力は、いくつかの取引センターで受け入れられた規則に従って資金を流用することにあります。 さらに、いくつかの逆の注文の利用可能性は、プログラムされた取引の文脈において、1つの注文よりも困難をもたらす。 様々なコミッションとスワップを(市場の注文ごとに別々に)検討すると、反対の注文を閉じる必要性が明らかになります。

シンボルの反対の注文( closeby.mq4 )をすべて閉じる単純なスクリプトの例。

 // ------------------------------------------------ -------------------- 
  // closeby.mq4 
  //コードは教育目的でのみ使用する必要があります。 
  // ------------------------------------------------ --------------- 1  -  
  int start () //特別な関数 'start' 
  { 
  string Symb = Symbol () ;  //シンボル 
  double Dist = 1000000.0 ;  //プリセット 
  // ------------------------------------------------ --------------- 2  -  
  while  true  //処理サイクル.. 
  { //反対の注文 
  double Hedg_Buy =  - 1.0 ;  // Max。  購入費用 
  double Hedg_Sell =  - 1.0 ;  // Max。  販売コスト 
  for  int i = 1 ; i <= OrdersTotal () ; i ++  //検索サイクルの順序 
  { 
  if  OrderSelect  i - 1  SELECT_BY_POS  == true  //次のものが利用可能な場合 
  { //注文分析: 
  // ------------------------------------------------ --- 3  -  
  if  OrderSymbol () != Symb  続きます   //シンボルは私たちのものではありません 
  int Tip = OrderType () ;  //オーダータイプ 
  if  Tip > 1 )を 続ける   //保留中の注文 
  // ------------------------------------------------ --- 4  -  
  スイッチ  ティップ  //注文タイプ別 
  { 
  case 0  // Order Buy 
  if  OrderLots () > Hedg_Buy  
  { 
  Hedg_Buy = OrderLots () ;  //最大値を選択します。  コスト 
  int Ticket_Buy = OrderTicket () ;  //チケットを注文する 
  } 
  休憩   //スイッチから 
  ケース 1  //売り注文 
  if  OrderLots () > Hedg_Sell  
  { 
  Hedg_Sell = OrderLots () ;  //最大値を選択します。  コスト 
  int Ticket_Sell = OrderTicket () ;  //チケットを注文する 
  } 
  } // 'switch'の終わり 
  } //終了時の分析 
  } //オーダー検索の終了 
  // ------------------------------------------------ --------- 5  -  
  if  Hedg_Buy < 0 || Hedg_Sell < 0  //利用可能な注文がない場合 
  { / /いくつかのタイプの 
  アラート   すべての反対の注文は閉じられています:)   ;  //メッセージ 
  return ;  // Exit start() 
  } 
  // ------------------------------------------------ --------- 6  -  
  while  true  //クローズサイクル 
  { 
  // ------------------------------------------------ -  -  -  7  -  
  アラート  " 近くにしようとする。応答を待っている.. "  ; 
  ブール Ans = OrderCloseBy  Ticket_Buy  Ticket_Sell  ;  //Закрытие 
  // ------------------------------------------------ ------ 8  -  
  if  Ans == true  //見つかりました!  :) 
  { 
  アラート  " 執行閉じる "  ; 
  休憩   //終了サイクルを終了する 
  } 
  // ------------------------------------------------ ------ 9  -  
  int Error = GetLastError () ;  //失敗しました:( 
  switch  Error  //オーバーフロー可能なエラー 
  { 
  ケース 4  アラート   取引サーバーがビジー状態です。再試行します..    
  スリープ  3000  ;  //単純な解 
  続ける ;  //次の繰り返しで 
  ケース 137  アラート   ブローカーがビジー状態です。再試行します..   ; 
  スリープ  3000  ;  //単純な解 
  続ける ;  //次の繰り返しで 
  ケース 146  アラート   取引サブシステムはビジー状態です  
  睡眠  500  ;  //単純な解 
  続ける ;  //次の繰り返しで 
  } 
  switch  エラー  //重大エラー 
  { 
  ケース 2  アラート   一般的なエラー    
  休憩   // exit 'switch' 
  ケース 64  警告  " アカウントはブロックされています。 "  ; 
  休憩   // exit 'switch' 
  ケース 133  アラート   取引が禁止されています    
  休憩   // exit 'switch' 
  ケース 139  警告   注文はブロックされ、処理中です  
  休憩   // exit 'switch' 
  ケース 145  アラート   変更禁止   
  " 注文は市場に近すぎる "  ; 
  休憩   // exit 'switch' 
  デフォルト  アラート  " 発生エラー "  エラー    //その他の選択肢 
  } 
  アラート   スクリプトは操作を完了しました--------------------------   ; 
  return ;  // Exit start() 
  } 
  } //処理サイクルの終わり 
  // ------------------------------------------------ -------------- 10  -  
  } // startの終わり() 
  // ------------------------------------------------ --------------------

上記のスクリプトのアルゴリズムは、前のスクリプトと少し異なります。 この相違点は、いくつかの注文(制限されない注文の金額)を正常に閉じるためには、同じコードを何度も実行しなければならないという点です。 このスクリプトは市場注文のランダムなセットでテストされました。 5つの異なる体積のオーダーが図1に示されている。 以下の97。

イチジク。 97.市場の注文は1つのシンボルのために開かれた。

利用可能な反対の注文を閉じるには、選択基準を事前に定義する必要があります。 与えられたアルゴリズムにおけるこの基準は、オーダサイズであり、より大きな体積のオーダが最初に閉じられ、次いでより小さな体積のオーダが閉じられる。 異なる量の反対の注文が閉じられた後、残りの注文の注文は残る。 例えば、反対注文の買い(1ロット)と売り(0.8ロット)は、注文(0.2ロット)が開かれたままの注文となります。 このため、更新が成功するたびに、プログラムは更新された注文リストを参照して、この更新されたリスト内の他の2つの大きな反対注文を見つけなければなりません。

上記の計算は、ブロック2-10において、(条件的に)連続的なサイクル「while」で実現される。 サイクルの初めに、各反復において、プログラムは特定の型の命令がもう存在しないと仮定する。 このために、値-1は変数Hedg_BuyとHedg_Sellに割り当てられます。 注文処理ブロックのアルゴリズムは、一般的に保存されています (closeby.mq4のコードを参照)。 順序探索サイクル「for」、すなわちブロック3-4では、前のプログラムと同様に、「間違った」命令が除外される。 この場合、これらは別のシンボルと保留中のオーダー用に開かれたオーダーです。

ブロック4-5では、ブロック3-4でチェックされた各注文の量が計算される。 計算中に、現在処理されている注文が処理されたすべての注文の中で最大のものであると判明した場合、そのチケットが保管されます。 これは、このチケットを有する注文が、この計算段階において、反対の注文を閉じるための候補であることを意味する。 'for'サイクルの最後の反復が終了する瞬間に、反対方向に開いた最大ロット数を有する注文のチケットは既に知られている。 これらの注文はプログラムによって選択されます。 この瞬間までにいかなるタイプの注文も既に利用できなくなった場合、ブロック5-6はプログラムを終了する。

ブロック6-10はエラー処理を表す。 これは上で検討したものと完全に同じです(このセクションと前のセクションで)。 反対の注文を閉じるための取引要求は、ブロック7-8で、OrderCloseBy()関数を使用して形成される。 それが失敗した場合、エラーコードに従って、プログラムは、取引を(同じチケットのために)再試行するか、またはプログラムオペレーションを終了させるオペレータの「返却」に制御を渡す。

取引が正常に実行されると、プログラムはエラー処理ブロックを終了し、最も外部のサイクル 'while'の現在の反復は終了する。 このサイクルの次の反復では、すべての計算が繰り返されます:利用可能な注文の検索、市場の注文の選択、注文タイプごとの選択、反対の取引のための取引要求の作成、およびその後のエラー分析。 このサイクルは、端末に特定のタイプ(または特定のケースでは両方のタイプ)の利用可能な注文がなくなるまで実行されます。 このイベントはブロック5-6で計算され、プログラムはその動作を終了する。

図5に示す市場注文のクローズを目的としたcloseby.mq4スクリプトの実行時に、以下のメッセージが受信されました。 97:

イチジク。 98. closeby.mq4スクリプトの実行時に受信したメッセージ。

[端末]ウィンドウの[アカウント履歴]タブでは、一部の注文がゼロ利益で終了していることがわかります。 これは、反対の注文を閉じるときに保存するものです。 経済的な結果を比較することができます。 図97 99:

イチジク。 スクリプトcloseby.mq4の実行後のアカウント履歴。

[ターミナル]ウィンドウの[ジャーナル]タブでは、注文締め切りの履歴を追跡できます(最新のイベントは一番上に表示されます)。

イチジク。 スクリプトcloseby.mq4の実行中にイベントが発生しました。

スクリプトの実行では、アルゴリズムに従って、現在使用可能な最大音量のオーダーが閉じられます。 注文がランダムシーケンス(図97)で開かれたにもかかわらず、閉鎖されるべき最初の注文は、購入778594および販売778595であり、それぞれ1ロットおよび0.8ロットの量であった(図2の下の行100)。 これらの注文には異なる数量があるため、反対の締め処理により、新しい注文、購入778597が生成され、残りのロットは0.2ロットとなりました。 その後、プログラムは、778592を購入し、778593を売り、それぞれ0.5ロットを反対の注文としてクローズするように選択した。 これらの命令は、休息命令を開くことなく閉じられた。

3回目の反復が始まった瞬間に、2回目の注文がシンボル・ウィンドウに残っていました。最初の注文0.3ロットの778596を販売し、スクリプトの実行の結果としてオープンされた注文は、0.2ロットの778597を購入します。 図2の上段には、 100の場合、それらの注文は反対の注文としても閉鎖されていることがわかります。 これらの注文の数量は異なるため、最後の取引では0.1ロットのマーケット注文がシンボルウィンドウに残りました(経済的結果に注意してください):

イチジク。 101.残りの費用0.1ロットで売りを注文します。

手動取引でcloseby.mq4というスクリプトを使用すると便利です。特に、シンボルウィンドウで多方面に指向したマーケット注文がある場合に便利です。

スポンサードリンク

-MQL4ブック, MT4
-,

© 2020 FX・ビットコイン・オプションのシステムトレード開発と取引録 Powered by AFFINGER5