ホーム » ソース共通化 » 取引関数 » PositionsTotal() – 取引関数

PositionsTotal() – 取引関数

取引関数

取引関数PositionsTotal()について、MQL4とMQL5のソースコード共通化する方法を説明しています。

関数定義

MQL4の定義

定義なし

MQL4には、PositionsTotal()がありません。

MQL5の定義

int  PositionsTotal();

ポジションの総数を取得します。
MQL4ではOrdersTotal()オーダーとポジションの総数を取得することを意識する必要があります。

共通化方法

MQL4でオーダーとポジションを区別する概念がありません。そのためPositionsTotal()が存在しないことを考慮します。

ソースを共通化するだけではなく、MQL4→MQL5とMQL5→MQL4への移植のケースもあると思います。よってこれら2つのケースも考慮したソース共通化を考えます。

No.移植方法特徴
1MQL4→MQL5PositionsTotal()が存在しないため、MQL4ではオーダーとポジションの区別のないOrdersTotal()を利用されますが、移植した場合にMQL5ではオーダーとポジションの区別がされるため期待通りの動作にならない結果が生じる可能性があります

MQL4でOrdersTotal()を使用してオーダーとポジションの総数を期待していても、MQL5に移植するとオーダーの総数となってしまうため、MQL4でオーダーとポジションの総数を期待した実装は避けるべきです
2MQL5→MQL4PositionsTotal()はポジション総数のみの取得であるため、MQL4に移植した際を考慮し、OrderType()PositionType()によりタイプを意識する必要があります
考慮すべき移植方法

ソース共通化

対処方法

共通化するためにMQL4用の定義をします。
#ifdef __MQL4__ ~ #endifを使用することでMQL4のコンパイルにのみ有効となります。

#ifdef __MQL4__
///////////////////////////////////////////////////////////////////////////////
// ポジション数を取得する(MQL4では注文も選択される)
int PositionsTotal()
{
	int iResult = OrdersTotal();
	return iResult;
}
#endif

使用例

ポジションとオーダーをオープンし、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();
}

以下の関数については別途説明します。

  1. OrderSend()
  2. PositionSelect()
  3. PositionType()
  4. PositionSymbol()
  5. PositionClose()
MT5での実行結果
MT5での実行結果

ポジションとオーダーをオープンし、オーダーの削除、ポジションのクローズを順に行っています。

MT4での実行結果
MT4での実行結果

MQL4でのPositonsTotal()ではオーダーとポジションの総数が取得できますが、オーダーを除外してポジションを削除しています。
オーダーのクローズについては、OrdersTotal()を参照してください。

コメント

タイトルとURLをコピーしました