EAを実際に稼働してみると、バックテストでは発生しなかった「error 141 : too many requests」というエラーが発生し、EAによる発注処理が実行されないことがあります。
1.Error 141 とは
Error 141とは、プログラムからの要求の頻度が多い場合に発生するエラーです。
具体的には、以下のような場合に当該エラーが発生します。
- 複数のEAを同時に稼働している。
- EAのロジックが複雑であるために、注文の発注までに多くの処理が介在している。
2.具体的な対処法
Error 141が発生するような場合に、EAによる発注処理を確実に行うようにするための具体的な対処法としては、以下のようなものが考えられます。
- エントリー条件を満たした場合に実行させるOrderSend()関数(詳細については「こちら」を参照してください。)による発注処理を、一度だけでなく、複数回繰り返させる。
⑴ 変数の宣言
OrderSend()関数による発注処理を繰り返させるためには、まず、以下のような変数を宣言しておきます。
- Max_Retry
OrderSend()関数による発注処理を繰り返させる最大回数を格納する変数です。 - Ticket_L
OrderSend()関数による発注処理を実行した結果(=戻り値)を格納する変数です。 - Retry
OrderSend()関数による発注処理を行った回数を格納する変数です。
⑵ 発注を繰り返させる
ア 発注を繰り返させる条件
Error 141に対処するために、具体例においては、ポジションを保有していない状態において最初に発注する場合を含め、変数「Max_Retry」で設定した回数に至るまで、OrderSend()関数による発注を繰り返させることにしているので、while()文(詳細については「こちら」を参照してください。)における条件式を、以下のように記述しています。
Ticket_L <= 0 && Retry <= Max_Retry - 1
- Ticket_L <= 0 について
「Ticket_L」はOrderSend()関数の戻り値を格納する変数ですが、当該変数は、初期値を「0」としているので、ポジションを保有していない状態においては、「0」が格納されています。
また、「Ticket_L」には、OrderSend()関数が正常に実行された場合はチケット番号として「正の整数値」が格納され、OrderSend()関数が正常に実行されなかった場合は「-1」が格納されます。
したがって、OrderSend()関数による発注処理を繰り返させる必要があるのは、変数「Ticket_L」に格納されている値が、「0」又は「-1」である場合ということになります。 - Retry <= Max_Retry – 1 について
「Retry」は、OrderSend()関数による発注処理を実行した回数を格納する変数ですが、初期値は「0」としているので、OrderSend()関数による発注処理を実行した回数は、「0」から数えることになります。
例えば、具体例のように、OrderSend()関数による発注処理の最大回数を「10」とした場合は、発注処理の実行回数が「10」に至るまでに、変数「Retry」に格納される値は、以下のように変化することになります。
0→1→2→3→4→5→6→7→8→9(=10-1)
イ OrderSend Error 129 の回避
上述のようにError 141は、OrderSend()関数による発注処理が実行されるまでに、複雑な処理が介在している場合に発生することがあります。
このことは、OrderSend Error 129 が発生する可能性があることを意味しています。
そこで、具体例においては、OrderSend Error 129 を回避するための処理を記述しています。
- OrderSend Error 129 及び、その回避方法の詳細については「こちら」を参照してください。
ウ 正常に発注処理が実行された場合
正常にOrderSend()関数による発注処理が実行された場合は、戻り値として正の整数値であるチケット番号が返され、当該値が変数「Ticket_L」に格納されます。
そこで、具体例においては、変数「Ticket_L」の値が「正」であれば、発注処理が完了してポジションを保有することになった旨を「ターミナルウィンドウ」の「エキスパート」タブに表示させるようにしています。
エ 正常に発注処理が実行されなかった場合
正常にOrderSend()関数による発注処理が実行されなかった場合は、戻り値として「-1」が返され、当該値が変数「Ticket_L」に格納されます。
そこで、具体例においては、以下のような処理を行うようにしています。
- 変数「Ticket_L」の値が「負」であれば、
- OrderSend()関数による発注処理が実行された回数を格納する変数「Retry」に格納されている値を「1」増やし、
- 変数「Retry」に格納されている値が、OrderSend()関数による発注処理が実行される最大回数を格納する変数「Max_Retry」の値と等しくなった際には、
- Print()関数を使用してOrderSend()関数による発注処理が失敗した旨を、「ターミナルウィンドウ」の「エキスパート」タブに表示させる。
オ 間隔をあける
Error 141 に対処するためには、OrderSend()関数による発注処理を繰り返し実行させることになります。
もっとも、Error 141 は、「プログラムの要求頻度が多い」場合に発生するものなので、一度OrderSend()関数による発注処理が失敗したとしても、即座にOrderSend()関数による発注処理を再実行するのではなく、一定の時間的間隔をあけることが妥当であるといえます。
そこで、具体例においては、Sleep()関数を用いて、OrderSend()関数による発注処理が失敗した場合に、再度OrderSend()関数を実行させるまでの間に、1秒間の間隔を置くようにしています。
カ 変数「Retry」の初期化
OrderSend()関数による発注処理の繰り返しが終了した場合には、変数「Retry」の値に「0」を格納して初期化し、その後にエントリー条件を満たした場合にも、OrderSend()関数による発注処理を繰り返すことができるようにしています。