ストップレベルの制限の可能性が高い
エラーコード 130とは
OrderSend時に発生するエラーコード「130」は、以下の場合に発生するエラーです。
- 損切り価格がエントリー価格よりも順行方向にある
- 利食い価格がエントリー価格よりも逆行方向にある
- 損切り/利食い価格がエントリー価格に近すぎる
エラーコード「130」を表す定数「ERR_INVALID_STOPS」を直訳すれば「無効なストップ値」となります。
最初の2つは当たり前ですよね。
成行買いを例にとるなら、その時の価格より上の位置に損切りを設定しようとしたってできるわけありませんから。
恐らくこのエラーが出る大半は最後の理由かと思います。
エントリー価格のすぐそばに損切り/利食い価格を設定しようとして怒られちゃうケースです。
エントリー価格に近すぎることによるinvalid stops 130エラーを回避するには、ストップレベル(StopLevel)について知らなければなりません。
ストップレベル(StopLevel)とは
多くのFX業者は、MT4サーバーに対してエントリー価格から一定以上離れた位置に損切りまたは利食い価格を設定しなければエラーとなるように設定しています。
この一定以上離れた位置の制限のことをストップレベル(StopLevel)と呼びます。
ストップレベルは以下の表の通り、成行注文、指値注文、逆指値注文いずれにも存在し、この条件を満たさないと注文送信時にinvalid stops 130エラーが発生します。
※表の出典元は公式ページです。
この表の見方ですが、買いの成行注文(1行目)の場合、損切り価格(SL)は「Bid – SL ≧ ストップレベル」、利食い価格(TP)は「TP – Bid ≧ ストップレベル」をそれぞれ満たすようにしなさいということです。
ここで、Bidは売り気配値(買いの成行注文の場合に使われる価格)、Askは買い気配値(売りの成行注文の場合に使われる価格)です。
買いの成行注文の場合、Bidがエントリー価格ということになります。
さて、「Bid – SL ≧ ストップレベル」という数式の見た目だとちょっと分かりにくいですね。
この不等式を組み替えてみましょう。
SLを右に移し、ストップレベルを左に移します。等号/不等号をまたがると符号が反転する点にご注意ください(覚えてます?)。
「Bid – ストップレベル ≧ SL」
SLが左側の方が分かりやすいので式を反転します。不等号の向きも反転しますよ!
「SL ≦ Bid – ストップレベル」
これでどうでしょうか?
「損切り価格(SL)はエントリー価格(Bid)からストップレベルだけ下げた位置以下にしてね」ということが直感的に分かるようになったかと思います。
この要領で表内の式は左側にSLまたはTPのみにすると分かりやすいです。
ストップレベルの確認方法
ストップレベルの値はFX業者ごと通貨ペアごとで異なります。
ストップレベルはMT4の画面で確認することもできますし、プログラミングで確認することもできます。
MT4の画面で確認するには、気配値表示ウィンドウで知りたい通貨ペアを右クリックし、「仕様」を選択します。
ストップレベルと書かれているところがストップレベルの値です。
この例ではGBPJPYのストップレベルが10であることが分かります。
10の単位はポイントと呼ばれるもので、1ポイントは最小価格(価格の一番右側の桁)を指します。この例で言えば1ポイント=0.001です。
10ポイントということは0.01がストップレベルの価格となります。
次にプログラミングで確認する方法ですが、以下のコードでストップレベルの値を取得できます。
MarketInfo(Symbol(), MODE_STOPLEVEL)
この場合、上記画面と同じでポイント(10)が取得できます。
価格にするには最小価格を表すPointという予約済み変数を掛け合わせます。
double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point;
stopLevelには10*0.0001=0.01が格納されることになります。
対策はストップレベルを加味して損切り価格を設定すればいいだけ
対策はもうお分かりだと思いますが、損切りや利食い価格を設定する場合はストップレベルを加味しましょうということになります。
実験用として買いの成行注文を行うサンプルコードをお見せします。
int OnInit() { double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL) * Point; // ----------------------------------------------------------------- // 成功する例 // ----------------------------------------------------------------- // 買いの場合、「stopPrice」は「Bid - stopLevel」以下にしなければならない double stopPrice = Bid - stopLevel; int ticket = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 10, stopPrice, 0, "", 0, 0, clrBlue); int err = GetLastError(); if(err > 0){ Print("成功: " + IntegerToString(err) + ": " + ErrorDescription(err)); } // ----------------------------------------------------------------- // エラーになる例 // ----------------------------------------------------------------- // 買いの場合、「stopPrice」は「Bid - stopLevel」以下にしなければならない stopPrice = Bid - stopLevel + Point; // 1ポイント(GBPJPYなら0.001)だけ足して違反させる ticket = OrderSend(Symbol(), OP_BUY, 0.02, Ask, 10, stopPrice, 0, "", 0, 0, clrBlue); err = GetLastError(); if(err > 0){ Print("エラー: " + IntegerToString(err) + ": " + ErrorDescription(err)); } return(INIT_SUCCEEDED); }
前半は成功する注文で、後半はエラーになる注文です。
エラーはこんな感じでターミナルウィンドウのエキスパートタブに表示されます。
違いはstopPriceに1ポイント分の価格(0.001)を上乗せしているか否かだけです。
0.001足したら、SL ≦ Bid – ストップレベルが成り立たなくなりますので、正しいですね。
実践で使う場合は、何らかの形で損切り価格を用意して、その損切り価格とBid – stopLevelを比較して条件成立しているか判定すると良いでしょう。
FX業者によっては高ボラの通貨ペア(ポンド系)に大きなストップレベルを設定しているところがありますので、なぜか損切り設定すると注文が行われないという時はストップレベル制限に引っかかっていないかをチェックしてみてください!
【余談】フリーズレベル(FreezeLevel)は詳細不明
ストップレベルに似た概念にフリーズレベル(FreezeLevel)というものもあるのですが、こちらの意味は正直よく分かりません。
というのもフリーズレベルが0より大きいFX業者に出会ったことがないのです。
殆どの場合、フリーズレベルは0なので、こちらはあまり気にする必要はないかなという感じです。