エラー#130 invalid stoplossに関するヘルプが必要です。 - ページ 4 1234 新しいコメント 削除済み 2011.11.16 20:02 #31 Raptorさん、お気づきいただきありがとうございます。 MODE_TICKSIZE(0.25)ではなく、MODE_TICKVALUE(12.50です)でDoubleRound関数を呼び出して いました。 直したのですが、#130は消えませんでした if(long) SL = MarketInfo(Symbol(), MODE_BID) - (stoploss * MarketInfo(Symbol(), MODE_POINT)); else SL = MarketInfo(Symbol(), MODE_ASK) + (stoploss * MarketInfo(Symbol(), MODE_POINT)); Log("SL: " + SL); //round to nearest Tickvalue SL = DoubleRound(SL, MarketInfo(Symbol(), MODE_TICKSIZE)); Log("SL rounded: " + SL); 以下は、更新されたDoubleRoundの行を含むエラーのログです: #ESZ1,M5: loaded successfully #ESZ1,M5: Date: 2011/11/16 21:54 #ESZ1,M5: Symbol: #ESZ1 #ESZ1,M5: Depot: 56127.45000000 #ESZ1,M5: Stop Level [Points]: 75.00000000 #ESZ1,M5: Freeze Level [Points]: 0.00000000 #ESZ1,M5: Spread [Points]: 25.00000000 #ESZ1,M5: Min/Max Lot: 0.01000000/1000.00000000 #ESZ1,M5: Point: 0.01000000 #ESZ1,M5: Tick Size: 0.25000000 #ESZ1,M5: Tick Value: 12.50000000 #ESZ1,M5: Digits: 2.00000000 #ESZ1,M5: Contract: 2011.09.14 00:00-2011.12.16 23:59 #ESZ1,M5: Expert ID: 35698390 #ESZ1,M5: Init successfully completed. #ESZ1,M5: initialized #ESZ1,M5: Opening Position: Short #ESZ1,M5: pos size: 1.00000000 #ESZ1,M5: Ask/Bid 1251.00000000/1250.75000000 #ESZ1,M5: Spread 0.25000000 #ESZ1,M5: open #13719226 sell 1.00 #ESZ1 at 1250.75 ok #ESZ1,M5: Order 13719226 Successfully Opened #ESZ1,M5: Stoplevel: 75.00000000 #ESZ1,M5: Freezelevel: 0.00000000 #ESZ1,M5: stoploss: 100.00000000 #ESZ1,M5: SL: 1252.00000000 #ESZ1,M5: SL rounded: 1252.00000000 #ESZ1,M5: error=130 比較のために、うまくいったログもあります: #ESZ1,M5: Opening Position: Long #ESZ1,M5: pos size: 1.00000000 #ESZ1,M5: Ask/Bid 1249.25000000/1249.00000000 #ESZ1,M5: Spread 0.25000000 #ESZ1,M5: open #13719321 buy 1.00 #ESZ1 at 1249.25 ok #ESZ1,M5: Order 13719321 Successfully Opened #ESZ1,M5: Stoplevel: 75.00000000 #ESZ1,M5: Freezelevel: 0.00000000 #ESZ1,M5: stoploss: 100.00000000 #ESZ1,M5: SL: 1248.00000000 #ESZ1,M5: SL rounded: 1248.00000000 #ESZ1,M5: modify #13719321 buy 1.00 #ESZ1 at 1249.25 sl: 1248.00 tp: 0.00 ok #ESZ1,M5: Stoploss successfully set いずれにせよ、より頻繁に動作するようになったので、我々は間違いなく近づいています。) Simon Gniadkowski 2011.11.17 09:52 #32 shinobi: いずれにせよ、今はもっと頻繁に動いているようで、確実に近づいています。) 修正に失敗した理由がわかりません ... OrderSend と OrderModify の間に新しい Bid/Ask を取得していますか? 私が今提案できるのは、エラー130が 出たときに、Bid, Ask (using MarketInfo), OOP, StopLevel, 設定しようとしているSLなど、すべてを新しくプリントすることです。 William Roeder 2011.11.17 12:34 #33 shinobi: MODE_TICKSIZE (0.25) の代わりに MODE_TICKVALUE (12.50) を指定して DoubleRound 関数を呼び出したのですが、どうすればよいですか? ティックバリューは間違いなく間違っています。代わりにticksizeでこれを試してみてください。 double DoubleRound(double number, double step){ return( MathRound(number/step)*step ); } 削除済み 2011.11.19 18:28 #34 Raptorさん、WHRoederさん、SDCさんへ。 130のストップロス・エラーは出なくなりました。最後のステップでようやく問題を突き止めたようです。 この後、すべてのステップをまとめた別の投稿をします。そうすれば、フォーラムでエラー#130と戦っている他の人たちは、このスレッドを参考として使うことができます。 継続的な助けに感謝します :). shinobi Simon Gniadkowski 2011.11.19 19:38 #35 shinobi: これからもよろしくお願いします :) シノビ よく頑張りましたね。 ...必ず説明はあるのですが、それを見つけるのが難しいことがある、というだけです。 削除済み 2011.11.19 19:58 #36 Error #130: invalid stoplossの考えられる原因についての参考資料です。 一般的なアドバイス ECNブローカー 4桁/5桁ブローカー 相場を変える スプレッド ストップレベル フリーズレベル ティックサイズ 完全な例 謝辞 一般的なアドバイス エラーに対抗するための最も重要なテクニックは、過剰なログを取ることです。エラーに関連する可能性のあるものはすべて出力してください。ログ関数を定義し、オンとオフを切り替えることができれば、問題を解決した後にコードを保持することができます。 エキスパートアドバイザーを初期化する際には、MarketInfo が提供するすべての情報をログに記録する必 要があります。https://docs.mql4.com/constants/marketinfo また、OrderModify などの関数の戻り値を常に確認するようにしてください。 if (!OrderSelect(ticket, SELECT_BY_TICKET)) { int error_code = GetLastError(); Print("Error: " + ErrorDescription(error_code)); return(-1); } ECNブローカー ECNブローカーは、買い/売りとストップロス/テイクプロフィットのための別々の注文を行う必要があります。そこで、次のようにコードを2つの注文に分割する必要があります。 int ticket = OrderSend(Symbol(), OP_BUY, 1, MarketInfo(Symbol(), MODE_ASK), 2, 0, 0, "", 12345); OrderSelect(ticket, SELECT_BY_TICKET); entry_price = OrderOpenPrice(); OrderModify(ticket, entry_price, stoploss, takeprofit, 0); 売り注文の場合、OP_BUYをOP_SELLに置き換える必要があります。また、OrderSelectとOrderModifyの戻り値も確認する必要があります(上記の一般的なヒントを参照)。 4桁/5桁のブローカー ブローカーによっては、ストップロス、テイクプロフィット、スリッページを4/5桁に調整することを要求する場合があります。以下のコードをinit()関数に入れれば、それが可能になります(thx WHRoeder)。 int pips2points; // slippage 3 pips 3=points 30=points double pips2dbl; // Stoploss 15 pips 0.0015 0.00150 int Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips) //init digit adjustment if (Digits % 2 == 1) { // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262 pips2dbl = Point*10; pips2points = 10; Digits.pips = 1; } else { pips2dbl = Point; pips2points = 1; Digits.pips = 0; } 次に、ブローカーに送信する前に、stoploss、takeprofit、slippageにpips2db1を乗じる必要があります。 OrderModify(ticket, entry_price, stoploss * pips2points, takeprofit * pips2points, 0); 市場レートの変更 もう1つの考えられる原因は、ティックがExpert Advisor(EA)をアクティブにしてから、EA OrderSend()またはOrderModify()が実行される間に市場レートが変更されたことです。この問題を回避するために、2つの解決策があります。 1つ目は、RefreshRates()を使用することです。1つ目は、以下のような定義済みの市場変数を使用する前に、RefreshRates() を使用することです。アスクやビッドなどの定義済み市場変数を使用する前に、RefreshRates()を使用することです。(これらの変数は、ティックがEAをアクティブにしたときに値を取得します) もう一つは、定義済みの市場変数を全く使用しないことです。その代わりに、MarketInfo()で現在の市場の値を使用することができます。アスク、ビッド、ポイントの代わりに MarketInfo(Symbol(), MODE_ASK) MarketInfo(Symbol(), MODE_BID) MarketInfo(Symbol(), MODE_POINT) スプレッド ストップロスやテイクプロフィットがエントリー価格に近すぎる場合、注文は拒否されます。この問題を回避するためには、AskとBidの間の現在のスプレッドを考慮する必要があります。ここでも2つの解決策があります。 1つ目は、スプレッドを計算し、それをストップロス/テイクプロフィットに加算/減算する方法です。 double spread = MarketInfo(Symbol(), MODE_ASK) - MarketInfo(Symbol(), MODE_BID); //buy stoploss = stoploss - spread; takeprofit = takeprofit + spread; //sell stoploss = stoploss + spread; takeprofit = takeprofit - spread; もう一つは、ストップロスやテイクプロフィットを計算する際に、アスクとビッドを用いて暗黙のうちにスプレッドを考慮する方法です。 stoploss = 50 takeprofit = 50 //buy SL = MarketInfo(Symbol(), MODE_BID) - (stoploss * MarketInfo(Symbol(), MODE_POINT)) TP = MarketInfo(Symbol(), MODE_ASK) + (takeprofit * MarketInfo(Symbol(), MODE_POINT)) //sell SL = MarketInfo(Symbol(), MODE_ASK) + (stoploss * MarketInfo(Symbol(), MODE_POINT)) TP = MarketInfo(Symbol(), MODE_BID) - (takeprofit * MarketInfo(Symbol(), MODE_POINT)) ストップレベル ブローカーは一定のストップレベルを持っています。ストップロスがそのレベルを下回っている場合、注文は拒否されます。ストップレベルは、MarketInfo(Symbol(), MODE_STOPLEVEL)で確認することができます。 これを避けるには、ブローカーのストップレベルに対してストップロスをチェックし、必要であれば調整してください。 double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL); if(stoploss < stoplevel) stoploss = stoplevel + 1; フリーズ・レベル Freeze Levelも同じようなコンセプトです。ストップロスもブローカーのフリーズレベルより大きくなければなりません。フリーズレベルはMarketInfo(Symbol(), MODE_FREEZELEVEL)で確認することができます。 これを避けるために、再度、ストップロスをブローカーのフリーズレベルと照らし合わせてください。 double freezelevel = MarketInfo(Symbol(), MODE_FREEZELEVEL); if(stoploss < freezelevel) stoploss = freezelevel + 1; ティックサイズ 最後に、ストップロスやテイクプロフィットは拒否されるかもしれません。なぜなら、シンボルはそのティックサイズに一致するストップロスやテイクプロフィットしかサポートしていないからです。ティックサイズとは、シンボルの価格が上下する最小距離のことです。例えば、価格が1000でticksizeが0.25の場合、価格は0.25の倍数(0.25 * n、nは自然数)だけ上下することができます。つまり、価格は0.25だけ上がって1000.25になり、1.75だけ下がって998.25になる可能性があります。 ティックサイズを考慮するには、二重の値をあるステップの値(例えば最も近い0.25)に丸める関数が必要です。以下はそのような関数です。 double DoubleRound(double number, double step) { double mod = MathMod(number, step); if(mod < step/2.0) step = 0; double rounded = number - mod + step; return (rounded); } 例えば、数値 = 1023.81234 とステップ = 0.25 で DoubleRound を呼び出すと、1023.75 が返されます。1023.967834で呼び出すと、1024.00が返されます。 ストップロスやテイクプロフィットを送信する前に、シンボルのティックサイズに丸める必要があります。 stoploss = (stoploss, MarketInfo(Symbol(), MODE_TICKSIZE)); takeprofit = (takeprofit, MarketInfo(Symbol(), MODE_TICKSIZE)); 完全な例 上記の対策をすべて考慮した完全な小例を以下に示します。 int init() { //for 4/5 Digits-Broker adjustment int pips2points; // slippage 3 pips 3=points 30=points double pips2dbl; // Stoploss 15 pips 0.0015 0.00150 int Digits.pips; // DoubleToStr(dbl/pips2dbl, Digits.pips) //init digit adjustment if (Digits % 2 == 1) { // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262 pips2dbl = Point*10; pips2points = 10; Digits.pips = 1; } else { pips2dbl = Point; pips2points = 1; Digits.pips = 0; } Print("Date: " + Year() + "/" + Month() + "/" + Day() + " " + Hour() + ":" + Minute()); Print("Symbol: " + Symbol()); Print("Depot: " + AccountBalance()); Print("Stop Level [Points]: " + MarketInfo(Symbol(), MODE_STOPLEVEL)); Print("Freeze Level [Points]: " + MarketInfo(Symbol(), MODE_FREEZELEVEL)); Print("Spread [Points]: " + MarketInfo(Symbol(), MODE_SPREAD)); Print("Min/Max Lot: " + MarketInfo(Symbol(), MODE_MINLOT) + "/" + MarketInfo(Symbol(), MODE_MAXLOT)); Print("Point: " + MarketInfo(Symbol(), MODE_POINT)); Print("Tick Size: " + MarketInfo(Symbol(), MODE_TICKSIZE)); Print("Tick Value: " + MarketInfo(Symbol(), MODE_TICKVALUE)); Print("Digits: " + MarketInfo(Symbol(), MODE_DIGITS)); Print("Contract: " + TimeToStr(MarketInfo(Symbol(), MODE_STARTING)) + "-" + TimeToStr(MarketInfo(Symbol(), MODE_EXPIRATION))); } //long = true: buy; long = false: sell int take_position(bool long) { int stoploss = 50; double SL = 0.0; int ticket = -1; //send order if(long) //buy ticket = OrderSend(Symbol(), OP_BUY, 1, MarketInfo(Symbol(), MODE_ASK), 2, 0, 0, "", 1234); else //sell ticket = OrderSend(Symbol(), OP_SELL, 1, MarketInfo(Symbol(), MODE_BID), 2, 0, 0, "", 1234); //check for errors if(result_ticket == -1) { int error_code = GetLastError(); Print("Error: " + ErrorDescription(error_code)); return(-1); } Print("order "+ticket+" successfully opened"); //select order if (!OrderSelect(result_ticket, SELECT_BY_TICKET)) { int error_code = GetLastError(); Print("Error: " + ErrorDescription(error_code)); return(-1); } double entry_price = OrderOpenPrice(); //check stoplevel double stoplevel = MarketInfo(Symbol(), MODE_STOPLEVEL); Print("Stoplevel: " + stoplevel); if(stoploss < stoplevel) stoploss = stoplevel + 1; //check freezelevel double freezelevel = MarketInfo(Symbol(), MODE_FREEZELEVEL); Print("Freezelevel: " + freezelevel); if(stoploss < freezelevel) stoploss = freezelevel + 1; Print("adjusted stoploss: " + stoploss); //account for spread AND account for 4/5-Digit Brokers if(long) SL = MarketInfo(Symbol(), MODE_BID) - (stoploss * pips2dbl); else SL = MarketInfo(Symbol(), MODE_ASK) + (stoploss * pips2dbl); Print("SL: " + SL); //round to nearest Tickvalue SL = DoubleRound(SL, MarketInfo(Symbol(), MODE_TICKSIZE)); Print("SL rounded: " + SL); //set stoploss if(!OrderModify(result_ticket, entry_price, SL, 0, Red)) { int error_code = GetLastError(); Print("Error: " + ErrorDescription(error_code)); return(-1); } Print("Stoploss successfully set"); return(0); } 130番を取り除くのに役立つことを願っています。もし、コードを変更してもうまくいかない場合は、まず、上記のような最小限の例を使ってみてください。そして、エラーが出なくなったら、変更したものを自分のコードに取り込んでください。 幸運を祈ります。 shinobi 謝辞 Raptorさん、WHRoederさん、SDCさん、BigAlさん、gjolさん、35806さん、エラーの解消とこのリファレンスをまとめるのに協力していただきありがとうございました。 1234 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
MODE_TICKSIZE(0.25)ではなく、MODE_TICKVALUE(12.50です)でDoubleRound関数を呼び出して いました。
直したのですが、#130は消えませんでした
以下は、更新されたDoubleRoundの行を含むエラーのログです:
比較のために、うまくいったログもあります:
いずれにせよ、より頻繁に動作するようになったので、我々は間違いなく近づいています。)
いずれにせよ、今はもっと頻繁に動いているようで、確実に近づいています。)
修正に失敗した理由がわかりません ... OrderSend と OrderModify の間に新しい Bid/Ask を取得していますか?
私が今提案できるのは、エラー130が 出たときに、Bid, Ask (using MarketInfo), OOP, StopLevel, 設定しようとしているSLなど、すべてを新しくプリントすることです。
MODE_TICKSIZE (0.25) の代わりに MODE_TICKVALUE (12.50) を指定して DoubleRound 関数を呼び出したのですが、どうすればよいですか?
130のストップロス・エラーは出なくなりました。最後のステップでようやく問題を突き止めたようです。
この後、すべてのステップをまとめた別の投稿をします。そうすれば、フォーラムでエラー#130と戦っている他の人たちは、このスレッドを参考として使うことができます。
継続的な助けに感謝します :).
shinobi
これからもよろしくお願いします :)
シノビ
エラーに対抗するための最も重要なテクニックは、過剰なログを取ることです。エラーに関連する可能性のあるものはすべて出力してください。ログ関数を定義し、オンとオフを切り替えることができれば、問題を解決した後にコードを保持することができます。
エキスパートアドバイザーを初期化する際には、MarketInfo が提供するすべての情報をログに記録する必 要があります。https://docs.mql4.com/constants/marketinfo
また、OrderModify などの関数の戻り値を常に確認するようにしてください。
ECNブローカーは、買い/売りとストップロス/テイクプロフィットのための別々の注文を行う必要があります。そこで、次のようにコードを2つの注文に分割する必要があります。
売り注文の場合、OP_BUYをOP_SELLに置き換える必要があります。また、OrderSelectとOrderModifyの戻り値も確認する必要があります(上記の一般的なヒントを参照)。
ブローカーによっては、ストップロス、テイクプロフィット、スリッページを4/5桁に調整することを要求する場合があります。以下のコードをinit()関数に入れれば、それが可能になります(thx WHRoeder)。
次に、ブローカーに送信する前に、stoploss、takeprofit、slippageにpips2db1を乗じる必要があります。
もう1つの考えられる原因は、ティックがExpert Advisor(EA)をアクティブにしてから、EA OrderSend()またはOrderModify()が実行される間に市場レートが変更されたことです。この問題を回避するために、2つの解決策があります。
1つ目は、RefreshRates()を使用することです。1つ目は、以下のような定義済みの市場変数を使用する前に、RefreshRates() を使用することです。アスクやビッドなどの定義済み市場変数を使用する前に、RefreshRates()を使用することです。(これらの変数は、ティックがEAをアクティブにしたときに値を取得します)
もう一つは、定義済みの市場変数を全く使用しないことです。その代わりに、MarketInfo()で現在の市場の値を使用することができます。アスク、ビッド、ポイントの代わりに
ストップロスやテイクプロフィットがエントリー価格に近すぎる場合、注文は拒否されます。この問題を回避するためには、AskとBidの間の現在のスプレッドを考慮する必要があります。ここでも2つの解決策があります。
1つ目は、スプレッドを計算し、それをストップロス/テイクプロフィットに加算/減算する方法です。
もう一つは、ストップロスやテイクプロフィットを計算する際に、アスクとビッドを用いて暗黙のうちにスプレッドを考慮する方法です。
ブローカーは一定のストップレベルを持っています。ストップロスがそのレベルを下回っている場合、注文は拒否されます。ストップレベルは、MarketInfo(Symbol(), MODE_STOPLEVEL)で確認することができます。
これを避けるには、ブローカーのストップレベルに対してストップロスをチェックし、必要であれば調整してください。
Freeze Levelも同じようなコンセプトです。ストップロスもブローカーのフリーズレベルより大きくなければなりません。フリーズレベルはMarketInfo(Symbol(), MODE_FREEZELEVEL)で確認することができます。
これを避けるために、再度、ストップロスをブローカーのフリーズレベルと照らし合わせてください。
最後に、ストップロスやテイクプロフィットは拒否されるかもしれません。なぜなら、シンボルはそのティックサイズに一致するストップロスやテイクプロフィットしかサポートしていないからです。ティックサイズとは、シンボルの価格が上下する最小距離のことです。例えば、価格が1000でticksizeが0.25の場合、価格は0.25の倍数(0.25 * n、nは自然数)だけ上下することができます。つまり、価格は0.25だけ上がって1000.25になり、1.75だけ下がって998.25になる可能性があります。
ティックサイズを考慮するには、二重の値をあるステップの値(例えば最も近い0.25)に丸める関数が必要です。以下はそのような関数です。
例えば、数値 = 1023.81234 とステップ = 0.25 で DoubleRound を呼び出すと、1023.75 が返されます。1023.967834で呼び出すと、1024.00が返されます。
ストップロスやテイクプロフィットを送信する前に、シンボルのティックサイズに丸める必要があります。
上記の対策をすべて考慮した完全な小例を以下に示します。
130番を取り除くのに役立つことを願っています。もし、コードを変更してもうまくいかない場合は、まず、上記のような最小限の例を使ってみてください。そして、エラーが出なくなったら、変更したものを自分のコードに取り込んでください。
幸運を祈ります。
shinobi
Raptorさん、WHRoederさん、SDCさん、BigAlさん、gjolさん、35806さん、エラーの解消とこのリファレンスをまとめるのに協力していただきありがとうございました。