取引関数のOrdersTotal()、PositionsTotal()について、MQL4とMQL5のソースコード共通化する方法を説明しています。
関数定義
MQL4の定義
int OrdersTotal();
ポジション、オーダーの区別はなくオーダーとポジションの総数を取得します。
MQL5の定義
int OrdersTotal();
オーダーの総数を取得します。
MQL4とMQL5でOrdersTotal()で取得できる数が違うということを意識する必要があります。
共通化方法
MQL5でオーダーはOrder系関数を使った記述をしても、MQL4に移植するとポジションも含まれてしまいます。
ソースを共通化するだけではなく、MQL4→MQL5とMQL5→MQL4への移植のケースもあると思います。よってこれら2つのケースも考慮したソース共通化を考えます。
No. | 移植方法 | 特徴 |
---|---|---|
1 | MQL4→MQL5 | オーダー、ポジション共にOrdersTotal()でオーダーとポジションの総数取得が行われる OrdersTotal()はオーダー、ポジションの区別をしない使われ方をしていることを考慮する必要がある OrdersTotal()によって取得された総数は、全オーダー、ポジションそれぞれに割り当てられたインデックス(順番)との関係がある インデックスを指定して何番目に対する操作を行うといった利用方法があることと、組込み関数であるため関数の動作を変更することが出来ない。 MQL4でOrdersTotal()を使用してオーダーとポジションの総数を期待していても、MQL5に移植するとオーダーの総数となってしまうため、MQL4でオーダーとポジションの総数を期待した実装は避けるべきです。 |
2 | MQL5→MQL4 | OrdersTotal()はMQL4と違いオーダー総数のみの取得であるため、MQL4に移植した際を考慮し、OrderType()、PositionType()によりタイプを意識する必要があります |
ソース共通化
対処方法
OrdersTotal()は、MQL4にもMQL5にも組込み関数があるため対処は使用方法で対処します。
使用例
ポジションとオーダーをオープンし、10秒後にオーダー削除、ポジションクローズをそれぞれ行っています。
input int MagicNumberOrder = 100;
input int MagicNumberPosition = 200;
int iNewTicket = -1;
void OnTick()
{
if (-1 == iNewTicket) {
iNewTicket = OrderSend(Symbol(), OP_BUY, 0.02,
NormalizeDouble(Ask, Digits()), //注文価格
10,
NormalizeDouble(20000, Digits()), //S/L
NormalizeDouble(25500, Digits()), //T/P
"Position",
MagicNumberOrder,
0,
clrBlue);
if (0 < iNewTicket) {
Print("ポジション成功:", iNewTicket);
}
int iNewOrder = OrderSend(Symbol(), OP_BUYSTOP, 0.03,
NormalizeDouble(22000, Digits()), //注文価格
10,
NormalizeDouble(20000, Digits()), //S/L
NormalizeDouble(25000, Digits()), //T/P
"Order",
MagicNumberPosition,
0,
clrBlue);
if (0 < iNewOrder) {
Print("オーダー成功:", iNewOrder);
}
EventSetTimer(10);
}
}
void OnTimer()
{
bool bResult = false;
//注文の削除
for (int iOrderIndex = OrdersTotal() - 1; iOrderIndex >= 0; iOrderIndex--) {
//注文選択
if (!OrderSelect(iOrderIndex, SELECT_BY_POS, MODE_TRADES)) {
continue;
}
if (OP_BUY == OrderType() || OP_SELL == OrderType()) {
continue;
}
//通貨確認
if (Symbol() != OrderSymbol()) {
continue;
}
//削除
bResult = OrderDelete(OrderTicket());
if (bResult) {
Print("オーダーの削除成功:", OrderTicket());
}
}
//ポジションのクローズ
for (int iPositionIndex = PositionsTotal() - 1; iPositionIndex >= 0; iPositionIndex--) {
//ポジション選択
if (!PositionSelect(iPositionIndex, SELECT_BY_POS, MODE_TRADES)) {
continue;
}
if (OP_BUY != PositionType() && OP_SELL != PositionType()) {
continue;
}
//通貨確認
if (Symbol() != PositionSymbol()) {
continue;
}
//価格設定
double dPrice = OP_BUY == PositionType() ? Bid : Ask;
//クローズ
bResult = PositionClose(PositionTicket(), PositionLots(), dPrice, 5);
if (bResult) {
Print("ポジションのクローズ成功:", PositionTicket());
}
}
EventKillTimer();
}
以下の関数については別途説明します。
MT5での実行結果
ポジションとオーダーをオープンし、オーダーの削除、ポジションのクローズを順に行っています。
MT4での実行結果
MQL4でのOrdersTotal()ではオーダーとポジションの総数が取得できますが、ポジションを除外してオーダーを削除しています。
ポジションのクローズについては、PositionsTotal()を参照してください。
コメント