指定したプロパティでオブジェクトを比較する仮想メソッドは、標準ライブラリのCObjectクラスで宣言されています。しかし、このメソッドはサブクラスで実装する必要があります。そこで、「抽象注文クラス」に、COrderオブジェクトをそのプロパティのいずれかによって比較するメソッドを追加してみましょう。
また、注文のプロパティにアクセスするためのいくつかのパブリックメソッドと、注文オブジェクトの特定のプロパティをサポートするためのフラグを返す仮想メソッドも追加します。これは、後でコレクションリストから注文をそのプロパティのいずれかによって選択する際に必要となります。デフォルトでは、これらのメソッドのいずれかが下位クラスに実装されていない場合、そのプロパティに対する注文のサポートを示すフラグが返されます。
2つのオーダーを指定したプロパティで比較するメソッドを実装しています。このメソッドは、ある値と比較されるべきプロパティを持つ注文オブジェクトへのポインタと、その値自体を注文プロパティ列挙体から受け取ります。
順番の値が比較された値よりも大きい場合、システムは 1 を返し、比較された値よりも小さい場合、システムは -1 を返し、そうでない場合は -0 を返します。比較が行われるオーダーのリストは、あらかじめ compared プロパティでソートされている必要があります。
//+------------------------------------------------------------------+
//| COrderオブジェクトをすべての可能なプロパティで比較する |
//+------------------------------------------------------------------+
int COrder::Compare(const CObject *node,const int mode=0) const
{
const COrder *order_compared=node;
//--- 2つの注文の整数プロパティを比較する
if(mode<ORDER_PROP_INTEGER_TOTAL)
{
long value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
long value_current=this.GetProperty((ENUM_ORDER_PROP_INTEGER)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
//--- 2つの注文の実数プロパティを比較する
else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL)
{
double value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
double value_current=this.GetProperty((ENUM_ORDER_PROP_DOUBLE)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
//--- 2つの注文の文字列プロパティを比較する
else if(mode<ORDER_PROP_DOUBLE_TOTAL+ORDER_PROP_INTEGER_TOTAL+ORDER_PROP_STRING_TOTAL)
{
string value_compared=order_compared.GetProperty((ENUM_ORDER_PROP_STRING)mode);
string value_current=this.GetProperty((ENUM_ORDER_PROP_STRING)mode);
return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
}
return 0;
}
//+------------------------------------------------------------------+
では、オーダーのプロパティを受け取り、プロパティ配列に書き込むメソッドを実装しましょう。これらのメソッドは、あらかじめprivateセクションで宣言されているメソッドです。順番のプロパティを受け取るメソッドはクロスプラットフォームなので、EAのマジックナンバーを受け取ることを例にして分析してみましょう。扱っているものに応じて、ポジション、注文、取引マジックナンバーのいずれかを返します。
//+------------------------------------------------------------------+
//| マジックナンバーを返す |
//+------------------------------------------------------------------+
long COrder::OrderMagicNumber() const
{
#ifdef __MQL4__
return ::OrderMagicNumber();
#else
long res=0;
switch((ENUM_ORDER_STATUS)this.GetProperty(ORDER_PROP_STATUS))
{
case ORDER_STATUS_MARKET_ACTIVE : res=::PositionGetInteger(POSITION_MAGIC); break;
case ORDER_STATUS_MARKET_PENDING : res=::OrderGetInteger(ORDER_MAGIC); break;
case ORDER_STATUS_DEAL : res=::HistoryDealGetInteger(m_ticket,DEAL_MAGIC); break;
case ORDER_STATUS_HISTORY_PENDING :
case ORDER_STATUS_HISTORY_ORDER : res=::HistoryOrderGetInteger(m_ticket,ORDER_MAGIC); break;
default : res=0; break;
}
return res;
#endif
}
//+------------------------------------------------------------------+