TrimPips MT5対応の一覧

01.02.構成要素
※本記事は、FXism及川デイトレ大百科スタディ時のメモです。メモの一覧はコチラ 前回 構成要素 MTF(マルチタイムフレーム)それぞれ(10MA) 黄緑のカクカク15分足の移動平均線 青のカクカク1時間足の移動平均線 赤のカクカク4時間足...
今回は、画面上のPIPS消去による決済機能です。
まずは、MQL4のソースをそのままインプリメントします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long & lparam, const double & dparam, const string & sparam) { AppWindow.ChartEvent(id, lparam, dparam, sparam); if((id == CHARTEVENT_OBJECT_DELETE) // オブジェクトが削除された && (input_DelClose)) //PIP表示削除で決済 { if(StringFind(sparam, Str_dsppip) == 0) { //オーダー番号を切り出す string sep_str[]; StringSplit(sparam, '_', sep_str); //バッファの2個目にはオーダー番号 int norderno = StrToInteger(sep_str[1]); if(!OrderSelect(norderno, SELECT_BY_TICKET, MODE_TRADES)) { Print("OrderSelect失敗 オーダーNo=", norderno); return; } //決済処理 if(!OrderClose(norderno, OrderLots(), OrderClosePrice(), 0)) { Print("OrderClose失敗 オーダーNo=", norderno); return; } // PlaySound("Ok.wav"); } } } |
エラーは以下の通り

MQL4 |
MQL5 |
|
int StrToInteger(string value) |
long StringToInteger(string value) |
StrToInteger
値文字表記を含むストリングをint (整数)タイプに変換します。
StringToInteger |
簡単簡単。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { AppWindow.ChartEvent(id, lparam, dparam, sparam); if((id == CHARTEVENT_OBJECT_DELETE) // オブジェクトが削除された && (input_DelClose)) //PIP表示削除で決済 { Print(__FUNCTION__, "id=", id, " sparam=", sparam); if(StringFind(sparam, Str_dsppip) == 0) { //チケット番号(バッファの2個目)を切り出す string sep_str[]; StringSplit(sparam, '_', sep_str); ExitCurrency.exitbyorderno(StringToInteger(sep_str[1])); } } } |
新規にチケット番号クローズを追加
MQL4の場合は、ピンポイントで
クローズできたのだが
ポジション数分ループさせ
チケット番号と一致しているものを
クローズする。
さらに非同期のため
確実にクローズが終わるまで回す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
//+------------------------------------------------------------------+ //|指定のチケット番号のポジションをクローズする | //+------------------------------------------------------------------+ bool CExitCurrency::exitbyorderno(long orderno) // --- 4 { CTrade ExtTrade; Print(__FUNCTION__, " orderno =", orderno); int leftcount = 0; //現通貨の残り個数 for(int s = 0; s < 10; s++) { leftcount = 0; //現通貨の残り個数 int ncount = PositionsTotal(); Print(s, "回目め 残り回数 -> ", ncount); for(int i = 0; i < ncount; i++) { PositionGetTicket(i); if(PositionGetInteger(POSITION_TICKET) == orderno) { leftcount++; if(! ExtTrade.PositionClose(_Symbol)) { Print("PositionClose失敗"); } Print("ResultRetcode -> ", ExtTrade.ResultRetcode()); break; } } if(!leftcount) //現通貨がなかったらループを抜ける break; Sleep(250); } return true; } |
できたー
と思いきや。
PIPS整理ですべてクローズされてしまう。

一旦、画面のPIPSを削除するため
クローズ処理が走ってしまうのだ。
あれ、MQL4のときは?
と思ってMQL4のログを見ると
* ワイルドカードになっている。

その結果、IDと一致しないので
クローズされないのだ。
MQL5の場合は、すべてのIDが入ってくるので
すべてクローズ処理が走ってしまう。
やり方としては2つ
- PIPS整理でPIPSを消さずに整理する
- PIPS整理時フラグを立て、フラグが立っているときはクローズしない
1.実は面倒くさい。
単純にアクティブなポジションを整理するだけならいいが、
クローズされたボジションを消すすべがない。
やるとすれば、現在のポジションを管理する
テーブル的なものを作り、クローズポジションを
把握する必要がある。
2.フラグ作戦は、簡単にできるが。。。ダサい
(プログラミングにおいてフラグを使うのはバグの元であり、最後の手段)
それにオフするタイミングがわからない
というか、複数プロコンが動いていると
おそらくうまくいかないタイミングがでる
とはいえ、右クリックして削除するまでに
1秒以上かかるので、1秒後にフラグをOFFでいいかも。
できました。
まずフラグの追加
|
bool berasepips; //PIPS整理中フラグ |
セッターとゲッター
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
bool GetErasePips(void); //PIPS整理フラグの取得 void SetErasePips(bool bval); //PIPS整理フラグの設定 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CPanelDialog::GetErasePips(void) { return(berasepips); //PIPS整理中フラグ } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CPanelDialog::SetErasePips(bool bval) { berasepips = bval; //PIPS整理中フラグの設定 } |
PIPS整理処理でフラグの設定
|
//+------------------------------------------------------------------+ //|画面上のPIPS表示を消去する | //+------------------------------------------------------------------+ void CPanelDialog::OnClickPipsErase(void) { // ObjectsDeleteAll(0,m_dsppips);// m_dsppips ←const string Str_dsppip = "dsppi_"; //ユニークにするための文字列 ErasePipsDsp(); SetErasePips(1); //ExitCurrency.ClearExitTotalPips();//決算済みPIPSのクリア } |
OnTick()の一番最後(PIPS表示完了後)にフラグをオフ
|
AppWindow.SetErasePips(0); //PIPS整理中フラグをオフる |
イベント処理にフラグの判別処理を追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { AppWindow.ChartEvent(id, lparam, dparam, sparam); if(AppWindow.GetErasePips()) return; //PIPS整理中は無視する if((id == CHARTEVENT_OBJECT_DELETE) // オブジェクトが削除された && (input_DelClose)) //PIP表示削除で決済 { Print(__FUNCTION__, "id=", id, " sparam=", sparam, " GetErasePips()=", AppWindow.GetErasePips()); if(StringFind(sparam, Str_dsppip) == 0) { //チケット番号(バッファの2個目)を切り出す string sep_str[]; StringSplit(sparam, '_', sep_str); ExitCurrency.exitbyorderno(StringToInteger(sep_str[1])); } } } |
完了です。
とおもいきや、
1個の削除で、複数クローズしてしまう


なるほど、一つ削除すると
チケット番号が塗り替わるのだ。
266350396を削除しても
また、266350396が出現するので
結局全てのポジションを削除してしまう。

うーん、力技で行きます。
1回めに残り個数を保持し
2回め以降に数が減っていれば、メインループを抜ける
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
|
//+------------------------------------------------------------------+ //|指定のチケット番号のポジションをクローズする | //+------------------------------------------------------------------+ bool CExitCurrency::exitbyorderno(long orderno) // --- 4 { CTrade ExtTrade; Print(__FUNCTION__, " orderno =", orderno); int ntotalpos = 0; //トータルポジション数 for(int s = 0; s < 10; s++) { int ncount = PositionsTotal(); Print(s, "回目め 残り回数 -> ", ncount," 1回目のポジション数=",ntotalpos); if(s > 0) //2回め以降のとき { if(ntotalpos > ncount) //ポジションの数が減っていたら break;//終了 } else { ntotalpos = ncount; //クローズ前の個数を保持しておく } for(int i = 0; i < ncount; i++) { PositionGetTicket(i); Print("PositionGetInteger(POSITION_TICKET) =", PositionGetInteger(POSITION_TICKET)); if(PositionGetInteger(POSITION_TICKET) == orderno) { if(! ExtTrade.PositionClose(_Symbol)) { Print("PositionClose失敗"); } Print("ResultRetcode -> ", ExtTrade.ResultRetcode()); break; } } Sleep(250); } return true; }か |
ログを確認。

いい感じです。
完成!
MQL4では、
|
OrderClose(norderno, OrderLots(), OrderClosePrice(), 0) |
これだけの処理が、
非同期になったためにこれだけ冗長に
なってしまった。
MQL4のOrderClose()をMQL5への置き換えする際のポイント
- 非同期なので、何度かチェックする必要がある
- クローズが成功すると、使用していたチケット番号が再利用される
一つずれて決済される
できたと思って、決済したら
なぜだか一つずれて決済されていた。
|
if(PositionGetInteger(POSITION_TICKET) == orderno) { if(! ExtTrade.PositionClose(orderno))こ |
これがいけないらしい。
うーーーーーーーーーーーーーん。
再度仕様を見ると。
PositionClose
指定されたシンボルでポジションを決済します。
bool PositionClose(
const string symbol,
ulong deviation=ULONG_MAX
)
|
Closes a position with the specified ticket.
bool PositionClose(
const ulong ticket,
ulong deviation=ULONG_MAX
)
|
あれ?
引数にチケットを指定すればいいだけじゃね?
というわけで、これだけでOKでした。
|
ExtTrade.PositionClose(orderno) |
一応、非同期なのでできるのを
確認できるまでぐるぐる回します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
//+------------------------------------------------------------------+ //|指定のチケット番号のポジションをクローズする | //+------------------------------------------------------------------+ bool CExitCurrency::exitbyorderno(long orderno) // --- 4 { CTrade ExtTrade; Print(__FUNCTION__, " orderno =", orderno); int ntotalpos = 0; //トータルポジション数 for(int s = 0; s < 10; s++) { int ncount = PositionsTotal(); Print(s, "回目め 残り回数 -> ", ncount, " 1回目のポジション数=", ntotalpos); if(s > 0) //2回め以降のとき { if(ntotalpos > ncount) //ポジションの数が減っていたら break;//終了 } else { ntotalpos = ncount; //クローズ前の個数を保持しておく } if(! ExtTrade.PositionClose(orderno)) { Print("PositionClose失敗"); } Print("ResultRetcode -> ", ExtTrade.ResultRetcode()); Sleep(250); } return true; } |
つぎはこちら

TrimPips MQL4とMQL5ソースの共通化(ストレージの使用)
TrimPips MT5対応の一覧 前回 おおかたTrimPipsのMT5対応が完成したのですが ここで問題が。。。 MT5対応でソースをかなり変更したため 元のMT4のソースからだいぶかけ離れて しまったのです。 これは由々しき問題です。
TrimPips MT5対応の一覧
コメント