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

OrderLots() – 取引関数

取引関数

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

関数定義

MQL4の定義

double  OrderLots();

ポジション、オーダーの区別はなくボリューム(ロットサイズ)を取得します。

MQL5の定義

定義なし

MQL5には、OrderLots()がありません。
MQL5では、オーダーボリュームとポジションボリュームで区別されている点がMQL4と変更点です。

共通化方法

  • Order系関数はオーダーで使用することとする
    OrderLots()
  • Position系関数はポジションで使用することとする
    PositionLots()

ただし、MQL5でオーダーはOrder系関数を使った記述をしても、MQL4に移植するとポジションも含まれてしまいます。

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

No.移植方法特徴
1MQL4→MQL5オーダー、ポジション共にOrderLots()でボリュームの取得が行われている
OrderLots()はオーダー、ポジションの区別をしない使われ方をしていることを考慮する必要がある
PositionLots()の使用に分けた実装にすることが望ましい
2MQL5→MQL4MQL4と同じ引数のOrderLots()を定義するが、OrderLots()はオーダーのボリューム取得することと定義し、ポジションはPositionLots()関数を定義して利用することとする
考慮すべき移植方法

ソース共通化

対処方法

共通化するためにMQL4とMQL5用の定義をします。
#ifdef __MQL5__ ~ #elseを使用することでMQL5のコンパイルにのみ有効となります。
#else~#endifはMQL5以外となるため、必然的にMQL4でのコンパイルのみ有効となります。

#ifdef __MQL5__
///////////////////////////////////////////////////////////////////////////////
// オーダーのロットサイズを取得
double OrderLots()
{
	double dResult = OrderGetDouble(ORDER_VOLUME_CURRENT);
	return dResult;
}
///////////////////////////////////////////////////////////////////////////////
// ポジションのシンボルを取得する
string PositionSymbol()
{
	string strSymbol = PositionGetString(POSITION_SYMBOL);
	return strSymbol;
}
#else	//__MQL4__
///////////////////////////////////////////////////////////////////////////////
// ポジションのロットサイズを取得
double PositionLots()
{
	return OrderLots();
}
#endif

MQL5にOrderLots()とPositionLots()の定義をし、MQL4にはPositionLots()を定義しています。
MQL4のPositionLots()は、OrderLots()をそのまま呼び出す移植用のラッパー関数でしかありません。そのため、オーダーに対して使用してもそのまま動作します。よってMQL5に移植した場合に動作が不一致になるため、間違った使用をしないように注意が必要です。

使用例

ポジションとオーダーをオープンし、それぞれでポジションボリュームとオーダーボリュームを取得しています。

input	int			MagicNumber = 1;
int iNewTicket = -1;
int OnInit()
{
#ifdef __MQL5__
	Print("これはMT5で動作しています");
#else	//__MQL4__
	Print("これはMT4で動作しています");
#endif
	return(INIT_SUCCEEDED);
}
void OnTick()
{
	if (-1 == iNewTicket) {
		iNewTicket = OrderSend(Symbol(), OP_BUY, 0.02,
					NormalizeDouble(Ask, Digits()),		//注文価格
					10,
					NormalizeDouble(100, Digits()),		//S/L
					NormalizeDouble(150, Digits()),		//T/P
					"",
					MagicNumber,
					0,
					clrBlue);
		if (0 <= iNewTicket) {
			if (PositionSelect(iNewTicket, SELECT_BY_TICKET)) {
				Print("PositionLots():", DoubleToString(PositionLots(), 2));
				Print("OrderLots():", DoubleToString(OrderLots(), 2));
			}
		}
		int iNewOrder = OrderSend(Symbol(), OP_BUYSTOP, 0.03,
					NormalizeDouble(140, Digits()),		//注文価格
					10,
					NormalizeDouble(100, Digits()),		//S/L
					NormalizeDouble(150, Digits()),		//T/P
					"",
					MagicNumber,
					0,
					clrBlue);
		if (0 <= iNewOrder) {
			if (OrderSelect(iNewOrder, SELECT_BY_TICKET)) {
				Print("PositionLots():", DoubleToString(PositionLots(), 2));
				Print("OrderLots():", DoubleToString(OrderLots(), 2));
			}
		}
	}
}

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

  1. OrderSend()
  2. OrderSelect()、PositionSelect()
MT5での実行結果
MT5での実行結果

1回目のOrderLots()はポジションであるため、オーダーボリュームは取得できません(0.00)。
2回目のPositionLots()は最初に約定したポジションのオーダーボリュームがそのまま引き継がれているため、2回目もオーダーボリュームは0.02になります。

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

1回目のOrderLots()はポジションにもかかわらず、オーダーボリュームは0.02になります。
2回目のPositionLots()はオーダーにもかかわらず、オーダーボリューム0.03になります。

これらの差が、ポジションとオーダーを区別していないMQL4での特徴です。この特徴を認識した上で注意した実装が必要です。

コメント

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