- 2018.05.18
- www.mql5.com
デモ口座で問題なく、本番口座で問題ありということならそれは処理による遅延ではないかと思いますが、本番口座での問題は実際に再現して確かめることができないので詳しいことは分かりません。
ところで、if(test == true && ...... の部分は待機のためにループ処理したのですか?
DLしたプログラムでは、trueにならなければ実行しないまま通過してしまいます。ループ処理すればSleep(2000)は必要ないように思います。
TradeTransactionについては、
例えば、買いの成行注文を送信すると、注文が処理され、買い注文が口座に記録されます。その後注文が実行されオープン注文の表から削除されて注文履歴に追加されます。 約定が履歴に追加され新しいポジションが作成されます。これらのアクションは全て取引トランザクションです。このようなトランザクションの端末への到着が TradeTransaction イベントです。https://www.mql5.com/ja/docs/runtime/event_fire#tradetransaction
と、説明されており、ターミナルに送られてくるトレード履歴に関する処理のようです。ですから TradeTransaction イベントが発生すれば処理内容がターミナルに到着しているということになります。
結果はOnTradeTransaction関数のMqlTradeResult構造体に格納されています。
https://www.mql5.com/ja/docs/event_handlers/ontradetransaction
https://www.mql5.com/ja/docs/constants/structures/mqltraderesult
その他に、OrderSend関数を使って注文を実行した場合もMqlTradeResultにより結果が返されますので、こちらも使えるかもしれません。
https://www.mql5.com/ja/docs/trading/ordersend
ところでOSは何ですか?Win11 それとも Win10 64bit?
- www.mql5.com
- www.mql5.com
//注文処理 bool test = trade.Sell(onelot, tuuka, bid, 0.0, 0.0, IntegerToString(ordersuu,3)); if(test == true) { uint nowRetcode = trade.ResultRetcode(); //注文完了時 if(nowRetcode == TRADE_RETCODE_DONE) { //初回購入時はmax値,min値を共に再設定する ordersuu++; max = trade.ResultPrice(); min = max; Print("新規購入(売り)、ポジション数:",ordersuu); } //注文中の場合は、注文完了まで(2000ms)待機する else if(nowRetcode == TRADE_RETCODE_PLACED) { Print("現在注文中、注文完了まで待機します"); for(int i = 0;i<200;i++) { nowRetcode = trade.ResultRetcode(); //注文完了時 if(nowRetcode == TRADE_RETCODE_DONE) { //初回購入時はmax値,min値を共に再設定する ordersuu++; max = trade.ResultPrice(); min = max; Print("新規購入(売り)、ポジション数:",ordersuu); break; } //注文中のままの場合は、10msスリープする(これを200回繰り返す) else if(nowRetcode == TRADE_RETCODE_PLACED) { Sleep(10); } //注文中、注文完了以外になった場合 else { Print("注文中にエラー発生!", "、エラーコード:",GetLastError()); break; } if(i == 199) { Print("注文に時間が掛かりすぎます!"); } } } else { Print("購入失敗:リターンコードエラー", "、エラーコード:",GetLastError()); } } else { Print("購入失敗:注文処理フラグがfalse", "、エラーコード:",GetLastError()); }
そうですか、ほとんど確認された後の投稿だったとお見受けいたしました。失礼しました。
プログラムを色々と変更した結果、
ResultPrice()関数は利用せず、注文後に2000ms(決め打ちの時間)のSleep()関数を実行して強制的に待ち時間を作り、
PositionSelectByTicket()関数を実行後に、PositionGetDouble(POSITION_PRICE_OPEN)関数を実行すると
わたしは、この実装に近く
[注文]
①OrderCheck()で注文のチェック
②OrderSend()で注文
③②の戻り値がTrueの場合に、.retcodeを判断して、注文の成功確認
④③で失敗しているならば、エラー内容によりリトライ
[ポジション取得]
①PositionSelectByTicket()
②PositionGetDouble(POSITION_PRICE_OPEN)で約定価格を取得
...
(実際は、未決済ポジションを全て取得して、突合を行っています( PositionsTotal()分 PositionGetTicket()で選択して))
[注文]と[ポジション取得]は同じスレッド(同じOnTickイベント内)では行っておらず
注文が通ったら、次のタイミングでポジションを取得するようにしています。
設計思想が異なるため、参考にならないかもしれません。
(挿入しているチャートの通貨ペア以外もコントロールしたい、ms単位での精度を求めず、数秒単位で処理を行いたい
ので、OnTickイベントではなく、OnTimerイベントで管理しています。)
サーバー側の実装はブローカー毎に微妙に異なっていると思われるので悩ましいところですね。
失礼しました。
ではでは。
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索