OrderSend Error 130 の回避

1.OrderSend Error 130 とは

 EAを稼働させていると、「OrderSend Error 130」というエラーが生じることがあります。

 「OrderSend Error 130」とは、定数が「ERR_INVALID_STOPS」(=無効な損切り値)となっているように、以下のような場合に生じるエラーです。

  1. 損切り(利益確定)値が現在のレートに近すぎる。
  2. 損切り(利益確定)値を算出する計算式が正しくない。
  3. 損切り(利益確定)値が正規化されていない。

 「OrderSend Error 130」が生じる原因は上記のとおりですが、その中でも、特に1番目が当該エラーを生じさせる原因となっていることが多いと思われるので、1番目の原因を生じさせないようにし、「OrderSend Error 130」エラーを回避するプログラミング方法について解説していきます。

2.ストップレベル

 「損切り(利益確定)値が現在のレートに近すぎる」ことを原因とした「OrderSend Error 130」の発生を回避するためには、まず、「ストップレベル」(Stop Level)について理解を得ておく必要があります。

⑴ ストップレベルとは

 MetaTrader4(MT4)を採用している各FX業者は、過大な取引サーバーに対する負荷を避けるために、現在値から一定のpips以上離れた位置に損切り値や利益確定値を設定しなければ、新規に損切り値や利益確定値を設定した注文を受け付けないようにしています。

 この、新規注文に対する損切り値や利益確定値の設定に対する値幅制限を、ストップレベルといいます。

Stop-Level
ストップレベル

⑵ ストップレベルによる注文の制限

 各種注文に対するストップレベルによる制限をまとめた表を、以下に示します(以下の表に示した条件を満たさない場合には、注文は執行されません。)。

ストップレベルによる制限

注文種別
(逆)指値
損切り値(SL)
利益確定値(TP)
成行買い
「Bid-SL」

ストップレベル
以上
「TP-Bid」

ストップレベル
以上
成行売り
「SL-Ask」

ストップレベル
以上
「Ask-TP」

ストップレベル
以上
指値買い
「Ask-指値」

ストップレベル
以上
「指値-SL」

ストップレベル
以上
「TP-指値」

ストップレベル
以上
指値売り
「指値-Bid」

ストップレベル
以上
「SL-指値」

ストップレベル
以上
「指値-TP」

ストップレベル
以上
逆指値買い
「逆指値-Ask」

ストップレベル
以上
「逆指値-SL」

ストップレベル
以上
「TP-逆指値」

ストップレベル
以上
逆指値売り
「Bid-逆指値」

ストップレベル
以上
「SL-逆指値」

ストップレベル
以上
「逆指値-TP」

ストップレベル
以上

3.具体的な回避策

 OrderSend Error 130 が、損切り値と利益確定値をストップレベルの範囲内に設定しようとすることから生じるのであれば、当該エラーを回避するためには、以下のような対策を講じればよいということになります。

  1. 設定しようとする損切り値と利益確定値が、ストップレベルの範囲内にあるかどうかを検証する。
  2. 検証の結果、ストップレベル違反が認められた場合には、設定しようとする損切り値と利益確定値が、ストップレベルの範囲外の値に自動的に修正されるようにする

 具体的なコードとしては、以下のようになります。

Download (PDF, 31KB)

⑴ 変数の宣言

 まず、以下のような変数を宣言しておきます。

  • Adjust_Stop
    後述の⑸ウ参照。
  • Stop_Loss
    約定価格から、損切り値までのpips数を指定します。
  • Take_Profit
    約定価格から、利益確定値までのpips数を指定します。
  • Ticket_L
    ロングエントリーしたポジションのチケット番号を格納します。
  • Ticket_S
    ショートエントリーしたポジションのチケット番号を格納します。
  • Pips
    損切り値や利益確定値などをpips単位で算出するための値を格納します。

⑵ 関数の定義

 損切り値や利益確定値を、提示レートの小数点以下の桁数にかかわらず、常にpips単位で算出することができるように、AdjustPoint()関数を宣言しています。

 AdjustPoint()関数の詳細については「こちら」を参照してください。

⑶ 初期設定の記述

 損切り値や利益確定値などをpips単位で算出するために使用する変数「Pips」に、AdjustPoint()関数の戻り値を格納しています。

 当該処理は、EAを稼働させてから一度だけ行えば足りるので、init()関数内で行っています。

⑷ 保有ポジションの選択

 具体例では、OrderSend Error130 の発生を回避するために、以下の手順を踏むことにしています。

  1. 損切り値及び利益確定値を指定しないエントリー注文を発注。
  2. エントリー注文約定後に、保有したポジションに対して、ストップレベルを考慮した損切り値及び利益確定値を設定する。

 そこで、以下のような処理を行っています。

  1. OrderSend()関数(詳細は「こちら」を参照してください。)の戻り値を変数「Ticket_L」に格納する。
  2. 変数「Ticket_L」の値が「正」(=注文が正常に約定した。)であるかどうか確認する。
  3. 変数「Ticket_L」の値が「正」であれば、OrderSelect()関数(詳細は「こちら」を参照してください。)を使用して、保有したポジションを選択する。

⑸ ストップレベルの計算

ア ストップレベルを取得する

 ストップレベルは、MarketInfo()関数(詳細は「こちら」を参照してください。)を使用することによって取得することができます。

 MarketInfo()関数によって取得されるストップレベルはポイント単位なので、例えば、ストップレベルが3pipsの場合、戻り値は以下のようになります。

  • 提示レートが小数点以下2桁又は4桁
    「3」
  • 提示レートが小数点以下3桁又は5桁
    「30」

 したがって、MarketInfo()関数で取得したストップレベルの値を、実際の値幅に変換するためには、MarketInfo()関数で取得したストップレベルの値に予約変数「Point」(詳細は「こちら」を参照してください。)を乗じることになります。

 具体例では、以下のように記述して、実際の値幅に変換したストップレベルの値を、変数「Stop_Level」に格納しています。


double Stop_Level =
MarketInfo(Symbol(),MODE_STOPLEVEL) * Point
  • Symbol()関数の詳細に「こちら」を参照してください。
イ 損切り値・利益確定値の設定可能値を算出する

 損切り値・利益確定値は、現在のレートにストップレベルの値を加減した値以上でなければなりません

 具体的には、買いポジションの利益確定値・売りポジションの損切り値・買いの逆指値注文・売りの指値注文は、以下の値以上でなければならないということになります。

売り気配値 + ストップレベル
(=Upper Stop Levelとします。)

 また、売りポジションの利益確定値・買いポジションの損切り値・売りの逆指値注文・買いの指値注文は、以下の値以下でなければならないということになります。

買い気配値 - ストップレベル
(=Lower Stop Levelとします。)

 具体例では、以下のように記述して、損切り値・利益確定値の設定可能値を変数「Upper_Stop_Level」及び「Lower_Stop_Level」に格納するようにしています。


RefreshRates();

double Upper_Stop_Level = Ask + Stop_Level;
double Lower_Stop_level = Bid - Stop_Level;
  • RefreshRates()関数の詳細については「こちら」を参照してください。
  • 「Ask」の詳細については「こちら」を参照してください。
  • 「Bid」の詳細については「こちら」を参照してください。
ウ スリッページを考慮する

 損切り値や利益確定値を「Upper Stop Level」や「Lower Stop Level」と等しい値にしてしまうと、相場状況によってはスリッページが発生し、損切り値や利益確定値を新規に設定した注文が無効となる場合が生じます。

 そこで、具体例では、損切り値や利益確定値を、「Upper Stop Level」や「Lower Stop Level」に一定のpips分加減した値に設定するようにしています。

 具体例では、「Upper Stop Level」や「Lower Stop Level」からのスリッページを考慮した調整値を任意の値に設定することができるように、これを外部変数「Adjust_Stop」としています。

 また、実際に「Upper Stop Level」や「Lower Stop Level」に加減するpips数を変数「Minimum_Stop」に格納するようにしています。


double Minimum_Stop = Adjust_Stop * Pips;

⑹ 損切り値と利益確定値の計算

ア 買いポジションの損切り値の計算

 買いポジションの損切り値は、以下の計算式から算出されます。

約定値-損切り幅

 具体例においては、以下のように記述して、買いポジションの損切り値を変数「Buy_Stop_Loss」に格納しています。


double Buy_Stop_Loss =
OrderOpenPrice() - (Stop_Loss * Pips);
  • OrderOpenPrice()関数の詳細については「こちら」を参照してください。
イ 買いポジションの利益確定値の計算

 買いポジションの利益確定値は、以下の計算式から算出されます。

約定値+利益確定幅

 具体例においては、以下のように記述して、買いポジションの利益確定値を変数「Buy_Take_Profit」に格納しています。


double Buy_Take_Profit =
OrderOpenPrice() + (Take_Profit * Pips);
  • OrderOpenPrice()関数の詳細については「こちら」を参照してください。

⑺ 損切り値と利益確定値の検証

ア 買いポジションの損切り値の検証

 買いポジションの損切り値はLower Stop Level以下でなければなりません

 そこで、具体例においては、以下のように記述して、新規に設定する買いポジションに対する損切り値が「Lower Stop Level」よりも大きかった場合は、買いポジションの損切り値を「Lower Stop Level」からスリッページを考慮した調整値を控除した値に修正するようにし、修正が行われた際にはその旨を「ターミナルウィンドウ」の「エキスパート」タブに出力するようにしています。


if(Buy_Stop_Loss > 0 &&
   Buy_Stop_Loss > Lower_Stop_Level)
  {
   Buy_Stop_Loss = Lower_Stop_Level - Minimum_Stop;
   
   Print("Stop-Loss has been
          automatically adjusted.");
  }
  • Print()関数の詳細については「こちら」を参照してください。
イ 買いポジションの利益確定値の検証

 買いポジションの利益確定値はUpper Stop Level以上でなければなりません

 そこで、具体例においては、以下のように記述して、新規に設定する買いポジションに対する利益確定値が「Upper Stop Level」よりも小さかった場合は、買いポジションの利益確定値を「Upper Stop Level」からスリッページを考慮した調整値を加算した値に修正するようにし、修正が行われた際にはその旨を「ターミナルウィンドウ」の「エキスパート」タブに出力するようにしています。


if(Buy_Take_Profit > 0 &&
   Buy_Take_Profit < Upper_Stop_Level)
  {
   Buy_Take_Profit = Upper_Stop_Level + Minimum_Stop;
   
   Print("Take-Profit has been
          automatically adjusted.");
  }
  • Print()関数の詳細については「こちら」を参照してください。

⑻ 注文の修正

 買いポジションに対する損切り値・利益確定値の計算・検証が終了した場合には、OrderModify()関数(詳細は「こちら」を参照してください。)を使用して、損切り値・利益確定値を設定しています。

⑼ 売りポジションに対する計算・検証・設定

 上記⑷~⑺と同様の処理を、売りポジションに対するものに適するように、適宜修正したコードを記述しています。

4.関連ツール

MQL言語の学習ができ、裁量トレーダーもEA開発が可能になる!
『EAつくーる』
『EAつくーる』 | fx-on.com

『EAつくーる』
『EAつくーる』 | fx-on.com

 上記ツール(EAつくーる『EAつくーる』 | fx-on.com)の詳細については「こちら『EAつくーる』 | fx-on.com」を参照してください。


MT4の使い方からプログラミングまで、わかりやすく解説