私自身はあまり「ドテン」はしないのですが、お客様から依頼されて久しぶりにドテンシステムを作ったところ、バックテストではうまく稼働するのに、トレードではエラー129が頻発しました。
成行き注文でこのエラーが出たら、原因はまず、AskやBidの最新値がうまく取得されていないということでしょう。
つまり、AskやBid等の予約変数は、スタート関数が呼び出されるとすぐに取得されるので、実行されるまでの間に複雑なプログラム処理が介在し、その間にレートが変わってしまうと、約定しないわけです。
簡単な実験をしてみましょう。
スタート関数に上のようなプログラムを書きました。
Price1には、スタート関数呼び出し後10秒後にAskの値が代入されます。
price2には、MarketInfo()関数により、最新のAskの値が代入されます。
price3には、直前にRefreshRates()関数が実行されるため、price2と同じく最新のAskの値が代入されます。
これをチャートに表示すると、
ご覧のように、Price1だけが古いレートになっています。
このように、RefreshRates()関数を使って、Askの値を最新のものにしてやればエラー129を防止できるわけです。
そこで、私が書いたプログラムを見てみましょう。
ネットなどでもよく紹介されている、通信エラー対策を盛り込んだオリジナル関数をほぼそのまま使用していますが、赤枠の部分を拡大してみましょう。
通常のスタート関数の中であれば、上のプログラムのように、OrderSend()関数の直前にRefreshRates()関数を記述すればよいわけですが、この場合には、オリジナル関数の中で記述されているため、OrderSend()関数の中にAsk自体が呼び出されていない点がどうも怪しいことに気づきました。
そこで、次のような実験をしてみました。
先ほどと異なり、Price3だけオリジナル関数を経由してAskの値を代入しますが、RefreshRates()関数は、そのオリジナル関数の中で使用し、その直後には、Ask自体は呼び出されていません。
これをチャートに表示すると、
Price2だけが最新のAskの値を取得し、Price1とPrice3が古い値となってしまっていることがわかります。
そこで、今度は、
上のプログラムのように、Price3だけオリジナル関数を経由しますが、その中で、Askを呼び出して、その直前にRefreshRates()関数を記述します。
すると、
Price3には最新のAskが取得されました。
つまり、まとめると、
RefreshRates()関数は、OrderSend()関数やOrderClose()関数の直前に置くのではなく、あくまでも、AskやBidの直前に置かないと意味がないということです。
そこで、もう一度、私が書いたプログラムを見ると、
RefreshRates()関数の後に、OrderSend()関数はありますが、肝心なAskが呼び出されていません。
なので、次にように書き変えればよいわけです。
実際に、このプログラムに変更してからは、エラー129は一切出なくなりました。
コメントをお書きください