MetaTraderプログラムを簡単かつ迅速に開発するためのライブラリ(第17部): ライブラリオブジェクトの相互作用
Artyom Trishkin | 13 12月, 2019
内容
前の記事では、すべてのライブラリオブジェクトの基本オブジェクトを作成しました。基本オブジェクトから継承されたオブジェクトはイベント機能を受け取ります。これにより、基本オブジェクトの下位クラスプロパティで発生するイベントを簡単に追跡できます。
今日は、さらに進んで、オブジェクト(および他のすべてのライブラリオブジェクト)に、変更、サイズの変更、オブジェクトプロパティの値レベルに関して外部から制御するプロパティを設定する機能を付与します。したがって、すべてのライブラリオブジェクトは、ユーザがライブラリオブジェクトと対話できる機能を受け取ります。
たとえば、ポジションを開くためにスプレッドと価格レベルを確認するとします。制御されたスプレッドサイズを簡単に設定し、指定されたレベルに達する価格を追跡し、ポジションを開くことができます。ここでしなければならないのは、取引が可能な最大スプレッドサイズと、銘柄オブジェクトからのイベントがプログラムに送信されてスプレッドと価格レベルによる取引が可能になる価格レベルをプログラムで設定することです。
もう1つの重要なことは、イベントフラグを使用する必要性をなくすことです(イベントフラグは、イベントの追跡に制限を課し、各オブジェクトのすべての可能なイベントタイプの列挙リストの保存を要求します)。可能性のあるイベントの数は、オブジェクトプロパティの数(整数および実数)に対応します。追跡されるべきではないプロパティはLONG_MAX値によって初期化され、オブジェクトイベントの検索に関与しません。
ライブラリオブジェクトはコレクションに格納されます。コレクションのオブジェクトプロパティの更新は、コレクションリストに格納されたオブジェクトのRefresh()メソッドが呼び出されるコレクションのRefresh()メソッドを使用して、ライブラリタイマーで実行されます。基本オブジェクトのRefresh()メソッドで子孫オブジェクトの変更を追跡する場合、各ライブラリオブジェクトの単純なイベントモデルを作成できます。各オブジェクトは、イベントのリストをCEngineライブラリメインオブジェクトに送信します。
したがって、ライブラリに基づいたプログラムは、コレクションのオブジェクトで発生したすべてのイベントを常に認識しています。また、コレクションの各オブジェクトのプロパティの制御値のサイズは常にプログラムで設定および変更できます。
これはすべて、すべてのライブラリオブジェクトの基本オブジェクトの単純なクラスによって実現されます。
ライブラリ基本オブジェクトイベントの制御メソッド
ライブラリ基本オブジェクトのイベントの操作は次のように配置されます。以前は、特定のクラスのイベントを定義するために、個別のイベント制御メソッドを実装し、イベントのフラグを作成し、可能なオブジェクトイベントの列挙を行いました。子孫クラスイベントの制御が唯一の基本クラスに配置されるようになったため、これが銘柄イベント、口座イベント、または後で作成される他のクラスのイベントであるかどうかに関係なく、ユニバーサルイベント制御を実装する必要があります。したがって、これはオブジェクトプロパティの状態(整数および実数)の変化を制御するのに適した場所です。各子孫クラスのリストは一意であり、イベントIDを表します。また、プロパティの変更の方向、つまりプロパティ値の増減(イベントの理由と呼びます)、およびオブジェクトプロパティの変更値を考慮する必要があります。イベントID、理由、および変更値は、オブジェクト基本イベントの単純なクラスに書き込まれ、同時に発生したイベントのリストに保存されます。
プログラムにイベントを送信するために、厳密に指定されたパラメータ(イベントID、 'long'、 'double'、および
'string'値)を持つイベントを使用することには既に同意しています。longパラメータでは、イベント時間をミリ秒単位で送信しました。ここで、イベントの定義が変更したので、いくつかのパラメータによってイベントを正確に定義する必要があります。
- イベントID - オブジェクトのプロパティを変更しました。各オブジェクトには固有のプロパティがあります。プログラムは、プロパティが変更されたオブジェクトについては何も知らないだけでなく、変更されたプロパティの状態(整数または実数)についても何も知らないため、イベントIDで正確に定義することは不可能です。
- イベントの理由 -
プロパティ値の増減または制御されたレベルを超えること。この値では、イベントを正確に判断することもできません。しかし、イベントIDと理由により、特定のオブジェクトプロパティが増加または減少したこと、または指定された制御値を超えたことを定義できます。したがって、イベントを正確に特定するには、イベントが発生したオブジェクトのクラスIDを指定する必要があります。
コレクションリストは、オブジェクトが属するクラス(銘柄、口座、または将来作成される他のコレクションオブジェクト)を正確に定義するのに最適です。したがって、次のデータをイベントに追加で送信する必要があります。
- コレクションID - 上記の3つのIDにより、イベントを正確に定義できます。
- イベント文字列プロパティ — イベントが発生したオブジェクトの名前。
したがって、イベントを定義するには、3つの整数パラメータを取得するとともに、イベント名を取得する必要があります。イベント名もlong値で渡されます。longイベントプロパティは1つだけです。何をすべきでしょうか。解決策は簡単です。1つのlongパラメータで3つのushort型整数イベントを渡します。longは8バイト、ushortは2バイトです。したがって、longコンテナを使用すると、long値のバイト0、1、バイト2、3、バイト4、5に書き込まれた3つのushort値を保存できますが、まだバイト6と7があるので、後で必要な場合、さらに別のushort値を渡すことができます。
イベント時間を定義するには、longパラメータのバイト0および1で時間ミリ秒を渡すだけです。
- イベントの日付と時刻は、イベントを取得するときにTimeCurrent()から取得でき、イベントのlong値のバイト0および1で渡されるミリ秒数を追加します。
- イベントの理由は、イベントのlongパラメータのバイト2および3に設定され、
- クラスIDは、イベントのlongパラメータのバイト4および5に設定されます。
したがって、イベントを受信すると、longパラメータから3つのushort値を取得してイベント時間を定義し、custom_event_id ushortパラメータとしてEventChartCustom()に渡されたイベントIDによる正確なイベント識別のための追加データを取得するとともに、イベントIDとlparamからさらに取得された2つの値を使用して、発生したイベントの正確なIDを構築します。
親オブジェクトタイマーで、各オブジェクトプロパティの現在の状態を確認し、前の状態と比較して、子孫オブジェクトプロパティでイベントを定義します。まず、プロパティ変更と比較する値が設定されているかどうかを確認します。確認された値が設定されていない場合(LONG_MAXが設定されている場合)、このプロパティは無視されます。
longおよび「double」型のオブジェクトプロパティのリストを確認するため、オブジェクトプロパティの現在および以前の状態を保存するには構造体よりも2次元配列を使用する方が合理的です。配列の最初の次元はオブジェクトプロパティインデックスを格納するためのものであり、2番目の次元はインデックスが最初の次元で設定されたプロパティの値、プロパティ変更値、および制御された値とプロパティイベントのフラグを格納するためのものです。
構造体よりも配列を使用する方が便利な理由を説明します。
確認するプロパティの型は事前にわかりません。ただし、その型はプロパティインデックスで確認できます(「double」オブジェクトプロパティは常にlongプロパティの後に配置されます)。これは、同じオブジェクトプロパティ値のlongおよび「double」値のために構造体内のフィールドを複製する必要がないことを意味します。オブジェクトプロパティの状態を制御するためには、必要なデータを正しい型で必要な型の配列に書き込むだけです(プロパティインデックスから定義されたプロパティ型に対応)。したがって、渡された値を設定する構造体フィールド(longまたはdouble)を選択する必要はありません。
オブジェクトプロパティのいずれかの変更が定義されたら、すぐにそれを基本オブジェクトイベントのリストに追加します(検索は基本オブジェクトで行われるため、イベントは基本的であるべきで、基本イベントのリストによって定義され、基本イベントから作成される子孫クラスイベントと混同されてはいけません。これらへのポインタはリストに格納されます)。
プロパティ変更のリスト(基本イベントリスト)は、各基本オブジェクトの子孫クラスのRefresh()メソッドのタイマーで確認されます。オブジェクトリストにこれらのイベントが含まれている場合、各イベントはライブラリイベントに変換され、制御プログラムに送信されます。
図を完全にするには、基本オブジェクトに基づいてライブラリオブジェクトのプロパティの制御された変更値をプログラムで設定できるメソッドを作成する必要があります。これにより、必要なオブジェクトからイベントを生成するための必須条件をいつでもすばやく変更できます。
ライブラリ基本オブジェクトを改善することを目的としたここで取られるすべての手段のセットにより、その後作成されるすべてのオブジェクトのイベント制御を作成することを検討する必要がなくなります。代わりに、既製の機能を使用します。
始めましょう。
すべてのライブラリオブジェクトの基本オブジェクトでイベントを処理するため、イベントを識別するためにイベント理由列挙を作成する必要があります。
\MQL5\Include\DoEasy\Defines.mqhファイルで、時間オプションの後に考えられるベースオブジェクトイベントの理由の列挙を追加します。
//+------------------------------------------------------------------+ //| Possible options of selecting by time | //+------------------------------------------------------------------+ enum ENUM_SELECT_BY_TIME { SELECT_BY_TIME_OPEN, // By open time (in milliseconds) SELECT_BY_TIME_CLOSE, // By close time (in milliseconds) }; //+------------------------------------------------------------------+ //| Possible event reasons of the object library base object | //+------------------------------------------------------------------+ enum ENUM_BASE_EVENT_REASON { BASE_EVENT_REASON_INC, // Increase in the object property value BASE_EVENT_REASON_DEC, // Decrease in the object property value BASE_EVENT_REASON_MORE_THEN, // Object property value exceeds the control value BASE_EVENT_REASON_LESS_THEN, // Object property value is less than the control value BASE_EVENT_REASON_EQUALS // Object property value is equal to the control value }; //+------------------------------------------------------------------+
イベントフラグが不要になったため、銘柄イベントフラグリストを[気配値表示]ウィンドウで可能な銘柄イベントのリストに置き換えます。
//+------------------------------------------------------------------+ //| Data for working with symbols | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| List of possible symbol events in the Market Watch window | //+------------------------------------------------------------------+ enum ENUM_MW_EVENT { MARKET_WATCH_EVENT_NO_EVENT = ACCOUNT_EVENTS_NEXT_CODE, // No event MARKET_WATCH_EVENT_SYMBOL_ADD, // Adding a symbol to the Market Watch window MARKET_WATCH_EVENT_SYMBOL_DEL, // Removing a symbol from the Market Watch window MARKET_WATCH_EVENT_SYMBOL_SORT, // Sorting symbols in the Market Watch window }; #define SYMBOL_EVENTS_NEXT_CODE (MARKET_WATCH_EVENT_SYMBOL_SORT+1) // The code of the next event after the last symbol event code //+------------------------------------------------------------------+
不要になったため、可能な銘柄イベントのリストを削除します。
//+------------------------------------------------------------------+ //| List of possible symbol events | //+------------------------------------------------------------------+ enum ENUM_SYMBOL_EVENT { SYMBOL_EVENT_NO_EVENT = ACCOUNT_EVENTS_NEXT_CODE, // No event SYMBOL_EVENT_MW_ADD, // Adding a symbol to the Market Watch window SYMBOL_EVENT_MW_DEL, // Removing a symbol from the Market Watch window SYMBOL_EVENT_MW_SORT, // Sorting symbols in the Market Watch window SYMBOL_EVENT_TRADE_DISABLE, // Disable order execution SYMBOL_EVENT_TRADE_LONGONLY, // Allow buy only SYMBOL_EVENT_TRADE_SHORTONLY, // Allow sell only SYMBOL_EVENT_TRADE_CLOSEONLY, // Enable close only SYMBOL_EVENT_TRADE_FULL, // No trading limitations SYMBOL_EVENT_SESSION_DEALS_INC, // The increase in the number of deals in the current session exceeds the specified value SYMBOL_EVENT_SESSION_DEALS_DEC, // The decrease in the number of deals in the current session exceeds the specified value SYMBOL_EVENT_SESSION_BUY_ORDERS_INC, // The increase in the total number of buy orders currently exceeds the specified value SYMBOL_EVENT_SESSION_BUY_ORDERS_DEC, // The decrease in the total number of buy orders currently exceeds the specified value SYMBOL_EVENT_SESSION_SELL_ORDERS_INC, // The increase in the total number of sell orders currently exceeds the specified value SYMBOL_EVENT_SESSION_SELL_ORDERS_DEC, // The decrease in the total number of sell orders currently exceeds the specified value SYMBOL_EVENT_VOLUME_INC, // Volume increase in the last deal exceeds the specified value SYMBOL_EVENT_VOLUME_DEC, // Volume decrease in the last deal exceeds the specified value SYMBOL_EVENT_VOLUME_HIGH_DAY_INC, // The increase in the maximum volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_HIGH_DAY_DEC, // The decrease in the maximum volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_LOW_DAY_INC, // The increase in the minimum volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_LOW_DAY_DEC, // The decrease in the minimum volume per day exceeds the specified value SYMBOL_EVENT_SPREAD_INC, // The increase in a spread exceeds the specified change SYMBOL_EVENT_SPREAD_DEC, // The decrease in a spread exceeds the specified change SYMBOL_EVENT_STOPLEVEL_INC, // The increase of a Stop order level exceeds the specified value SYMBOL_EVENT_STOPLEVEL_DEC, // The decrease of a Stop order level exceeds the specified value SYMBOL_EVENT_FREEZELEVEL_INC, // The increase in the freeze level exceeds the specified value SYMBOL_EVENT_FREEZELEVEL_DEC, // The decrease in the freeze level exceeds the specified value SYMBOL_EVENT_BID_LAST_INC, // The increase in the Bid or Last price exceeds the specified value SYMBOL_EVENT_BID_LAST_DEC, // The decrease in the Bid or Last price exceeds the specified value SYMBOL_EVENT_BID_LAST_HIGH_INC, // The increase in the maximum Bid or Last price per day exceeds the specified value SYMBOL_EVENT_BID_LAST_HIGH_DEC, // The decrease in the maximum Bid or Last price per day exceeds the specified value relative to the specified price SYMBOL_EVENT_BID_LAST_LOW_INC, // The increase in the minimum Bid or Last price per day exceeds the specified value relative to the specified price SYMBOL_EVENT_BID_LAST_LOW_DEC, // The decrease in the minimum Bid or Last price per day exceeds the specified value SYMBOL_EVENT_ASK_INC, // The increase in the Ask price exceeds the specified value SYMBOL_EVENT_ASK_DEC, // The decrease in the Ask price exceeds the specified value SYMBOL_EVENT_ASK_HIGH_INC, // The increase in the maximum Ask price per day exceeds the specified value SYMBOL_EVENT_ASK_HIGH_DEC, // The decrease in the maximum Ask price per day exceeds the specified value SYMBOL_EVENT_ASK_LOW_INC, // The increase in the minimum Ask price per day exceeds the specified value SYMBOL_EVENT_ASK_LOW_DEC, // The decrease in the minimum Ask price per day exceeds the specified value SYMBOL_EVENT_VOLUME_REAL_DAY_INC, // The increase in the real volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_REAL_DAY_DEC, // The decrease in the real volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_HIGH_REAL_DAY_INC, // The increase in the maximum real volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_HIGH_REAL_DAY_DEC, // The decrease in the maximum real volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_LOW_REAL_DAY_INC, // The increase in the minimum real volume per day exceeds the specified value SYMBOL_EVENT_VOLUME_LOW_REAL_DAY_DEC, // The decrease in the minimum real volume per day exceeds the specified value SYMBOL_EVENT_OPTION_STRIKE_INC, // The increase in the strike price exceeds the specified value SYMBOL_EVENT_OPTION_STRIKE_DEC, // The decrease in the strike price exceeds the specified value SYMBOL_EVENT_VOLUME_LIMIT_INC, // The increase in the maximum available total position volume and pending orders in one direction SYMBOL_EVENT_VOLUME_LIMIT_DEC, // The decrease in the maximum available total position volume and pending orders in one direction SYMBOL_EVENT_SWAP_LONG_INC, // The increase in the swap long SYMBOL_EVENT_SWAP_LONG_DEC, // The decrease in the swap long SYMBOL_EVENT_SWAP_SHORT_INC, // The increase in the swap short SYMBOL_EVENT_SWAP_SHORT_DEC, // The decrease in the swap short SYMBOL_EVENT_SESSION_VOLUME_INC, // The increase in the total volume of deals in the current session exceeds the specified value SYMBOL_EVENT_SESSION_VOLUME_DEC, // The decrease in the total volume of deals in the current session exceeds the specified value SYMBOL_EVENT_SESSION_TURNOVER_INC, // The increase in the total turnover in the current session exceeds the specified value SYMBOL_EVENT_SESSION_TURNOVER_DEC, // The decrease in the total turnover in the current session exceeds the specified value SYMBOL_EVENT_SESSION_INTEREST_INC, // The increase in the total volume of open positions in the current session exceeds the specified value SYMBOL_EVENT_SESSION_INTEREST_DEC, // The decrease in the total volume of open positions in the current session exceeds the specified value SYMBOL_EVENT_SESSION_BUY_ORD_VOLUME_INC, // The increase in the total volume of buy orders exceeds the specified value SYMBOL_EVENT_SESSION_BUY_ORD_VOLUME_DEC, // The decrease in the total volume of buy orders exceeds the specified value SYMBOL_EVENT_SESSION_SELL_ORD_VOLUME_INC, // The increase in the total volume of sell orders exceeds the specified value SYMBOL_EVENT_SESSION_SELL_ORD_VOLUME_DEC, // The decrease in the total volume of sell orders exceeds the specified value SYMBOL_EVENT_SESSION_OPEN_INC, // The increase in the session open price exceeds the specified value relative to the specified price SYMBOL_EVENT_SESSION_OPEN_DEC, // The decrease in the session open price exceeds the specified value relative to the specified price SYMBOL_EVENT_SESSION_CLOSE_INC, // The increase in the session close price exceeds the specified value relative to the specified price SYMBOL_EVENT_SESSION_CLOSE_DEC, // The decrease in the session close price exceeds the specified value relative to the specified price SYMBOL_EVENT_SESSION_AW_INC, // The increase in the average weighted session price exceeds the specified value SYMBOL_EVENT_SESSION_AW_DEC, // The decrease in the average weighted session price exceeds the specified value }; #define SYMBOL_EVENTS_NEXT_CODE (SYMBOL_EVENT_SESSION_AW_DEC+1) // The code of the next event after the last symbol event code //+------------------------------------------------------------------+
次のイベントのコードはENUM_MW_EVENT列挙体の MARKET_WATCH_EVENT_SYMBOL_SORT定数に続く値に置き換えられました。
計画された機能を実装しましょう。
\MQL5\Include\DoEasy\Objects\BaseObj.mqh基本オブジェクトファイルに、基本イベントの新しいクラスを追加します。
//+------------------------------------------------------------------+ //| Library object's base event class | //+------------------------------------------------------------------+ class CBaseEvent : public CObject { private: ENUM_BASE_EVENT_REASON m_reason; int m_event_id; double m_value; public: ENUM_BASE_EVENT_REASON Reason(void) const { return this.m_reason; } int ID(void) const { return this.m_event_id; } double Value(void) const { return this.m_value; } //--- コンストラクタ CBaseEvent(const int event_id,const ENUM_BASE_EVENT_REASON reason,const double value) : m_reason(reason), m_event_id(event_id), m_value(value){} //--- Comparison method to search for identical event objects virtual int Compare(const CObject *node,const int mode=0) const { const CBaseEvent *compared=node; return ( this.Reason()>compared.Reason() ? 1 : this.Reason()<compared.Reason() ? -1 : this.ID()>compared.ID() ? 1 : this.ID()<compared.ID() ? -1 : 0 ); } }; //+------------------------------------------------------------------+
クラスのprivateセクションには、イベントの理由、イベントID(変更されたオブジェクトプロパティのインデックスと一致)、イベントプロパティの変更値を保存するための変数があります
。クラスのpublicセクションには、上記のクラスメンバ変数を返すためのメソッドがあります。
クラスコンストラクタの仮パラメーターは、プロパティ値を受け取ります。渡された値は、初期化リストの適切なクラスメンバ変数にすぐに割り当てられます。
また、このクラスには、何回か前述したように、オブジェクトへの動的ポインタのリストで検索するために2つのクラスオブジェクトを比較するメソッドがあります。
制御オブジェクトプロパティのリストを2次元配列に格納するため、2番目の配列次元のサイズを指すマクロ置換を追加します。クラスのprivateセクションで、クラスから継承される整数の数とオブジェクトの実数プロパティを格納する2つの変数を宣言します(
基本クラスはその子孫が持つプロパティの番号について何も知らないため、これらの数は明示的に表示する必要があります)。
プロパティ配列に入力するメソッドを宣言して、子孫オブジェクトのプロパティの変更を検索します。
//+------------------------------------------------------------------+ //| Base object class for all library objects | //+------------------------------------------------------------------+ #define CONTROLS_TOTAL (10) class CBaseObj : public CObject { private: int m_long_prop_total; int m_double_prop_total; //--- Fill in the object property array template<typename T> bool FillPropertySettings(const int index,T &array[][CONTROLS_TOTAL],T &array_prev[][CONTROLS_TOTAL],int &event_id); protected:
クラスのprotectedセクションで、オブジェクト基本イベントインスタンスへのポインタを格納するリスト、イベントIDを格納する変数、最初の起動フラグ、および子孫オブジェクト型を格納する変数を宣言します。
また、プロパティを保存してその変更を制御するための4つの2次元配列(現在および以前の整数および実数の子孫オブジェクトプロパティ)、およびイベント時間に格納されたミリ秒のみを返すメソッド
(MQL4の場合は0を返し、MQL5の場合は時間long値を1000で除算した余りを返します)を追加しました。
基本クラスは子孫オブジェクトのプロパティの数について何も知らないので、サイズは子孫クラス(既知の場合)から設定する必要がありますが、配列のサイズを設定および確認するためのメソッドを宣言します。
protected: CArrayObj m_list_events_base; // Object base event list CArrayObj m_list_events; // Object event list MqlTick m_tick; // Tick structure for receiving quote data double m_hash_sum; // Object data hash sum double m_hash_sum_prev; // Object data hash sum during the previous check int m_digits_currency; // Number of decimal places in an account currency int m_global_error; // Global error code long m_chart_id; // Control program chart ID bool m_is_event; // Object event flag int m_event_code; // Object event code int m_event_id; // Event ID (equal to the object property value) string m_name; // Object name string m_folder_name; // Name of the folder storing CBaseObj descendant objects bool m_first_start; // First launch flag int m_type; // Object type (corresponds to the collection IDs) //--- Data in the array cells //--- Data for storing, controlling and returning tracked properties: //--- [Property index][0] Controlled property increase value //--- [Property index][1] Controlled property decrease value //--- [Property index][2] Controlled property value level //--- [Property index][3] Property value //--- [Property index][4] Property value change //--- [Property index][5] Flag of a property change exceeding the increase value //--- [Property index][6] Flag of a property change exceeding the decrease value //--- [Property index][7] Flag of a property increase exceeding the control level //--- [Property index][8] Flag of a property decrease being less than the control level //--- [Property index][9] Flag of a property value being equal to the control level long m_long_prop_event[][CONTROLS_TOTAL]; // The array for storing object's integer properties values and controlled property change values double m_double_prop_event[][CONTROLS_TOTAL]; // The array for storing object's real properties values and controlled property change values long m_long_prop_event_prev[][CONTROLS_TOTAL]; // The array for storing object's controlled integer properties values during the previous check double m_double_prop_event_prev[][CONTROLS_TOTAL]; // The array for storing object's controlled real properties values during the previous check //--- Return (1) time in milliseconds, (2) milliseconds from the MqlTick time value long TickTime(void) const { return #ifdef __MQL5__ this.m_tick.time_msc #else this.m_tick.time*1000 #endif ; } ushort MSCfromTime(const long time_msc) const { return #ifdef __MQL5__ ushort(this.TickTime()%1000) #else 0 #endif ; } //--- return the flag of the event code presence in the event object bool IsPresentEventFlag(const int change_code) const { return (this.m_event_code & change_code)==change_code; } //--- Return the number of decimal places of the account currency int DigitsCurrency(void) const { return this.m_digits_currency; } //--- Returns the number of decimal places in the 'double' value int GetDigits(const double value) const; //--- Set the size of the array of controlled (1) integer and (2) real object properties bool SetControlDataArraySizeLong(const int size); bool SetControlDataArraySizeDouble(const int size); //--- Check the array size of object properties bool CheckControlDataArraySize(bool check_long=true); //--- Set the (1) controlled value and (2) object property change value template<typename T> void SetControlledValue(const int property,const T value); template<typename T> void SetControlledChangedValue(const int property,const T value); //--- Set the value of the pbject property controlled (1) increase, (2) decrease, (3) control level template<typename T> void SetControlledValueINC(const int property,const T value); template<typename T> void SetControlledValueDEC(const int property,const T value); template<typename T> void SetControlledValueLEVEL(const int property,const T value); //--- Set the flag of a property change exceeding the (1) increase and (2) decrease values template<typename T> void SetControlledFlagINC(const int property,const T value); template<typename T> void SetControlledFlagDEC(const int property,const T value); //--- Set the flag of a property change (1) exceeding, (2) being less than the control level, (3) being equal to the level template<typename T> void SetControlledFlagMORE(const int property,const T value); template<typename T> void SetControlledFlagLESS(const int property,const T value); template<typename T> void SetControlledFlagEQUAL(const int property,const T value); //--- Return the set value of the controlled (1) integer and (2) real object properties increase long GetControlledValueLongINC(const int property) const { return this.m_long_prop_event[property][0]; } double GetControlledValueDoubleINC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][0]; } //--- Return the set value of the controlled (1) integer and (2) real object properties decrease long GetControlledValueLongDEC(const int property) const { return this.m_long_prop_event[property][1]; } double GetControlledValueDoubleDEC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][1]; } //--- Return the control level of object's (1) integer and (2) real properties long GetControlledValueLongLEVEL(const int property) const { return this.m_long_prop_event[property][2]; } double GetControlledValueDoubleLEVEL(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][2]; } //--- Return the value of the object (1) integer and (2) real property long GetControlledValueLong(const int property) const { return this.m_long_prop_event[property][3]; } double GetControlledValueDouble(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][3]; } //--- Return the change value of the controlled (1) integer and (2) real object property long GetControlledChangedValueLong(const int property) const { return this.m_long_prop_event[property][4]; } double GetControlledChangedValueDouble(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][4]; } //--- Return the flag of an (1) integer and (2) real property value change exceeding the increase value long GetControlledFlagLongINC(const int property) const { return this.m_long_prop_event[property][5]; } double GetControlledFlagDoubleINC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][5]; } //--- Return the flag of an (1) integer and (2) real property value change exceeding the decrease value long GetControlledFlagLongDEC(const int property) const { return this.m_long_prop_event[property][6]; } double GetControlledFlagDoubleDEC(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][6]; } //--- Return the flag of an (1) integer and (2) real property value increase exceeding the control level long GetControlledFlagLongMORE(const int property) const { return this.m_long_prop_event[property][7]; } double GetControlledFlagDoubleMORE(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][7]; } //--- Return the flag of an (1) integer and (2) real property value decrease being less than the control level long GetControlledFlagLongLESS(const int property) const { return this.m_long_prop_event[property][8]; } double GetControlledFlagDoubleLESS(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][8]; } //--- Return the flag of an (1) integer and (2) real property being equal to the control level long GetControlledFlagLongEQUAL(const int property) const { return this.m_long_prop_event[property][9]; } double GetControlledFlagDoubleEQUAL(const int property) const { return this.m_double_prop_event[property-this.m_long_prop_total][9]; } //--- (1) Pack a 'ushort' number to a passed 'long' number //--- (2) convert a 'ushort' value to a specified 'long' number byte long UshortToLong(const ushort ushort_value,const uchar index,long &long_value); long UshortToByte(const ushort value,const uchar index) const; public:
クラスのprivateセクションには、制御対象プロパティとその値を設定および返すためのメソッドとインデックスによって指定されたlongコンテナバイトにushort数をパックするメソッドも宣言されています。(Index
0 => bytes 0-1, Index 1 => bytes 2-3, Index 2 => bytes 4-5)
クラスのpublicセクションで、変更されたプロパティの値をリセットするメソッド、制御オブジェクトプロパティの値をリセットするメソッド、リストに基本イベントを追加するメソッド、インデックスによってリストから基本オブジェクトを受け取るメソッド、リスト内の基本オブジェクトの数を返すメソッド、オブジェクト型を返す仮想メソッド、基本イベントの文字列の説明を返すメソッドを宣言します。
public: //--- Reset the variables of (1) tracked and (2) controlled object data (can be reset in the descendants) void ResetChangesParams(void); virtual void ResetControlsParams(void); //--- Add the (1) object event and (2) the object event reason to the list bool EventAdd(const ushort event_id,const long lparam,const double dparam,const string sparam); bool EventBaseAdd(const int event_id,const ENUM_BASE_EVENT_REASON reason,const double value); //--- Return the occurred event flag to the object data bool IsEvent(void) const { return this.m_is_event; } //--- Return (1) the list of events, (2) the object event code and (3) the global error code CArrayObj *GetListEvents(void) { return &this.m_list_events; } int GetEventCode(void) const { return this.m_event_code; } int GetError(void) const { return this.m_global_error; } //--- Return (1) an event object and (2) a base event by its number in the list CEventBaseObj *GetEvent(const int shift=WRONG_VALUE,const bool check_out=true); CBaseEvent *GetEventBase(const int index); //--- Return the number of (1) object events int GetEventsTotal(void) const { return this.m_list_events.Total(); } //--- (1) Set and (2) return the chart ID of the control program void SetChartID(const long id) { this.m_chart_id=id; } long GetChartID(void) const { return this.m_chart_id; } //--- (1) Set the sub-folder name, (2) return the folder name for storing descendant object files void SetSubFolderName(const string name) { this.m_folder_name=DIRECTORY+name; } string GetFolderName(void) const { return this.m_folder_name; } //--- Return the object name string GetName(void) const { return this.m_name; } //--- Update the object data to search for changes (Calling from the descendants: CBaseObj::Refresh()) virtual void Refresh(void); //--- Return an object type virtual int Type(void) const { return this.m_type; } //--- Return an object event description string EventDescription(const int property, const ENUM_BASE_EVENT_REASON reason, const int source, const string value, const string property_descr, const int digits); //--- コンストラクタ CBaseObj(); }; //+------------------------------------------------------------------+
ここで、上記で宣言されたすべてのメソッドを簡単に確認しましょう。
クラスコンストラクタ:
//+------------------------------------------------------------------+ //| コンストラクタ | //+------------------------------------------------------------------+ CBaseObj::CBaseObj() : m_global_error(ERR_SUCCESS), m_hash_sum(0),m_hash_sum_prev(0), m_is_event(false),m_event_code(WRONG_VALUE), m_chart_id(::ChartID()), m_folder_name(DIRECTORY), m_name(__FUNCTION__), m_long_prop_total(0), m_double_prop_total(0), m_first_start(true) { ::ArrayResize(this.m_long_prop_event,0,100); ::ArrayResize(this.m_double_prop_event,0,100); ::ArrayResize(this.m_long_prop_event_prev,0,100); ::ArrayResize(this.m_double_prop_event_prev,0,100); ::ZeroMemory(this.m_tick); this.m_digits_currency=(#ifdef __MQL5__ (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif); this.m_list_events.Clear(); this.m_list_events.Sort(); this.m_list_events_base.Clear(); this.m_list_events_base.Sort(); } //+------------------------------------------------------------------+
以前はゼロ値がイベントの不在を示したフラグから収集していたイベントコードがなくなったため、クラス初期化リストでイベントコードの初期化をゼロ以外のものに置き換える必要があります(ゼロは オブジェクトの整数プロパティの列挙の最初のプロパティを示し、正の値はオブジェクトプロパティリストの次のイベントを示しますが、親クラスでそれらの番号を定義することはできません)。イベントコードを-1に設定しましょう。
オブジェクト名はクラス名で初期化されます
(名前は子孫で再割り当てされます)。子孫オブジェクトの整数および実数プロパティの数をゼロ値で初期化し、最初の起動のフラグを設定します。
クラス本体で、整数と実数プロパティの配列のサイズをゼロ値に設定し、基本イベントのリストを消去し、並び替え済みリストフラグを設定します。
以前は、クラスのRefresh()仮想メソッドは単に宣言され、その実装は子孫クラスによって実行されていました。次に、基本オブジェクトクラスのメソッドを作成および実装して、子孫オブジェクトプロパティの変更を追跡しましょう。イベントが定義されると、基本イベントが作成され、その後の処理とプログラムに送信されるオブジェクトイベントの作成のために、基本イベントのリストに追加されます。
//+------------------------------------------------------------------+ //| Update the object data to search changes in them | //| Call from descendants: CBaseObj::Refresh() | //+------------------------------------------------------------------+ void CBaseObj::Refresh(void) { //--- Check the size of the arrays, Exit if it is zero if(!this.CheckControlDataArraySize() || !this.CheckControlDataArraySize(false)) return; //--- Reset the event flag and clear all lists this.m_is_event=false; this.m_list_events.Clear(); this.m_list_events.Sort(); this.m_list_events_base.Clear(); this.m_list_events_base.Sort(); //--- Fill in the array of integer properties and control their changes for(int i=0;i<this.m_long_prop_total;i++) if(!this.FillPropertySettings(i,this.m_long_prop_event,this.m_long_prop_event_prev,this.m_event_id)) continue; //--- Fill in the array of real properties and control their changes for(int i=0;i<this.m_double_prop_total;i++) if(!this.FillPropertySettings(i,this.m_double_prop_event,this.m_double_prop_event_prev,this.m_event_id)) continue; //--- 初回実行 if(this.m_first_start) { ::ArrayCopy(this.m_long_prop_event_prev,this.m_long_prop_event); ::ArrayCopy(this.m_double_prop_event_prev,this.m_double_prop_event); this.m_hash_sum_prev=this.m_hash_sum; this.m_first_start=false; this.m_is_event=false; this.m_list_events_base.Clear(); this.m_list_events_base.Sort(); return; } } //+------------------------------------------------------------------+
ここでは、イベントリストの事前消去や、整数および実数の子孫オブジェクトプロパティの配列への入力とその変更の確認のためのメソッドの呼び出しなど、メソッドで実行されるアクションを含む、すべてのアクションがコードコメントで説明されています。
これが最初の起動である場合、プロパティ配列の現在のステータスは前のステータスにコピーされ(違いがイベント登録につながるのを避けるため)、最初の起動フラグがリセットされ、FillPropertySettings()メソッドが呼び出された際に作成された可能性のある基本イベントのリストが消去されます。
子孫オブジェクトプロパティの配列に書き入れて、それらの変更を制御するメソッドを実装します。
//+------------------------------------------------------------------+ //| Fill in the object property array | //+------------------------------------------------------------------+ template<typename T> bool CBaseObj::FillPropertySettings(const int index,T &array[][CONTROLS_TOTAL],T &array_prev[][CONTROLS_TOTAL],int &event_id) { //--- Data in the array cells //--- [Property index][0] Controlled property increase value //--- [Property index][1] Controlled property decrease value //--- [Property index][2] Controlled property value level //--- [Property index][3] Property value //--- [Property index][4] Property value change //--- [Property index][5] Flag of a property change exceeding the increase value //--- [Property index][6] Flag of a property change exceeding the decrease value //--- [Property index][7] Flag of a property increase exceeding the control level //--- [Property index][8] Flag of a property decrease being less than the control level //--- [Property index][9] Flag of a property value being equal to the control level //--- If controlled values are not set, exit with 'false' if(this.m_first_start) return false; //--- Set the shift of the 'double' property index and the event ID event_id=index+(typename(T)=="double" ? this.m_long_prop_total : 0); //--- Reset all event flags for(int j=5;j<CONTROLS_TOTAL;j++) array[index][j]=false; //--- Property change value T value=array[index][3]-array_prev[index][3]; array[index][4]=value; //--- If the controlled property increase value is set if(array[index][0]<LONG_MAX) { //--- If the property change value exceeds the controlled increase value - there is an event, //--- add the event to the list, set the flag and save the new property value size if(value>0 && value>array[index][0]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_INC,value)) { array[index][5]=true; array_prev[index][4]=value; } } } //--- If the controlled property decrease value is set if(array[index][1]<LONG_MAX) { //--- If the property change value exceeds the controlled decrease value - there is an event, //--- add the event to the list, set the flag and save the new property value size if(value<0 && fabs(value)>array[index][1]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_DEC,value)) { array[index][6]=true; array_prev[index][4]=value; } } } //--- If the controlled level value is set if(array[index][2]<LONG_MAX) { value=array[index][3]-array[index][2]; //--- If a property value exceeds the control level, there is an event //--- add the event to the list and set the flag if(value>0 && array_prev[index][3]<=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_MORE_THEN,array[index][2])) array[index][7]=true; } //--- If a property value is less than the control level, there is an event, //--- add the event to the list and set the flag else if(value<0 && array_prev[index][3]>=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_LESS_THEN,array[index][2])) array[index][8]=true; } //--- If a property value is equal to the control level, there is an event, //--- add the event to the list and set the flag else if(value==0 && array_prev[index][3]!=array[index][2]) { if(this.EventBaseAdd(event_id,BASE_EVENT_REASON_EQUALS,array[index][2])) array[index][9]=true; } } //--- Save the current property value as a previous one array_prev[index][3]=array[index][3]; return true; } //+------------------------------------------------------------------+
ここでは、すべてのアクションがコードコメントで説明されています。私が明確にしたいのは、イベントIDを受信するためのオブジェクトの「double」プロパティインデックスシフトの選択だけです。すべてのオブジェクトの実数プロパティは整数プロパティの後に位置するため、最初の実数プロパティの先頭は整数プロパティの数に等しくなります(longプロパティの数が3に等しい場合、最初の実数プロパティのインデックスは3です) (0、1、2、 3)。配列では、カウントはゼロから始まります。したがって、「double」プロパティを使用する場合、オブジェクト整数プロパティの数を配列インデックスに追加する必要があります。
以下は、整数の配列と実数の子孫オブジェクトのプロパティのサイズを設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the size of the arrays of the object integer properties | //+------------------------------------------------------------------+ bool CBaseObj::SetControlDataArraySizeLong(const int size) { int x=(#ifdef __MQL4__ CONTROLS_TOTAL #else 1 #endif ); this.m_long_prop_total=::ArrayResize(this.m_long_prop_event,size,100)/x; return((::ArrayResize(this.m_long_prop_event_prev,size,100)/x)==size && this.m_long_prop_total==size ? true : false); } //+------------------------------------------------------------------+ //| Set the size of the arrays of the object real properties | //+------------------------------------------------------------------+ bool CBaseObj::SetControlDataArraySizeDouble(const int size) { int x=(#ifdef __MQL4__ CONTROLS_TOTAL #else 1 #endif ); this.m_double_prop_total=::ArrayResize(this.m_double_prop_event,size,100)/x; return((::ArrayResize(this.m_double_prop_event_prev,size,100)/x)==size && this.m_double_prop_total==size ? true : false); } //+------------------------------------------------------------------+
メソッドは、渡された値によって配列のサイズを変更して、結果を返します。
MQL4で多次元配列サイズを変更する1つの機能を強調する必要があります。MQL4のArrayResize()関数はすべての配列次元の合計サイズを返します。MQL5では、最初の次元のサイズを返しますが、これは変更される可能性があります。たとえば、2番目の次元のサイズが2の場合、最初の次元のサイズが10に変更されると、関数は20を返しますが、これは論理的ではありません(最初の次元のサイズのみを変更するため)。MQL5では、関数は正しい値を返します。上記の例では、期待どおり10を返します。
したがって、MQL4ではこのメソッドは、関数によって返される値を分割するべき区切りを備えています(2番目のサイズ)。
以下は、整数および実数の子孫オブジェクトプロパティの配列のサイズを確認するメソッドです。
//+------------------------------------------------------------------+ //| Check the array size of object properties | //+------------------------------------------------------------------+ bool CBaseObj::CheckControlDataArraySize(bool check_long=true) { string txt1=""; string txt2=""; string txt3=""; string txt4=""; bool res=true; if(check_long) { if(this.m_long_prop_total==0) { txt1=TextByLanguage("Массив данных контролируемых integer-свойств имеет нулевой размер","Controlled integer properties data array has zero size"); txt2=TextByLanguage("Необходимо сначала установить размер массива равным количеству integer-свойств объекта","You should first set size of array equal to number of object integer properties"); txt3=TextByLanguage("Для этого используйте метод CBaseObj::SetControlDataArraySizeLong()","To do this, use CBaseObj::SetControlDataArraySizeLong() method"); txt4=TextByLanguage("со значением количества integer-свойств объекта в параметре \"size\"","with value of number of integer properties of object in \"size\" parameter"); res=false; } } else { if(this.m_double_prop_total==0) { txt1=TextByLanguage("Массив данных контролируемых double-свойств имеет нулевой размер","Controlled double properties data array has zero size"); txt2=TextByLanguage("Необходимо сначала установить размер массива равным количеству double-свойств объекта","You should first set size of array equal to number of object double properties"); txt3=TextByLanguage("Для этого используйте метод CBaseObj::SetControlDataArraySizeDouble()","To do this, use CBaseObj::SetControlDataArraySizeDouble() method"); txt4=TextByLanguage("со значением количества double-свойств объекта в параметре \"size\"","with value of number of double properties of object in \"size\" parameter"); res=false; } } if(res) return true; #ifdef __MQL5__ ::Print(DFUN,"\n",txt1,"\n",txt2,"\n",txt3,"\n",txt4); #else ::Print(DFUN); ::Print(txt1); ::Print(txt2); ::Print(txt3); ::Print(txt4); #endif this.m_global_error=ERR_ZEROSIZE_ARRAY; return false; } //+------------------------------------------------------------------+
メソッドは、確認された配列のサイズを示すフラグを受け取ります。
trueの場合、longプロパティの配列が確認され、falseの場合、代わりに「double」プロパティの配列が確認されます。
確認された配列のサイズが設定されていない場合、メッセージテキストが生成され、メッセージが操作ログに表示され、falseが返されます。配列サイズがすでに設定されている場合、trueが返されます。
以下は、制御値をリセットしてオブジェクトプロパティの追跡データの値を変更するメソッドです。
//+------------------------------------------------------------------+ //| Reset the variables of controlled object data values | //+------------------------------------------------------------------+ void CBaseObj::ResetControlsParams(void) { if(!this.CheckControlDataArraySize(true) || !this.CheckControlDataArraySize(false)) return; //--- Data in the array cells //--- [Property index][0] Controlled property increase value //--- [Property index][1] Controlled property decrease value //--- [Property index][2] Controlled property value level for(int i=this.m_long_prop_total-1;i>WRONG_VALUE;i--) for(int j=0; j<3; j++) this.m_long_prop_event[i][j]=LONG_MAX; for(int i=this.m_double_prop_total-1;i>WRONG_VALUE;i--) for(int j=0; j<3; j++) this.m_double_prop_event[i][j]=(double)LONG_MAX; } //+------------------------------------------------------------------+ //| Reset the variables of tracked object data | //+------------------------------------------------------------------+ void CBaseObj::ResetChangesParams(void) { if(!this.CheckControlDataArraySize(true) || !this.CheckControlDataArraySize(false)) return; this.m_list_events.Clear(); this.m_list_events.Sort(); this.m_list_events_base.Clear(); this.m_list_events_base.Sort(); //--- Data in the array cells //--- [Property index][3] Property value //--- [Property index][4] Property value change //--- [Property index][5] Flag of a property change exceeding the increase value //--- [Property index][6] Flag of a property change exceeding the decrease value //--- [Property index][7] Flag of a property increase exceeding the control level //--- [Property index][8] Flag of a property decrease being less than the control level //--- [Property index][9] Flag of a property value being equal to the controlled value for(int i=this.m_long_prop_total-1;i>WRONG_VALUE;i--) for(int j=3; j<CONTROLS_TOTAL; j++) this.m_long_prop_event[i][j]=(j<5 ? LONG_MAX : 0); for(int i=this.m_double_prop_total-1;i>WRONG_VALUE;i--) for(int j=3; j<CONTROLS_TOTAL; j++) this.m_double_prop_event[i][j]=(j<5 ? (double)LONG_MAX : 0); } //+------------------------------------------------------------------+
初期化値は、子孫オブジェクトの整数と実数のプロパティの配列によって、2つのループ内のメソッドの配列の2番目の次元の必要なセルに設定されます。初期化されたセルは、コードコメントで設定されます。
以下は、オブジェクト基本イベントのリストに基本イベントを追加するメソッドです。
//+------------------------------------------------------------------+ //| Add the object base event to the list | //+------------------------------------------------------------------+ bool CBaseObj::EventBaseAdd(const int event_id,const ENUM_BASE_EVENT_REASON reason,const double value) { CBaseEvent* event=new CBaseEvent(event_id,reason,value); if(event==NULL) return false; this.m_list_events_base.Sort(); if(this.m_list_events_base.Search(event)>WRONG_VALUE) { delete event; return false; } return this.m_list_events_base.Add(event); } //+------------------------------------------------------------------+
メソッドは、イベントID、イベントの理由、子孫オブジェクトのプロパティ変更値を受け取ります。
次に、新しい基本イベントが作成され、同じイベントが基本イベントのリストに既に存在する場合は削除され、falseが返されます。イベントは追加されません。そうでない場合は、新しいイベントを基本オブジェクトイベントのリストに追加した結果が返されます。
以下は、基本オブジェクトイベントのリスト内のインデックスによって基本イベントを返すメソッドです。
//+------------------------------------------------------------------+ //| Return a base event by its index in the list | //+------------------------------------------------------------------+ CBaseEvent *CBaseObj::GetEventBase(const int index) { int total=this.m_list_events_base.Total(); if(total==0 || index<0 || index>total-1) return NULL; CBaseEvent *event=this.m_list_events_base.At(index); return(event!=NULL ? event : NULL); } //+------------------------------------------------------------------+
メソッドは必要なイベントのインデックスを受け取ります。リストのサイズがゼロの場合、またはインデックスが基本イベントリストを超える場合、NULLが返されます。それ以外の場合、インデックスからリストからイベントを受け取り、取得したオブジェクトへのポインタが返されます。
必要なプロパティの変更をすばやく設定するには、オブジェクト基本クラスのメソッドを作成する必要があります。変更を超えると、イベントが生成されます。また、子孫オブジェクトプロパティの新しい値を設定し、発生した「制御された」オブジェクトイベントに関するフラグを返すメソッドも必要です。基本クラスはその子孫のプロパティについて何も知らないので、必要な子孫オブジェクトのプロパティを変更できるようにするユニバーサルメソッドを作成する必要があります。各子孫クラスの整数および実数のプロパティを示すため、値を設定するプロパティを定義するのは簡単です。変更されたプロパティインデックスを確認するだけです。インデックスが整数プロパティの数よりも小さい場合、オブジェクトの整数プロパティに変更が加えられます。それ以外の場合、実際のプロパティに変更が加えられます。
以下は、子孫オブジェクト制御対象プロパティを設定するメソッドの実装です。
//+------------------------------------------------------------------+ //| Methods of setting controlled parameters | //+------------------------------------------------------------------+ //--- Data for storing, controlling and returning tracked properties: //--- [Property index][0] Controlled property increase value //--- [Property index][1] Controlled property decrease value //--- [Property index][2] Controlled property value level //--- [Property index][3] Property value //--- [Property index][4] Property value change //--- [Property index][5] Flag of a property change exceeding the increase value //--- [Property index][6] Flag of a property change exceeding the decrease value //--- [Property index][7] Flag of a property increase exceeding the control level //--- [Property index][8] Flag of a property decrease being less than the control level //--- [Property index][9] Flag of a property value being equal to the control level //+------------------------------------------------------------------+ //| Set the value of the controlled increase of object properties | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledValueINC(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][0]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][0]=(double)value; } //+------------------------------------------------------------------+ //| Set the value of the controlled decrease of object properties | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledValueDEC(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][1]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][1]=(double)value; } //+------------------------------------------------------------------+ //| Set the control level of object properties | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledValueLEVEL(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][2]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][2]=(double)value; } //+------------------------------------------------------------------+ //| Set the object property value | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledValue(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][3]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][3]=(double)value; } //+------------------------------------------------------------------+ //| Set the object property change value | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledChangedValue(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][4]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][4]=(double)value; } //+------------------------------------------------------------------+ //| Set the flag of the property value change | //| exceeding the increase value | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledFlagINC(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][5]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][5]=(double)value; } //+------------------------------------------------------------------+ //| Set the flag of the property value change | //| exceeding the decrease value | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledFlagDEC(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][6]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][6]=(double)value; } //+------------------------------------------------------------------+ //| Set the flag of the property value increase | //| exceeding the control level | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledFlagMORE(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][7]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][7]=(double)value; } //+------------------------------------------------------------------+ //| Set the flag of the property value decrease | //| being less than the control level | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledFlagLESS(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][8]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][8]=(double)value; } //+------------------------------------------------------------------+ //| Set the flag of the property value being equal to the | //| control level | //+------------------------------------------------------------------+ template<typename T> void CBaseObj::SetControlledFlagEQUAL(const int property,const T value) { if(property<this.m_long_prop_total) this.m_long_prop_event[property][9]=(long)value; else this.m_double_prop_event[property-this.m_long_prop_total][9]=(double)value; } //+------------------------------------------------------------------+
テンプレートT値を追加するプロパティを取得する最後のメソッドを見てみましょう。プロパティインデックスが子孫オブジェクトの整数プロパティの数より少ない場合、T値がオブジェクト整数プロパティの配列の必要なセルに追加されます。そうでない場合はプロパティが実数プロパティ配列に格納されるインデックスを計算します(プロパティの「double」インデックスは常にオブジェクトの整数プロパティの数だけ同じプロパティのインデックスを超えます)、オブジェクトの実数プロパティの配列の必要なセルにT値を追加します。各メソッドの配列の2番目の次元の必須セルは、メソッドリストの前にリストされています。
以下は、ushort値をlongコンテナへの後続のパッキングに必要なバイト数だけシフトしたlong値に変換するメソッドです。
//+------------------------------------------------------------------+ //| Convert a 'ushort' value to a specified 'long' number byte | //+------------------------------------------------------------------+ long CBaseObj::UshortToByte(const ushort value,const uchar index) const { if(index>3) { ::Print(DFUN,TextByLanguage("Ошибка. Значение \"index\" должно быть в пределах 0 - 3","Error. \"index\" value should be between 0 - 3")); return 0; } return(long)value<<(16*index); } //+------------------------------------------------------------------+
それぞれが2バイトのセルに分割された8バイトのlong値があると仮定します(その種類の各セルに一意のインデックスが割り当てられます)。
バイト6-7(インデックス3) |
バイト4-5(インデックス2) | バイト2-3(インデックス1) |
バイト0-1(インデックス0) |
---|---|---|---|
ushort 4 |
ushort 3 |
ushort 2 |
ushort 1 |
4つの'ushort'数を配置できます。後続の各番号は、16ビット*インデックス(1バイト= 8ビット)だけ左にシフトする必要があります。次に、取得した値がlong数に追加されます。したがって、longコンテナにいくつかのushort値がパックされます。
このメソッドは、ushort値とushort値がlongコンテナに格納されるインデックスを受け取ります。
インデックスが確認され、3を超える場合、「誤ったインデックス」メッセージが表示され、0が返されます。
インデックスが正しい場合、ushort値は左に16ビット*インデックスだけシフトされ(1バイトには8ビットが含まれ、
2バイトの ushort値をシフトする必要があります)、
シフト結果がメソッドから返されます。
以下は、必要なバイト数だけシフトされたushort値をlongコンテナにパックするメソッドです。
//+------------------------------------------------------------------+ //| Pack a 'ushort' number to a passed 'long' number | //+------------------------------------------------------------------+ long CBaseObj::UshortToLong(const ushort ushort_value,const uchar index,long &long_value) { if(index>3) { ::Print(DFUN,TextByLanguage("Ошибка. Значение \"index\" должно быть в пределах 0 - 3","Error. \"index\" value should be between 0 - 3")); return 0; } return(long_value |= UshortToByte(ushort_value,index)); } //+------------------------------------------------------------------+
メソッドは、リンクによってメソッドに渡されるlongコンテナにパックされるushort値とlongコンテナでのushort値のバイトが配置されるインデックスの値を受け取ります。
上記のメソッドと同様に、インデックスが確認されます。確認が成功した場合、UshortToByte()メソッドをメソッドを使用して必要なバイト数だけシフトされたushort値
が、ビット単位の「OR」を使用してlong数に追加されて、結果が呼び出しプログラムに返されます。
以下は、子孫オブジェクトのイベントの文字列の説明を返すメソッドです。
//+------------------------------------------------------------------+ //| Return an object event description | //+------------------------------------------------------------------+ string CBaseObj::EventDescription(const int property, const ENUM_BASE_EVENT_REASON reason, const int source, const string value, const string property_descr, const int digits) { //--- Depending on the collection ID, create th object type description string type= ( this.Type()==COLLECTION_SYMBOLS_ID ? TextByLanguage("символа: ","symbol property: ") : this.Type()==COLLECTION_ACCOUNT_ID ? TextByLanguage("аккаунта: ","account property: ") : "" ); //--- Depending on the property type, create the property change value description string level= ( property<this.m_long_prop_total ? ::DoubleToString(this.GetControlledValueLongLEVEL(property),digits) : ::DoubleToString(this.GetControlledValueDoubleLEVEL(property),digits) ); //--- Depending on the event reason, create the event description text string res= ( reason==BASE_EVENT_REASON_INC ? TextByLanguage("Значение свойства ","Value of the ")+type+property_descr+TextByLanguage(" увеличено на "," increased by ")+value : reason==BASE_EVENT_REASON_DEC ? TextByLanguage("Значение свойства ","Value of the ")+type+property_descr+TextByLanguage(" уменьшено на "," decreased by ")+value : reason==BASE_EVENT_REASON_MORE_THEN ? TextByLanguage("Значение свойства ","Value of the ")+type+property_descr+TextByLanguage(" стало больше "," became more than ")+level : reason==BASE_EVENT_REASON_LESS_THEN ? TextByLanguage("Значение свойства ","Value of the ")+type+property_descr+TextByLanguage(" стало меньше "," became less than ")+level : reason==BASE_EVENT_REASON_EQUALS ? TextByLanguage("Значение свойства ","Value of the ")+type+property_descr+TextByLanguage(" равно "," is equal to ")+level : TextByLanguage("Неизвестное событие ","Unknown ")+type ); //--- Return the object name+created event description text return this.m_name+": "+res; } //+------------------------------------------------------------------+
基本オブジェクトクラスは子孫について何も知らないため、子孫クラスのイベントを記述するために、イベントが発生した子孫オブジェクトを指定する必要があります。
これを達成するために、メソッドは以下を受け取ります。
- イベントが検出されたオブジェクトのプロパティ
- イベントの理由 — 指定された値によるプロパティ値の増加/減少/プロパティ値による指定されたレベルの交差
- イベントソース — イベントが発生したオブジェクトのコレクションのID
- オブジェクトのプロパティが変更された値
- 子孫オブジェクトプロパティのテキスト説明(子孫で利用可能)
- 変更されたプロパティの数値表現の小数点以下の桁数(子孫でも使用可能)
子孫オブジェクトを作成するすべての手順は、コードのコメントで説明されています。コメントは十分に包括的だと思います。
基本オブジェクトクラスで必要なすべての変更を行いました(ライブラリのさらなる開発および新しいコレクションの作成中に、正しいコレクションのIDを最後のメソッドに追加して、正しいイベントの説明を作成します)。
銘柄クラスと銘柄コレクションの改訂
ここでは、新しい基本オブジェクトイベントを念頭に置いて、銘柄クラスと銘柄コレクション操作を修正します。銘柄と銘柄コレクションクラスにいくつかの変更を加えましょう。
\MQL5\Include\DoEasy\Objects\Symbols\Symbol.mqhを開いて変更を追加します。
基本オブジェクトのすべての子孫オブジェクトイベントがクラスで定義されるようになったため、子孫クラスのオブジェクトプロパティの変更を制御する必要はありません。 したがって、追跡されるオブジェクトプロパティのデータ構造体は不要になります。
銘柄オブジェクトクラスから構造体と構造体型を持つ2つのオブジェクトを削除しましょう。
struct MqlDataSymbol
{
//--- Symbol integer properties
ENUM_SYMBOL_TRADE_MODE trade_mode; // SYMBOL_TRADE_MODE Order filling modes
long session_deals; // SYMBOL_SESSION_DEALS The number of deals in the current session
long session_buy_orders; // SYMBOL_SESSION_BUY_ORDERS The total number of current buy orders
long session_sell_orders; // SYMBOL_SESSION_SELL_ORDERS The total number of current sell orders
long volume; // SYMBOL_VOLUME Last deal volume
long volume_high_day; // SYMBOL_VOLUMEHIGH Maximum volume within a day
long volume_low_day; // SYMBOL_VOLUMELOW Minimum volume within a day
int spread; // SYMBOL_SPREAD Spread in points
int stops_level; // SYMBOL_TRADE_STOPS_LEVEL Minimum distance in points from the current close price for setting Stop orders
int freeze_level; // SYMBOL_TRADE_FREEZE_LEVEL Freeze distance for trading operations (in points)
//--- Symbol real properties
double bid_last; // SYMBOL_BID/SYMBOL_LAST Bid - the best sell offer/Last deal price
double bid_last_high; // SYMBOL_BIDHIGH/SYMBOL_LASTHIGH Maximum Bid within the day/Maximum Last per day
double bid_last_low; // SYMBOL_BIDLOW/SYMBOL_LASTLOW Minimum Bid within the day/Minimum Last per day
double ask; // SYMBOL_ASK Ask - nest buy offer
double ask_high; // SYMBOL_ASKHIGH Maximum Ask of the day
double ask_low; // SYMBOL_ASKLOW Minimum Ask of the day
double volume_real_day; // SYMBOL_VOLUME_REAL Real Volume of the day
double volume_high_real_day; // SYMBOL_VOLUMEHIGH_REAL Maximum real Volume of the day
double volume_low_real_day; // SYMBOL_VOLUMELOW_REAL Minimum real Volume of the day
double option_strike; // SYMBOL_OPTION_STRIKE Strike price
double volume_limit; // SYMBOL_VOLUME_LIMIT Maximum permissible total volume for a position and pending orders in one direction
double swap_long; // SYMBOL_SWAP_LONG Long swap value
double swap_short; // SYMBOL_SWAP_SHORT Short swap value
double session_volume; // SYMBOL_SESSION_VOLUME The total volume of deals in the current session
double session_turnover; // SYMBOL_SESSION_TURNOVER The total turnover in the current session
double session_interest; // SYMBOL_SESSION_INTEREST The total volume of open positions
double session_buy_ord_volume; // SYMBOL_SESSION_BUY_ORDERS_VOLUME The total volume of Buy orders at the moment
double session_sell_ord_volume; // SYMBOL_SESSION_SELL_ORDERS_VOLUME The total volume of Sell orders at the moment
double session_open; // SYMBOL_SESSION_OPEN Session open price
double session_close; // SYMBOL_SESSION_CLOSE Session close price
double session_aw; // SYMBOL_SESSION_AW The average weighted price of the session
};
MqlDataSymbol m_struct_curr_symbol; // Current symbol data
MqlDataSymbol m_struct_prev_symbol; // Previous symbol data
//---
制御および変更された銘柄オブジェクトプロパティを保存するためのすべてのクラスメンバ変数を削除します。このデータはすべて基本オブジェクトクラス配列に保存されます。
//--- Current session deals
long m_control_session_deals_inc; // Controlled value of the growth of the number of deals
long m_control_session_deals_dec; // Controlled value of the decrease in the number of deals
long m_changed_session_deals_value; // Value of change in the number of deals
bool m_is_change_session_deals_inc; // Flag of a change in the number of deals exceeding the growth value
bool m_is_change_session_deals_dec; // Flag of a change in the number of deals exceeding the decrease value
//--- Buy orders of the current session
long m_control_session_buy_ord_inc; // Controlled value of the increase of the number of Buy orders
long m_control_session_buy_ord_dec; // Controlled value of the decrease in the number of Buy orders
long m_changed_session_buy_ord_value; // Buy orders change value
bool m_is_change_session_buy_ord_inc; // Flag of a change in the number of Buy orders exceeding the increase value
bool m_is_change_session_buy_ord_dec; // Flag of a change in the number of Buy orders being less than the increase value
//--- Sell orders of the current session
long m_control_session_sell_ord_inc; // Controlled value of the increase of the number of Sell orders
long m_control_session_sell_ord_dec; // Controlled value of the decrease in the number of Sell orders
long m_changed_session_sell_ord_value; // Sell orders change value
bool m_is_change_session_sell_ord_inc; // Flag of a change in the number of Sell orders exceeding the increase value
bool m_is_change_session_sell_ord_dec; // Flag of a change in the number of Sell orders exceeding the decrease value
//--- Volume of the last deal
long m_control_volume_inc; // Controlled value of the volume increase in the last deal
long m_control_volume_dec; // Controlled value of the volume decrease in the last deal
long m_changed_volume_value; // Value of the volume change in the last deal
bool m_is_change_volume_inc; // Flag of the volume change in the last deal exceeding the increase value
bool m_is_change_volume_dec; // Flag of the volume change in the last deal being less than the increase value
//--- Maximum volume within a day
long m_control_volume_high_day_inc; // Controlled value of the maximum volume increase for a day
long m_control_volume_high_day_dec; // Controlled value of the maximum volume decrease for a day
long m_changed_volume_high_day_value; // Maximum volume change value within a day
bool m_is_change_volume_high_day_inc; // Flag of the maximum day volume exceeding the increase value
bool m_is_change_volume_high_day_dec; // Flag of the maximum day volume exceeding the decrease value
//--- Minimum volume within a day
long m_control_volume_low_day_inc; // Controlled value of the minimum volume increase for a day
long m_control_volume_low_day_dec; // Controlled value of the minimum volume decrease for a day
long m_changed_volume_low_day_value; // Minimum volume change value within a day
bool m_is_change_volume_low_day_inc; // Flag of the minimum day volume exceeding the increase value
bool m_is_change_volume_low_day_dec; // Flag of the minimum day volume exceeding the decrease value
//--- Spread
int m_control_spread_inc; // Controlled spread increase value in points
int m_control_spread_dec; // Controlled spread decrease value in points
int m_changed_spread_value; // Spread change value in points
bool m_is_change_spread_inc; // Flag of spread change in points exceeding the increase value
bool m_is_change_spread_dec; // Flag of spread change in points exceeding the decrease value
//--- StopLevel
int m_control_stops_level_inc; // Controlled StopLevel increase value in points
int m_control_stops_level_dec; // Controlled StopLevel decrease value in points
int m_changed_stops_level_value; // StopLevel change value in points
bool m_is_change_stops_level_inc; // Flag of StopLevel change in points exceeding the increase value
bool m_is_change_stops_level_dec; // Flag of StopLevel change in points exceeding the decrease value
//--- Freeze distance
int m_control_freeze_level_inc; // Controlled FreezeLevel increase value in points
int m_control_freeze_level_dec; // Controlled FreezeLevel decrease value in points
int m_changed_freeze_level_value; // FreezeLevel change value in points
bool m_is_change_freeze_level_inc; // Flag of FreezeLevel change in points exceeding the increase value
bool m_is_change_freeze_level_dec; // Flag of FreezeLevel change in points exceeding the decrease value
//--- Bid/Last
double m_control_bid_last_inc; // Controlled value of Bid or Last price increase
double m_control_bid_last_dec; // Controlled value of Bid or Last price decrease
double m_changed_bid_last_value; // Bid or Last price change value
bool m_is_change_bid_last_inc; // Flag of Bid or Last price change exceeding the increase value
bool m_is_change_bid_last_dec; // Flag of Bid or Last price change exceeding the decrease value
//--- Maximum Bid/Last of the day
double m_control_bid_last_high_inc; // Controlled increase value of the maximum Bid or Last price of the day
double m_control_bid_last_high_dec; // Controlled decrease value of the maximum Bid or Last price of the day
double m_changed_bid_last_high_value; // Maximum Bid or Last change value for the day
bool m_is_change_bid_last_high_inc; // Flag of the maximum Bid or Last price change for the day exceeding the increase value
bool m_is_change_bid_last_high_dec; // Flag of the maximum Bid or Last price change for the day exceeding the decrease value
//--- Minimum Bid/Last of the day
double m_control_bid_last_low_inc; // Controlled increase value of the minimum Bid or Last price of the day
double m_control_bid_last_low_dec; // Controlled decrease value of the minimum Bid or Last price of the day
double m_changed_bid_last_low_value; // Minimum Bid or Last change value for the day
bool m_is_change_bid_last_low_inc; // Flag of the minimum Bid or Last price change for the day exceeding the increase value
bool m_is_change_bid_last_low_dec; // Flag of the minimum Bid or Last price change for the day exceeding the decrease value
//--- Ask
double m_control_ask_inc; // Controlled value of the Ask price increase
double m_control_ask_dec; // Controlled value of the Ask price decrease
double m_changed_ask_value; // Ask price change value
bool m_is_change_ask_inc; // Flag of the Ask price change exceeding the increase value
bool m_is_change_ask_dec; // Flag of the Ask price change exceeding the decrease value
//--- Maximum Ask price for the day
double m_control_ask_high_inc; // Controlled increase value of the maximum Ask price of the day
double m_control_ask_high_dec; // Controlled decrease value of the maximum Ask price of the day
double m_changed_ask_high_value; // Maximum Ask price change value for the day
bool m_is_change_ask_high_inc; // Flag of the maximum Ask price change for the day exceeding the increase value
bool m_is_change_ask_high_dec; // Flag of the maximum Ask price change for the day exceeding the decrease value
//--- Minimum Ask price for the day
double m_control_ask_low_inc; // Controlled increase value of the minimum Ask price of the day
double m_control_ask_low_dec; // Controlled decrease value of the minimum Ask price of the day
double m_changed_ask_low_value; // Minimum Ask price change value for the day
bool m_is_change_ask_low_inc; // Flag of the minimum Ask price change for the day exceeding the increase value
bool m_is_change_ask_low_dec; // Flag of the minimum Ask price change for the day exceeding the decrease value
//--- Real Volume for the day
double m_control_volume_real_inc; // Controlled value of the real volume increase of the day
double m_control_volume_real_dec; // Controlled value of the real volume decrease of the day
double m_changed_volume_real_value; // Real volume change value of the day
bool m_is_change_volume_real_inc; // Flag of the real volume change for the day exceeding the increase value
bool m_is_change_volume_real_dec; // Flag of the real volume change for the day exceeding the decrease value
//--- Maximum real volume for the day
double m_control_volume_high_real_day_inc; // Controlled value of the maximum real volume increase of the day
double m_control_volume_high_real_day_dec; // Controlled value of the maximum real volume decrease of the day
double m_changed_volume_high_real_day_value; // Maximum real volume change value of the day
bool m_is_change_volume_high_real_day_inc; // Flag of the maximum real volume change for the day exceeding the increase value
bool m_is_change_volume_high_real_day_dec; // Flag of the maximum real volume change for the day exceeding the decrease value
//--- Minimum real volume for the day
double m_control_volume_low_real_day_inc; // Controlled value of the minimum real volume increase of the day
double m_control_volume_low_real_day_dec; // Controlled value of the minimum real volume decrease of the day
double m_changed_volume_low_real_day_value; // Minimum real volume change value of the day
bool m_is_change_volume_low_real_day_inc; // Flag of the minimum real volume change for the day exceeding the increase value
bool m_is_change_volume_low_real_day_dec; // Flag of the minimum real volume change for the day exceeding the decrease value
//--- Strike price
double m_control_option_strike_inc; // Controlled value of the strike price increase
double m_control_option_strike_dec; // Controlled value of the strike price decrease
double m_changed_option_strike_value; // Strike price change value
bool m_is_change_option_strike_inc; // Flag of the strike price change exceeding the increase value
bool m_is_change_option_strike_dec; // Flag of the strike price change exceeding the decrease value
//--- Total volume of positions and orders
double m_changed_volume_limit_value; // Minimum total volume change value
bool m_is_change_volume_limit_inc; // Flag of the minimum total volume increase
bool m_is_change_volume_limit_dec; // Flag of the minimum total volume decrease
//--- Swap long
double m_changed_swap_long_value; // Swap long change value
bool m_is_change_swap_long_inc; // Flag of the swap long increase
bool m_is_change_swap_long_dec; // Flag of the swap long decrease
//--- Swap short
double m_changed_swap_short_value; // Swap short change value
bool m_is_change_swap_short_inc; // Flag of the swap short increase
bool m_is_change_swap_short_dec; // Flag of the swap short decrease
//--- The total volume of deals in the current session
double m_control_session_volume_inc; // Controlled value of the total trade volume increase in the current session
double m_control_session_volume_dec; // Controlled value of the total trade volume decrease in the current session
double m_changed_session_volume_value; // The total deal volume change value in the current session
bool m_is_change_session_volume_inc; // Flag of total trade volume change in the current session exceeding the increase value
bool m_is_change_session_volume_dec; // Flag of total trade volume change in the current session exceeding the decrease value
//--- The total turnover in the current session
double m_control_session_turnover_inc; // Controlled value of the total turnover increase in the current session
double m_control_session_turnover_dec; // Controlled value of the total turnover decrease in the current session
double m_changed_session_turnover_value; // Total turnover change value in the current session
bool m_is_change_session_turnover_inc; // Flag of total turnover change in the current session exceeding the increase value
bool m_is_change_session_turnover_dec; // Flag of total turnover change in the current session exceeding the decrease value
//--- The total volume of open positions
double m_control_session_interest_inc; // Controlled value of the total open position volume increase in the current session
double m_control_session_interest_dec; // Controlled value of the total open position volume decrease in the current session
double m_changed_session_interest_value; // Change value of the open positions total volume in the current session
bool m_is_change_session_interest_inc; // Flag of total open positions' volume change in the current session exceeding the increase value
bool m_is_change_session_interest_dec; // Flag of total open positions' volume change in the current session exceeding the decrease value
//--- The total volume of Buy orders at the moment
double m_control_session_buy_ord_volume_inc; // Controlled value of the current total buy order volume increase
double m_control_session_buy_ord_volume_dec; // Controlled value of the current total buy order volume decrease
double m_changed_session_buy_ord_volume_value; // Change value of the current total buy order volume
bool m_is_change_session_buy_ord_volume_inc; // Flag of changing the current total buy orders volume exceeding the increase value
bool m_is_change_session_buy_ord_volume_dec; // Flag of changing the current total buy orders volume exceeding the decrease value
//--- The total volume of Sell orders at the moment
double m_control_session_sell_ord_volume_inc; // Controlled value of the current total sell order volume increase
double m_control_session_sell_ord_volume_dec; // Controlled value of the current total sell order volume decrease
double m_changed_session_sell_ord_volume_value; // Change value of the current total sell order volume
bool m_is_change_session_sell_ord_volume_inc; // Flag of changing the current total sell orders volume exceeding the increase value
bool m_is_change_session_sell_ord_volume_dec; // Flag of changing the current total sell orders volume exceeding the decrease value
//--- Session open price
double m_control_session_open_inc; // Controlled value of the session open price increase
double m_control_session_open_dec; // Controlled value of the session open price decrease
double m_changed_session_open_value; // Session open price change value
bool m_is_change_session_open_inc; // Flag of the session open price change exceeding the increase value
bool m_is_change_session_open_dec; // Flag of the session open price change exceeding the decrease value
//--- Session close price
double m_control_session_close_inc; // Controlled value of the session close price increase
double m_control_session_close_dec; // Controlled value of the session close price decrease
double m_changed_session_close_value; // Session close price change value
bool m_is_change_session_close_inc; // Flag of the session close price change exceeding the increase value
bool m_is_change_session_close_dec; // Flag of the session close price change exceeding the decrease value
//--- The average weighted session price
double m_control_session_aw_inc; // Controlled value of the average weighted session price increase
double m_control_session_aw_dec; // Controlled value of the average weighted session price decrease
double m_changed_session_aw_value; // The average weighted session price change value
bool m_is_change_session_aw_inc; // Flag of the average weighted session price change value exceeding the increase value
bool m_is_change_session_aw_dec; // Flag of the average weighted session price change value exceeding the decrease value
強調表示されたメソッドは冗長なので削除します。
//--- Initialize the variables of (1) tracked, (2) controlled symbol data virtual void InitChangesParams(void); virtual void InitControlsParams(void); //--- Check symbol changes, return a change code virtual int SetEventCode(void); //--- Set an event type and fill in the event list virtual void SetTypeEvent(void); //--- Return description of symbol events string EventDescription(const ENUM_SYMBOL_EVENT event);
銘柄プロパティを変更するためのコードを配置する仮想メソッドの代わりに、銘柄プロパティの変更を確認してイベントを作成するメソッドを宣言します。
//--- Initialize the variables of controlled symbol data virtual void InitControlsParams(void); //--- Check the list of symbol property changes and create an event void CheckEvents(void);
クラスのpublicセクションで、追跡値を設定し、追跡プロパティの制御値、プロパティ変更値、フラグを返すメソッドの宣言を追加します。
public: //--- Set the change value of the controlled symbol property template<typename T> void SetControlChangedValue(const int property,const T value); //--- Set the value of the controlled symbol property (1) increase, (2) decrease and (3) control level template<typename T> void SetControlPropertyINC(const int property,const T value); template<typename T> void SetControlPropertyDEC(const int property,const T value); template<typename T> void SetControlPropertyLEVEL(const int property,const T value); //--- Set the flag of a symbol property change exceeding the (1) increase and (2) decrease values template<typename T> void SetControlFlagINC(const int property,const T value); template<typename T> void SetControlFlagDEC(const int property,const T value); //--- Return the set value of the (1) integer and (2) real symbol property controlled increase long GetControlParameterINC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledValueLongINC(property); } double GetControlParameterINC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledValueDoubleINC(property); } //--- Return the set value of the (1) integer and (2) real symbol property controlled decrease long GetControlParameterDEC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledValueLongDEC(property); } double GetControlParameterDEC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledValueDoubleDEC(property); } //--- Return the flag of an (1) integer and (2) real symbol property value change exceeding the increase value long GetControlFlagINC(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledFlagLongINC(property); } double GetControlFlagINC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledFlagDoubleINC(property); } //--- Return the flag of an (1) integer and (2) real symbol property value change exceeding the decrease value bool GetControlFlagDEC(const ENUM_SYMBOL_PROP_INTEGER property) const { return (bool)this.GetControlledFlagLongDEC(property); } bool GetControlFlagDEC(const ENUM_SYMBOL_PROP_DOUBLE property) const { return (bool)this.GetControlledFlagDoubleDEC(property); } //--- Return the change value of the controlled (1) integer and (2) real object property long GetControlChangedValue(const ENUM_SYMBOL_PROP_INTEGER property) const { return this.GetControlledChangedValueLong(property); } double GetControlChangedValue(const ENUM_SYMBOL_PROP_DOUBLE property) const { return this.GetControlledChangedValueDouble(property); } //+------------------------------------------------------------------+
各メソッドは、設定/確認された銘柄オブジェクトプロパティの型に対応する基本オブジェクトのメソッドを呼び出すオーバーロードされた2つのメソッドの形式で作成されます。
いくつかの銘柄オブジェクトプロパティへの単純化されたアクセスのメソッドはすでに開発しました。そこにプロパティの制御レベルの値を配置するメソッドとBid/Lastおよび関連パラメータのデータを設定/受信するメソッドを追加します(以前は、Bid/Lastはチャー後の基になっている価格に応じて自動的に選択されました)。次に、このデータを操作するためのメソッドを作成する必要があります)。
//+------------------------------------------------------------------+ //| Get and set the parameters of tracked property changes | //+------------------------------------------------------------------+ //--- Execution //--- Flag of changing the trading mode for a symbol bool IsChangedTradeMode(void) const { return this.m_is_change_trade_mode; } //--- Current session deals //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the number of deals during the current session //--- getting (3) the number of deals change value during the current session, //--- getting the flag of the number of deals change during the current session exceeding the (4) increase, (5) decrease value void SetControlSessionDealsInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } void SetControlSessionDealsDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } void SetControlSessionDealsLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_DEALS,(long)::fabs(value)); } long GetValueChangedSessionDeals(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_DEALS); } bool IsIncreasedSessionDeals(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_DEALS); } bool IsDecreasedSessionDeals(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_DEALS); } //--- Buy orders of the current session //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the current number of Buy orders //--- getting (4) the current number of Buy orders change value, //--- getting the flag of the current Buy orders' number change exceeding the (5) growth, (6) decrease value void SetControlSessionBuyOrdInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } void SetControlSessionBuyOrdDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } void SetControlSessionBuyOrdLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS,(long)::fabs(value)); } long GetValueChangedSessionBuyOrders(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS); } bool IsIncreasedSessionBuyOrders(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS); } bool IsDecreasedSessionBuyOrders(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS); } //--- Sell orders of the current session //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the current number of Sell orders //--- getting (4) the current number of Sell orders change value, //--- getting the flag of the current Sell orders' number change exceeding the (5) growth, (6) decrease value void SetControlSessionSellOrdInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value)); } void SetControlSessionSellOrdDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value)); } void SetControlSessionSellOrdLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS,(long)::fabs(value));} long GetValueChangedSessionSellOrders(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS); } bool IsIncreasedSessionSellOrders(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS); } bool IsDecreasedSessionSellOrders(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS); } //--- Volume of the last deal //--- setting the last deal volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) volume change values in the last deal, //--- getting the flag of the volume change in the last deal exceeding the (5) growth, (6) decrease value void SetControlVolumeInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } void SetControlVolumeDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } void SetControlVolumeLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUME,(long)::fabs(value)); } long GetValueChangedVolume(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUME); } bool IsIncreasedVolume(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUME); } bool IsDecreasedVolume(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUME); } //--- Maximum volume within a day //--- setting the maximum day volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the maximum volume change value within a day, //--- getting the flag of the maximum day volume change exceeding the (5) growth, (6) decrease value void SetControlVolumeHighInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } void SetControlVolumeHighDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } void SetControlVolumeHighLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUMEHIGH,(long)::fabs(value)); } long GetValueChangedVolumeHigh(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUMEHIGH); } bool IsIncreasedVolumeHigh(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUMEHIGH); } bool IsDecreasedVolumeHigh(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUMEHIGH); } //--- Minimum volume within a day //--- setting the minimum day volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the minimum volume change value within a day, //--- getting the flag of the minimum day volume change exceeding the (5) growth, (6) decrease value void SetControlVolumeLowInc(const long value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } void SetControlVolumeLowDec(const long value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } void SetControlVolumeLowLevel(const long value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUMELOW,(long)::fabs(value)); } long GetValueChangedVolumeLow(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUMELOW); } bool IsIncreasedVolumeLow(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUMELOW); } bool IsDecreasedVolumeLow(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUMELOW); } //--- Spread //--- setting the controlled spread (1) increase, (2) decrease value and (3) control level in points //--- getting (4) spread change value in points, //--- getting the flag of the spread change in points exceeding the (5) growth, (6) decrease value void SetControlSpreadInc(const int value) { this.SetControlPropertyINC(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } void SetControlSpreadDec(const int value) { this.SetControlPropertyDEC(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } void SetControlSpreadLevel(const int value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SPREAD,(long)::fabs(value)); } int GetValueChangedSpread(void) const { return (int)this.GetControlChangedValue(SYMBOL_PROP_SPREAD); } bool IsIncreasedSpread(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SPREAD); } bool IsDecreasedSpread(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SPREAD); } //--- StopLevel //--- setting the controlled StopLevel (1) increase, (2) decrease value and (3) control level in points //--- getting (4) StopLevel change value in points, //--- getting the flag of StopLevel change in points exceeding the (5) growth, (6) decrease value void SetControlStopLevelInc(const int value) { this.SetControlPropertyINC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } void SetControlStopLevelDec(const int value) { this.SetControlPropertyDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } void SetControlStopLevelLevel(const int value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_TRADE_STOPS_LEVEL,(long)::fabs(value)); } int GetValueChangedStopLevel(void) const { return (int)this.GetControlChangedValue(SYMBOL_PROP_TRADE_STOPS_LEVEL); } bool IsIncreasedStopLevel(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_TRADE_STOPS_LEVEL); } bool IsDecreasedStopLevel(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_TRADE_STOPS_LEVEL); } //--- Freeze distance //--- setting the controlled FreezeLevel (1) increase, (2) decrease value and (3) control level in points //--- getting (4) FreezeLevel change value in points, //--- getting the flag of FreezeLevel change in points exceeding the (5) growth, (6) decrease value void SetControlFreezeLevelInc(const int value) { this.SetControlPropertyINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } void SetControlFreezeLevelDec(const int value) { this.SetControlPropertyDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } void SetControlFreezeLevelLevel(const int value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_TRADE_FREEZE_LEVEL,(long)::fabs(value)); } int GetValueChangedFreezeLevel(void) const { return (int)this.GetControlChangedValue(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } bool IsIncreasedFreezeLevel(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } bool IsDecreasedFreezeLevel(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_TRADE_FREEZE_LEVEL); } //--- Bid //--- setting the controlled Bid price (1) increase, (2) decrease value and (3) control level in points //--- getting (4) Bid or Last price change value, //--- getting the flag of the Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_BID,::fabs(value)); } void SetControlBidDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_BID,::fabs(value)); } void SetControlBidLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_BID,::fabs(value)); } double GetValueChangedBid(void) const { return this.GetControlChangedValue(SYMBOL_PROP_BID); } bool IsIncreasedBid(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_BID); } bool IsDecreasedBid(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_BID); } //--- The highest Bid price of the day //--- setting the controlled maximum Bid price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) maximum Bid or Last price change value, //--- getting the flag of the maximum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidHighInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_BIDHIGH,::fabs(value)); } void SetControlBidHighDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_BIDHIGH,::fabs(value)); } void SetControlBidHighLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_BIDHIGH,::fabs(value)); } double GetValueChangedBidHigh(void) const { return this.GetControlChangedValue(SYMBOL_PROP_BIDHIGH); } bool IsIncreasedBidHigh(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_BIDHIGH); } bool IsDecreasedBidHigh(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_BIDHIGH); } //--- The lowest Bid price of the day //--- setting the controlled minimum Bid price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) minimum Bid or Last price change value, //--- getting the flag of the minimum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidLowInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_BIDLOW,::fabs(value)); } void SetControlBidLowDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_BIDLOW,::fabs(value)); } void SetControlBidLowLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_BIDLOW,::fabs(value)); } double GetValueChangedBidLow(void) const { return this.GetControlChangedValue(SYMBOL_PROP_BIDLOW); } bool IsIncreasedBidLow(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_BIDLOW); } bool IsDecreasedBidLow(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_BIDLOW); } //--- Last //--- setting the controlled Last price (1) increase, (2) decrease value and (3) control level in points //--- getting (4) Bid or Last price change value, //--- getting the flag of the Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlLastInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_LAST,::fabs(value)); } void SetControlLastDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_LAST,::fabs(value)); } void SetControlLastLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_LAST,::fabs(value)); } double GetValueChangedLast(void) const { return this.GetControlChangedValue(SYMBOL_PROP_LAST); } bool IsIncreasedLast(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_LAST); } bool IsDecreasedLast(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_LAST); } //--- The highest Last price of the day //--- setting the controlled maximum Last price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) maximum Bid or Last price change value, //--- getting the flag of the maximum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlLastHighInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_LASTHIGH,::fabs(value)); } void SetControlLastHighDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_LASTHIGH,::fabs(value)); } void SetControlLastHighLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_LASTHIGH,::fabs(value)); } double GetValueChangedLastHigh(void) const { return this.GetControlChangedValue(SYMBOL_PROP_LASTHIGH); } bool IsIncreasedLastHigh(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_LASTHIGH); } bool IsDecreasedLastHigh(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_LASTHIGH); } //--- The lowest Last price of the day //--- setting the controlled minimum Last price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) minimum Bid or Last price change value, //--- getting the flag of the minimum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlLastLowInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_LASTLOW,::fabs(value)); } void SetControlLastLowDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_LASTLOW,::fabs(value)); } void SetControlLastLowLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_LASTLOW,::fabs(value)); } double GetValueChangedLastLow(void) const { return this.GetControlChangedValue(SYMBOL_PROP_LASTLOW); } bool IsIncreasedLastLow(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_LASTLOW); } bool IsDecreasedLastLow(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_LASTLOW); } //--- Bid/Last //--- setting the controlled Bid or Last price (1) increase, (2) decrease value and (3) control level in points //--- getting (4) Bid or Last price change value, //--- getting the flag of the Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidLastInc(const double value); void SetControlBidLastDec(const double value); void SetControlBidLastLevel(const double value); double GetValueChangedBidLast(void) const; bool IsIncreasedBidLast(void) const; bool IsDecreasedBidLast(void) const; //--- Maximum Bid/Last of the day //--- setting the controlled maximum Bid or Last price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) maximum Bid or Last price change value, //--- getting the flag of the maximum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidLastHighInc(const double value); void SetControlBidLastHighDec(const double value); void SetControlBidLastHighLevel(const double value); double GetValueChangedBidLastHigh(void) const; bool IsIncreasedBidLastHigh(void) const; bool IsDecreasedBidLastHigh(void) const; //--- Minimum Bid/Last of the day //--- setting the controlled minimum Bid or Last price (1) increase, (2) decrease value and (3) control level in points //--- getting the (4) minimum Bid or Last price change value, //--- getting the flag of the minimum Bid or Last price change exceeding the (5) growth, (6) decrease value void SetControlBidLastLowInc(const double value); void SetControlBidLastLowDec(const double value); void SetControlBidLastLowLevev(const double value); double GetValueChangedBidLastLow(void) const; bool IsIncreasedBidLastLow(void) const; bool IsDecreasedBidLastLow(void) const; //--- Ask //--- setting the controlled Ask price (1) increase, (2) decrease value and (3) control level in points //--- getting (4) Ask price change value, //--- getting the flag of the Ask price change exceeding the (5) growth, (6) decrease value void SetControlAskInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_ASK,::fabs(value)); } void SetControlAskDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_ASK,::fabs(value)); } void SetControlAskLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_ASK,::fabs(value)); } double GetValueChangedAsk(void) const { return this.GetControlChangedValue(SYMBOL_PROP_ASK); } bool IsIncreasedAsk(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_ASK); } bool IsDecreasedAsk(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_ASK); } //--- Maximum Ask price for the day //--- setting the maximum day Ask controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the maximum Ask change value within a day, //--- getting the flag of the maximum day Ask change exceeding the (5) growth, (6) decrease value void SetControlAskHighInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_ASKHIGH,::fabs(value)); } void SetControlAskHighDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_ASKHIGH,::fabs(value)); } void SetControlAskHighLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_ASKHIGH,::fabs(value)); } double GetValueChangedAskHigh(void) const { return this.GetControlChangedValue(SYMBOL_PROP_ASKHIGH); } bool IsIncreasedAskHigh(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_ASKHIGH); } bool IsDecreasedAskHigh(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_ASKHIGH); } //--- Minimum Ask price for the day //--- setting the minimum day Ask controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the minimum Ask change value within a day, //--- getting the flag of the minimum day Ask change exceeding the (5) growth, (6) decrease value void SetControlAskLowInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_ASKLOW,::fabs(value)); } void SetControlAskLowDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_ASKLOW,::fabs(value)); } void SetControlAskLowLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_ASKLOW,::fabs(value)); } double GetValueChangedAskLow(void) const { return this.GetControlChangedValue(SYMBOL_PROP_ASKLOW); } bool IsIncreasedAskLow(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_ASKLOW); } bool IsDecreasedAskLow(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_ASKLOW); } //--- Real Volume for the day //--- setting the real day volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the change value of the real day volume, //--- getting the flag of the real day volume change exceeding the (5) growth, (6) decrease value void SetControlVolumeRealInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } void SetControlVolumeRealDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } void SetControlVolumeRealLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUME_REAL,::fabs(value)); } double GetValueChangedVolumeReal(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUME_REAL); } bool IsIncreasedVolumeReal(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUME_REAL); } bool IsDecreasedVolumeReal(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUME_REAL); } //--- Maximum real volume for the day //--- setting the maximum real day volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the change value of the maximum real day volume, //--- getting the flag of the maximum real day volume change exceeding the (5) growth, (6) decrease value void SetControlVolumeHighRealInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } void SetControlVolumeHighRealDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } void SetControlVolumeHighRealLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUMEHIGH_REAL,::fabs(value)); } double GetValueChangedVolumeHighReal(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUMEHIGH_REAL); } bool IsIncreasedVolumeHighReal(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUMEHIGH_REAL); } bool IsDecreasedVolumeHighReal(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUMEHIGH_REAL); } //--- Minimum real volume for the day //--- setting the minimum real day volume controlled (1) increase, (2) decrease and (3) control level //--- getting (4) the change value of the minimum real day volume, //--- getting the flag of the minimum real day volume change exceeding the (5) growth, (6) decrease value void SetControlVolumeLowRealInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } void SetControlVolumeLowRealDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } void SetControlVolumeLowRealLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUMELOW_REAL,::fabs(value)); } double GetValueChangedVolumeLowReal(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUMELOW_REAL); } bool IsIncreasedVolumeLowReal(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUMELOW_REAL); } bool IsDecreasedVolumeLowReal(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUMELOW_REAL); } //--- Strike price //--- setting the controlled strike price (1) increase, (2) decrease value and (3) control level in points //--- getting (4) the change value of the strike price, //--- getting the flag of the strike price change exceeding the (5) growth, (6) decrease value void SetControlOptionStrikeInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } void SetControlOptionStrikeDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } void SetControlOptionStrikeLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_OPTION_STRIKE,::fabs(value)); } double GetValueChangedOptionStrike(void) const { return this.GetControlChangedValue(SYMBOL_PROP_OPTION_STRIKE); } bool IsIncreasedOptionStrike(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_OPTION_STRIKE); } bool IsDecreasedOptionStrike(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_OPTION_STRIKE); } //--- Maximum allowed total volume of unidirectional positions and orders //--- (1) Setting the control level //--- (2) getting the change value of the maximum allowed total volume of unidirectional positions and orders, //--- getting the flag of (3) increasing, (4) decreasing the maximum allowed total volume of unidirectional positions and orders void SetControlVolumeLimitLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_VOLUME_LIMIT,::fabs(value)); } double GetValueChangedVolumeLimit(void) const { return this.GetControlChangedValue(SYMBOL_PROP_VOLUME_LIMIT); } bool IsIncreasedVolumeLimit(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_VOLUME_LIMIT); } bool IsDecreasedVolumeLimit(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_VOLUME_LIMIT); } //--- Swap long //--- (1) Setting the control level //--- (2) getting the swap long change value, //--- getting the flag of (3) increasing, (4) decreasing the swap long void SetControlSwapLongLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SWAP_LONG,::fabs(value)); } double GetValueChangedSwapLong(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SWAP_LONG); } bool IsIncreasedSwapLong(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SWAP_LONG); } bool IsDecreasedSwapLong(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SWAP_LONG); } //--- Swap short //--- (1) Setting the control level //--- (2) getting the swap short change value, //--- getting the flag of (3) increasing, (4) decreasing the swap short void SetControlSwapShortLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SWAP_SHORT,::fabs(value)); } double GetValueChangedSwapShort(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SWAP_SHORT); } bool IsIncreasedSwapShort(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SWAP_SHORT); } bool IsDecreasedSwapShort(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SWAP_SHORT); } //--- The total volume of deals in the current session //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the total volume of deals during the current session //--- getting (4) the total deal volume change value in the current session, //--- getting the flag of the total deal volume change during the current session exceeding the (5) growth, (6) decrease value void SetControlSessionVolumeInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } void SetControlSessionVolumeDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } void SetControlSessionVolumeLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_VOLUME,::fabs(value)); } double GetValueChangedSessionVolume(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_VOLUME); } bool IsIncreasedSessionVolume(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_VOLUME); } bool IsDecreasedSessionVolume(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_VOLUME); } //--- The total turnover in the current session //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the total turnover during the current session //--- getting (4) the total turnover change value in the current session, //--- getting the flag of the total turnover change during the current session exceeding the (5) growth, (6) decrease value void SetControlSessionTurnoverInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } void SetControlSessionTurnoverDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } void SetControlSessionTurnoverLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_TURNOVER,::fabs(value)); } double GetValueChangedSessionTurnover(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_TURNOVER); } bool IsIncreasedSessionTurnover(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_TURNOVER); } bool IsDecreasedSessionTurnover(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_TURNOVER); } //--- The total volume of open positions //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the total volume of open positions during the current session //--- getting (4) the change value of the open positions total volume in the current session, //--- getting the flag of the open positions total volume change during the current session exceeding the (5) growth, (6) decrease value void SetControlSessionInterestInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } void SetControlSessionInterestDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } void SetControlSessionInterestLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_INTEREST,::fabs(value)); } double GetValueChangedSessionInterest(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_INTEREST); } bool IsIncreasedSessionInterest(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_INTEREST); } bool IsDecreasedSessionInterest(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_INTEREST); } //--- The total volume of Buy orders at the moment //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the current total buy order volume //--- getting (4) the change value of the current total buy order volume, //--- getting the flag of the current total buy orders' volume change exceeding the (5) growth, (6) decrease value void SetControlSessionBuyOrdVolumeInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionBuyOrdVolumeDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionBuyOrdVolumeLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME,::fabs(value));} double GetValueChangedSessionBuyOrdVolume(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } bool IsIncreasedSessionBuyOrdVolume(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } bool IsDecreasedSessionBuyOrdVolume(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME); } //--- The total volume of Sell orders at the moment //--- setting the controlled value of (1) growth, (2) decrease and (3) control level of the current total sell order volume //--- getting (4) the change value of the current total sell order volume, //--- getting the flag of the current total sell orders' volume change exceeding the (5) growth, (6) decrease value void SetControlSessionSellOrdVolumeInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionSellOrdVolumeDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value)); } void SetControlSessionSellOrdVolumeLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME,::fabs(value));} double GetValueChangedSessionSellOrdVolume(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } bool IsIncreasedSessionSellOrdVolume(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } bool IsDecreasedSessionSellOrdVolume(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME); } //--- Session open price //--- setting the controlled session open price (1) increase, (2) decrease and (3) control value //--- getting (4) the change value of the session open price, //--- getting the flag of the session open price change exceeding the (5) growth, (6) decrease value void SetControlSessionPriceOpenInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } void SetControlSessionPriceOpenDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } void SetControlSessionPriceOpenLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_OPEN,::fabs(value)); } double GetValueChangedSessionPriceOpen(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_OPEN); } bool IsIncreasedSessionPriceOpen(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_OPEN); } bool IsDecreasedSessionPriceOpen(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_OPEN); } //--- Session close price //--- setting the controlled session close price (1) increase, (2) decrease and (3) control value //--- getting (4) the change value of the session close price, //--- getting the flag of the session close price change exceeding the (5) growth, (6) decrease value void SetControlSessionPriceCloseInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } void SetControlSessionPriceCloseDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } void SetControlSessionPriceCloseLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_CLOSE,::fabs(value)); } double GetValueChangedSessionPriceClose(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_CLOSE); } bool IsIncreasedSessionPriceClose(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_CLOSE); } bool IsDecreasedSessionPriceClose(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_CLOSE); } //--- The average weighted session price //--- setting the controlled session average weighted price (1) increase, (2) decrease and (3) control value //--- getting (4) the change value of the average weighted session price, //--- getting the flag of the average weighted session price change exceeding the (5) growth, (6) decrease value void SetControlSessionPriceAWInc(const double value) { this.SetControlPropertyINC(SYMBOL_PROP_SESSION_AW,::fabs(value)); } void SetControlSessionPriceAWDec(const double value) { this.SetControlPropertyDEC(SYMBOL_PROP_SESSION_AW,::fabs(value)); } void SetControlSessionPriceAWLevel(const double value) { this.SetControlPropertyLEVEL(SYMBOL_PROP_SESSION_AW,::fabs(value)); } double GetValueChangedSessionPriceAW(void) const { return this.GetControlChangedValue(SYMBOL_PROP_SESSION_AW); } bool IsIncreasedSessionPriceAW(void) const { return (bool)this.GetControlFlagINC(SYMBOL_PROP_SESSION_AW); } bool IsDecreasedSessionPriceAW(void) const { return (bool)this.GetControlFlagDEC(SYMBOL_PROP_SESSION_AW); } //---
宣言されたメソッドの実装と既存のメソッドの変更について考えてみましょう。
クラスコンストラクタにいくつかの小さな変更を加えます。
//+------------------------------------------------------------------+ //| Closedパラメトリックコンストラクタ | //+------------------------------------------------------------------+ CSymbol::CSymbol(ENUM_SYMBOL_STATUS symbol_status,const string name,const int index) { this.m_name=name; this.m_type=COLLECTION_SYMBOLS_ID; if(!this.Exist()) { ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\"",": ",TextByLanguage("Ошибка. Такого символа нет на сервере","Error. No such symbol on the server")); this.m_global_error=ERR_MARKET_UNKNOWN_SYMBOL; } bool select=::SymbolInfoInteger(this.m_name,SYMBOL_SELECT); ::ResetLastError(); if(!select) { if(!this.SetToMarketWatch()) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось поместить в обзор рынка. Ошибка: ","Failed to put in market watch. Error: "),this.m_global_error); } } ::ResetLastError(); if(!::SymbolInfoTick(this.m_name,this.m_tick)) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,"\"",this.m_name,"\": ",TextByLanguage("Не удалось получить текущие цены. Ошибка: ","Could not get current prices. Error: "),this.m_global_error); } //--- Initialize control data this.SetControlDataArraySizeLong(SYMBOL_PROP_INTEGER_TOTAL); this.SetControlDataArraySizeDouble(SYMBOL_PROP_DOUBLE_TOTAL); this.ResetChangesParams(); this.ResetControlsParams(); //--- Initialize symbol data this.Reset(); this.InitMarginRates(); #ifdef __MQL5__ ::ResetLastError(); if(!this.MarginRates()) { this.m_global_error=::GetLastError(); ::Print(DFUN_ERR_LINE,this.Name(),": ",TextByLanguage("Не удалось получить коэффициенты взимания маржи. Ошибка: ","Failed to get margin rates. Error: "),this.m_global_error); return; } #endif //--- 整数型プロパティを保存する this.m_long_prop[SYMBOL_PROP_STATUS] = symbol_status; this.m_long_prop[SYMBOL_PROP_INDEX_MW] = index; this.m_long_prop[SYMBOL_PROP_VOLUME] = (long)this.m_tick.volume; this.m_long_prop[SYMBOL_PROP_SELECT] = ::SymbolInfoInteger(this.m_name,SYMBOL_SELECT); this.m_long_prop[SYMBOL_PROP_VISIBLE] = ::SymbolInfoInteger(this.m_name,SYMBOL_VISIBLE); this.m_long_prop[SYMBOL_PROP_SESSION_DEALS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_DEALS); this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_BUY_ORDERS); this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_SELL_ORDERS); this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMEHIGH); this.m_long_prop[SYMBOL_PROP_VOLUMELOW] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMELOW); this.m_long_prop[SYMBOL_PROP_DIGITS] = ::SymbolInfoInteger(this.m_name,SYMBOL_DIGITS); this.m_long_prop[SYMBOL_PROP_SPREAD] = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD); this.m_long_prop[SYMBOL_PROP_SPREAD_FLOAT] = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD_FLOAT); this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH] = ::SymbolInfoInteger(this.m_name,SYMBOL_TICKS_BOOKDEPTH); this.m_long_prop[SYMBOL_PROP_TRADE_MODE] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_MODE); this.m_long_prop[SYMBOL_PROP_START_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_START_TIME); this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_EXPIRATION_TIME); this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_STOPS_LEVEL); this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_FREEZE_LEVEL); this.m_long_prop[SYMBOL_PROP_TRADE_EXEMODE] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_EXEMODE); this.m_long_prop[SYMBOL_PROP_SWAP_ROLLOVER3DAYS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SWAP_ROLLOVER3DAYS); this.m_long_prop[SYMBOL_PROP_TIME] = this.TickTime(); this.m_long_prop[SYMBOL_PROP_EXIST] = this.SymbolExists(); this.m_long_prop[SYMBOL_PROP_CUSTOM] = this.SymbolCustom(); this.m_long_prop[SYMBOL_PROP_MARGIN_HEDGED_USE_LEG] = this.SymbolMarginHedgedUseLEG(); this.m_long_prop[SYMBOL_PROP_ORDER_MODE] = this.SymbolOrderMode(); this.m_long_prop[SYMBOL_PROP_FILLING_MODE] = this.SymbolOrderFillingMode(); this.m_long_prop[SYMBOL_PROP_EXPIRATION_MODE] = this.SymbolExpirationMode(); this.m_long_prop[SYMBOL_PROP_ORDER_GTC_MODE] = this.SymbolOrderGTCMode(); this.m_long_prop[SYMBOL_PROP_OPTION_MODE] = this.SymbolOptionMode(); this.m_long_prop[SYMBOL_PROP_OPTION_RIGHT] = this.SymbolOptionRight(); this.m_long_prop[SYMBOL_PROP_BACKGROUND_COLOR] = this.SymbolBackgroundColor(); this.m_long_prop[SYMBOL_PROP_CHART_MODE] = this.SymbolChartMode(); this.m_long_prop[SYMBOL_PROP_TRADE_CALC_MODE] = this.SymbolCalcMode(); this.m_long_prop[SYMBOL_PROP_SWAP_MODE] = this.SymbolSwapMode(); //--- 実数型プロパティを保存する this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKHIGH)] = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKHIGH); this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASKLOW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_ASKLOW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTHIGH)] = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTHIGH); this.m_double_prop[this.IndexProp(SYMBOL_PROP_LASTLOW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_LASTLOW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_POINT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_POINT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_PROFIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_LOSS); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_CONTRACT_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_STEP); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_LIMIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_LONG); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_SHORT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_TURNOVER); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_INTEREST); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_OPEN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_CLOSE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_AW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_SETTLEMENT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_BID)] = this.m_tick.bid; this.m_double_prop[this.IndexProp(SYMBOL_PROP_ASK)] = this.m_tick.ask; this.m_double_prop[this.IndexProp(SYMBOL_PROP_LAST)] = this.m_tick.last; this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDHIGH)] = this.SymbolBidHigh(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_BIDLOW)] = this.SymbolBidLow(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_REAL)] = this.SymbolVolumeReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMEHIGH_REAL)] = this.SymbolVolumeHighReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMELOW_REAL)] = this.SymbolVolumeLowReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_OPTION_STRIKE)] = this.SymbolOptionStrike(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_ACCRUED_INTEREST)] = this.SymbolTradeAccruedInterest(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_FACE_VALUE)] = this.SymbolTradeFaceValue(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_LIQUIDITY_RATE)] = this.SymbolTradeLiquidityRate(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_HEDGED)] = this.SymbolMarginHedged(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_INITIAL)] = this.m_margin_rate.Long.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL)] = this.m_margin_rate.BuyStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL)] = this.m_margin_rate.BuyLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL)] = this.m_margin_rate.BuyStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE)] = this.m_margin_rate.Long.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE)] = this.m_margin_rate.BuyStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE)] = this.m_margin_rate.BuyLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE)] = this.m_margin_rate.BuyStopLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_INITIAL)] = this.m_margin_rate.Short.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL)] = this.m_margin_rate.SellStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL)] = this.m_margin_rate.SellLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL)] = this.m_margin_rate.SellStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE)] = this.m_margin_rate.Short.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE)] = this.m_margin_rate.SellStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE)] = this.m_margin_rate.SellLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE)]= this.m_margin_rate.SellStopLimit.Maintenance; //--- 文字列プロパティを保存する this.m_string_prop[this.IndexProp(SYMBOL_PROP_NAME)] = this.m_name; this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_BASE)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_BASE); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_PROFIT)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_PROFIT); this.m_string_prop[this.IndexProp(SYMBOL_PROP_CURRENCY_MARGIN)] = ::SymbolInfoString(this.m_name,SYMBOL_CURRENCY_MARGIN); this.m_string_prop[this.IndexProp(SYMBOL_PROP_DESCRIPTION)] = ::SymbolInfoString(this.m_name,SYMBOL_DESCRIPTION); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PATH)] = ::SymbolInfoString(this.m_name,SYMBOL_PATH); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BASIS)] = this.SymbolBasis(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_BANK)] = this.SymbolBank(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_ISIN)] = this.SymbolISIN(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_FORMULA)] = this.SymbolFormula(); this.m_string_prop[this.IndexProp(SYMBOL_PROP_PAGE)] = this.SymbolPage(); //--- 追加の整数型プロパティを保存する this.m_long_prop[SYMBOL_PROP_DIGITS_LOTS] = this.SymbolDigitsLot(); //--- if(!select) this.RemoveFromMarketWatch(); } //+------------------------------------------------------------------------------------------------------------+ //|Compare CSymbol objects by all possible properties (for sorting lists by a specified symbol object property)| //+------------------------------------------------------------------------------------------------------------+
基本オブジェクトクラスでオブジェクトイベントを正確に定義するには、銘柄コレクションIDを銘柄オブジェクト型に割り当て、整数および実数データ配列のサイズを設定し、基本親オブジェクトによる銘柄オブジェクトプロパティのイベントを追跡します。次に、整数および実数プロパティの配列で、編集可能および制御対象のパラメータを初期化します。
銘柄objectのRefresh()メソッドも変更されています。
//+------------------------------------------------------------------+ //| Update all symbol data | //+------------------------------------------------------------------+ void CSymbol::Refresh(void) { //--- Update quote data if(!this.RefreshRates()) return; #ifdef __MQL5__ ::ResetLastError(); if(!this.MarginRates()) { this.m_global_error=::GetLastError(); return; } #endif //--- Initialize event data this.m_is_event=false; this.m_hash_sum=0; //--- Update integer properties this.m_long_prop[SYMBOL_PROP_SELECT] = ::SymbolInfoInteger(this.m_name,SYMBOL_SELECT); this.m_long_prop[SYMBOL_PROP_VISIBLE] = ::SymbolInfoInteger(this.m_name,SYMBOL_VISIBLE); this.m_long_prop[SYMBOL_PROP_SESSION_DEALS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_DEALS); this.m_long_prop[SYMBOL_PROP_SESSION_BUY_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_BUY_ORDERS); this.m_long_prop[SYMBOL_PROP_SESSION_SELL_ORDERS] = ::SymbolInfoInteger(this.m_name,SYMBOL_SESSION_SELL_ORDERS); this.m_long_prop[SYMBOL_PROP_VOLUMEHIGH] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMEHIGH); this.m_long_prop[SYMBOL_PROP_VOLUMELOW] = ::SymbolInfoInteger(this.m_name,SYMBOL_VOLUMELOW); this.m_long_prop[SYMBOL_PROP_SPREAD] = ::SymbolInfoInteger(this.m_name,SYMBOL_SPREAD); this.m_long_prop[SYMBOL_PROP_TICKS_BOOKDEPTH] = ::SymbolInfoInteger(this.m_name,SYMBOL_TICKS_BOOKDEPTH); this.m_long_prop[SYMBOL_PROP_START_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_START_TIME); this.m_long_prop[SYMBOL_PROP_EXPIRATION_TIME] = ::SymbolInfoInteger(this.m_name,SYMBOL_EXPIRATION_TIME); this.m_long_prop[SYMBOL_PROP_TRADE_STOPS_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_STOPS_LEVEL); this.m_long_prop[SYMBOL_PROP_TRADE_FREEZE_LEVEL] = ::SymbolInfoInteger(this.m_name,SYMBOL_TRADE_FREEZE_LEVEL); this.m_long_prop[SYMBOL_PROP_BACKGROUND_COLOR] = this.SymbolBackgroundColor(); //--- Update real properties this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_PROFIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_PROFIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_VALUE_LOSS)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_VALUE_LOSS); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_TICK_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_TICK_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_CONTRACT_SIZE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_TRADE_CONTRACT_SIZE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_STEP)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_STEP); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_LIMIT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_VOLUME_LIMIT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_LONG)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_LONG); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SWAP_SHORT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SWAP_SHORT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_INITIAL)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_MAINTENANCE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_TURNOVER)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_TURNOVER); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_INTEREST)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_INTEREST); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_BUY_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_BUY_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_SELL_ORDERS_VOLUME)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_SELL_ORDERS_VOLUME); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_OPEN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_OPEN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_CLOSE)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_CLOSE); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_AW)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_AW); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_SETTLEMENT)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_SETTLEMENT); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MIN)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MIN); this.m_double_prop[this.IndexProp(SYMBOL_PROP_SESSION_PRICE_LIMIT_MAX)] = ::SymbolInfoDouble(this.m_name,SYMBOL_SESSION_PRICE_LIMIT_MAX); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUME_REAL)] = this.SymbolVolumeReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMEHIGH_REAL)] = this.SymbolVolumeHighReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_VOLUMELOW_REAL)] = this.SymbolVolumeLowReal(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_OPTION_STRIKE)] = this.SymbolOptionStrike(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_ACCRUED_INTEREST)] = this.SymbolTradeAccruedInterest(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_FACE_VALUE)] = this.SymbolTradeFaceValue(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_TRADE_LIQUIDITY_RATE)] = this.SymbolTradeLiquidityRate(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_HEDGED)] = this.SymbolMarginHedged(); this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_INITIAL)] = this.m_margin_rate.Long.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_INITIAL)] = this.m_margin_rate.BuyStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_INITIAL)] = this.m_margin_rate.BuyLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_INITIAL)] = this.m_margin_rate.BuyStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_LONG_MAINTENANCE)] = this.m_margin_rate.Long.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOP_MAINTENANCE)] = this.m_margin_rate.BuyStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_LIMIT_MAINTENANCE)] = this.m_margin_rate.BuyLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_BUY_STOPLIMIT_MAINTENANCE)] = this.m_margin_rate.BuyStopLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_INITIAL)] = this.m_margin_rate.Short.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_INITIAL)] = this.m_margin_rate.SellStop.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_INITIAL)] = this.m_margin_rate.SellLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_INITIAL)] = this.m_margin_rate.SellStopLimit.Initial; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SHORT_MAINTENANCE)] = this.m_margin_rate.Short.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOP_MAINTENANCE)] = this.m_margin_rate.SellStop.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_LIMIT_MAINTENANCE)] = this.m_margin_rate.SellLimit.Maintenance; this.m_double_prop[this.IndexProp(SYMBOL_PROP_MARGIN_SELL_STOPLIMIT_MAINTENANCE)]= this.m_margin_rate.SellStopLimit.Maintenance; //--- Fill in the symbol current data for(int i=0;i<SYMBOL_PROP_INTEGER_TOTAL;i++) this.m_long_prop_event[i][3]=this.m_long_prop[i]; for(int i=0;i<SYMBOL_PROP_DOUBLE_TOTAL;i++) this.m_double_prop_event[i][3]=this.m_double_prop[i]; CBaseObj::Refresh(); this.CheckEvents(); } //+------------------------------------------------------------------+
現在および以前の銘柄プロパティの状態を保存するための構造体を作成する必要がなくなったため、現在の銘柄ステータスデータの構造体の入力は削除されました。代わりに、整数と実数プロパティの配列への書き入れを基本オブジェクトで行います。
配列に入力した後、
CBaseObj base objectのRefresh()メソッドを呼び出す必要があります。このメソッドでは、発生した変更の検索が実行され、子孫オブジェクト基本イベントのリストが作成されます。
親クラスで基本イベントのリストを作成した後(イベント生成基準がある場合)、CheckEvents()メソッドを使用して基本イベントを確認します。存在する場合は、銘柄イベントのリストを作成します。
以下は、イベントを確認するメソッドの実装です。
//+------------------------------------------------------------------+ //| Check the list of symbol property changes and create an event | //+------------------------------------------------------------------+ void CSymbol::CheckEvents(void) { int total=this.m_list_events_base.Total(); if(total==0) return; for(int i=0;i<total;i++) { CBaseEvent *event=this.GetEventBase(i); if(event==NULL) continue; long lvalue=0; this.UshortToLong(this.MSCfromTime(this.TickTime()),0,lvalue); this.UshortToLong(event.Reason(),1,lvalue); this.UshortToLong(COLLECTION_SYMBOLS_ID,2,lvalue); if(this.EventAdd((ushort)event.ID(),lvalue,event.Value(),this.Name())) this.m_is_event=true; } } //+------------------------------------------------------------------+
基本イベントのリストが空の場合は、終了します。
基本イベントのリストのループで、次のイベントを受け取ります。イベントを受信した場合、銘柄イベントを作成します。
- ミリ秒単位の現在時刻からミリ秒だけを受け取り、それらをイベントのlongパラメータの最初の2バイトに追加します
- イベントの理由を取得(レベルを上げる/下げる/レベルを上げる/下げる)し、イベントの2番目の2バイトのlongパラメータに追加します
- 銘柄コレクションIDをイベントのlongパラメータの3番目の2バイトに追加します
- 銘柄イベントを銘柄イベントのリストに追加して、銘柄上のイベントの存在を示すフラグを設定します
以下は、管理された銘柄データの変数を初期化するメソッドです。
//+------------------------------------------------------------------+ //| Initialize the variables of controlled symbol data | //+------------------------------------------------------------------+ void CSymbol::InitControlsParams(void) { this.ResetControlsParams(); } //+------------------------------------------------------------------+
管理されたオブジェクトデータ値の変数をリセットする上記のメソッドを呼び出すだけです。
以下は、発生した変更の管理された値とフラグを設定するメソッドと、発生した変更とフラグのサイズを受け取るメソッドです。
//+------------------------------------------------------------------+ //| Set the value of the controlled property increase | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlPropertyINC(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledValueINC(property,(long)value); else this.SetControlledValueINC(property,(double)value); } //+------------------------------------------------------------------+ //| Set the value of the controlled property decrease | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlPropertyDEC(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledValueDEC(property,(long)value); else this.SetControlledValueDEC(property,(double)value); } //+------------------------------------------------------------------+ //| Set the value of the controlled property level | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlPropertyLEVEL(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledValueLEVEL(property,(long)value); else this.SetControlledValueLEVEL(property,(double)value); } //+------------------------------------------------------------------+ //| Set the flag of the symbol property value change | //| exceeding the increase value | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlFlagINC(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledFlagINC(property,(long)value); else this.SetControlledFlagINC(property,(double)value); } //+------------------------------------------------------------------+ //| Set the flag of the symbol property value change | //| exceeding the decrease value | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlFlagDEC(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledFlagDEC(property,(long)value); else this.SetControlledFlagDEC(property,(double)value); } //+------------------------------------------------------------------+ //| Set the change value of the controlled symbol property | //+------------------------------------------------------------------+ template<typename T> void CSymbol::SetControlChangedValue(const int property,const T value) { if(property<SYMBOL_PROP_INTEGER_TOTAL) this.SetControlledChangedValue(property,(long)value); else this.SetControlledChangedValue(property,(double)value); } //+------------------------------------------------------------------+ //| Set the Bid or Last price controlled increase | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastInc(const double value) { this.SetControlPropertyINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //|Set the Bid or Last price controlled decrease | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastDec(const double value) { this.SetControlPropertyDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //| Set the Bid or Last price control level | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLevel(const double value) { this.SetControlPropertyLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BID : SYMBOL_PROP_LAST),::fabs(value)); } //+------------------------------------------------------------------+ //| Return the Bid or Last price change value | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetControlChangedValue(SYMBOL_PROP_BID) : this.GetControlChangedValue(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Return the flag of the Bid or Last price change | //| exceeding the increase value | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagINC(SYMBOL_PROP_BID) : (bool)this.GetControlFlagINC(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Return the flag of the Bid or Last price change | //| exceeding the decrease value | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLast(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagDEC(SYMBOL_PROP_BID) : (bool)this.GetControlFlagDEC(SYMBOL_PROP_LAST)); } //+------------------------------------------------------------------+ //| Set the controlled increase value | //| of the maximum Bid or Last price | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighInc(const double value) { this.SetControlPropertyINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Set the controlled decrease value | //| of the maximum Bid or Last price | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighDec(const double value) { this.SetControlPropertyDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Set the maximum Bid or Last price control level | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastHighLevel(const double value) { this.SetControlPropertyLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDHIGH : SYMBOL_PROP_LASTHIGH),::fabs(value)); } //+------------------------------------------------------------------+ //| Return the maximum Bid or Last price change value | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetControlChangedValue(SYMBOL_PROP_BIDHIGH) : this.GetControlChangedValue(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Return the flag of a change of the maximum | //| Bid or Last price exceeding the increase value | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagINC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetControlFlagINC(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Return the flag of a change of the maximum | //| Bid or Last price exceeding the decrease value | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLastHigh(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagDEC(SYMBOL_PROP_BIDHIGH) : (bool)this.GetControlFlagDEC(SYMBOL_PROP_LASTHIGH)); } //+------------------------------------------------------------------+ //| Set the controlled increase value | //| of the minimum Bid or Last price | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowInc(const double value) { this.SetControlPropertyINC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Set the controlled decrease value | //| of the minimum Bid or Last price | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowDec(const double value) { this.SetControlPropertyDEC((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Set the minimum Bid or Last price control level | //+------------------------------------------------------------------+ void CSymbol::SetControlBidLastLowLevev(const double value) { this.SetControlPropertyLEVEL((this.ChartMode()==SYMBOL_CHART_MODE_BID ? SYMBOL_PROP_BIDLOW : SYMBOL_PROP_LASTLOW),::fabs(value)); } //+------------------------------------------------------------------+ //| Return the minimum Bid or Last price change value | //+------------------------------------------------------------------+ double CSymbol::GetValueChangedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? this.GetControlChangedValue(SYMBOL_PROP_BIDLOW) : this.GetControlChangedValue(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+ //| Return the flag of a change of the minimum | //| Bid or Last price exceeding the increase value | //+------------------------------------------------------------------+ bool CSymbol::IsIncreasedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagINC(SYMBOL_PROP_BIDLOW) : (bool)this.GetControlFlagINC(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+ //| Return the flag of a change of the minimum | //| Bid or Last price exceeding the decrease value | //+------------------------------------------------------------------+ bool CSymbol::IsDecreasedBidLastLow(void) const { return(this.ChartMode()==SYMBOL_CHART_MODE_BID ? (bool)this.GetControlFlagDEC(SYMBOL_PROP_BIDLOW) : (bool)this.GetControlFlagDEC(SYMBOL_PROP_LASTLOW)); } //+------------------------------------------------------------------+
基本オブジェクトクラスを改善する際に、同様のメソッドを既に検討しています。必要な銘柄オブジェクトプロパティに応じて、考慮されるメソッドがここで呼び出されます。
銘柄オブジェクトクラスの改善はこれで終わりです。
後は、銘柄コレクションクラスをわずかに改良するだけです。
\MQL5\Include\DoEasy\Collections\SymbolsCollection.mqhファイルを開いて、必要な変更を加えます。
オブジェクトごとに個別のイベント列挙を作成する必要がなくなったため、last symbol event変数とGetLastEvent()メソッドには、以前のENUM_SYMBOL_EVENT型の代わりにint型を設定します 。
int m_last_event; // 最後のイベント
int GetLastEvent(void) const { return this.m_last_event; }
すべての銘柄イベント(および任意の子孫オブジェクトのイベント)が基本オブジェクトクラスで処理されるようになったため、EventDescription()メソッドの名前をEventMWDescription()に変更し、気配値表示ウィンドウイベントの列挙型を持つ変数をメソッドに渡します。
//--- Return the description of the (1) Market Watch window event, (2) mode of working with symbols string EventMWDescription(const ENUM_MW_EVENT event); string ModeSymbolsListDescription(void);
列挙名が変更されたため、気配値表示ウィンドウの操作方法が若干変更されました(列挙名およびイベント変数型が変更されました)。
//+------------------------------------------------------------------+ //| Working with market watch window events | //+------------------------------------------------------------------+ void CSymbolsCollection::MarketWatchEventsControl(const bool send_events=true) { ::ResetLastError(); //--- If no current prices are received, exit if(!::SymbolInfoTick(::Symbol(),this.m_tick)) { this.m_global_error=::GetLastError(); return; } uchar array[]; int sum=0; this.m_hash_sum=0; //--- Calculate the hash sum of all visible symbols in the Market Watch window this.m_total_symbols=this.SymbolsTotalVisible(); //--- In the loop by all Market Watch window symbols int total_symbols=::SymbolsTotal(true); for(int i=0;i<total_symbols;i++) { //--- get a symbol name by index string name=::SymbolName(i,true); //--- skip if invisible if(!::SymbolInfoInteger(name,SYMBOL_VISIBLE)) continue; //--- write symbol name (characters) codes to the uchar array ::StringToCharArray(name,array); //--- in a loop by the resulting array, sum up the values of all array cells creating the symbol code for(int j=::ArraySize(array)-1;j>WRONG_VALUE;j--) sum+=array[j]; //--- add the symbol code and the loop index specifying the symbol index in the market watch list to the hash sum m_hash_sum+=i+sum; } //--- If sending events is disabled, create the collection list and exit saving the current hash some as the previous one if(!send_events) { //--- Clear the list this.m_list_all_symbols.Clear(); //--- Clear the collection list this.CreateSymbolsList(true); //--- Clear the market watch window snapshot this.CopySymbolsNames(); //--- save the current hash some as the previous one this.m_hash_sum_prev=this.m_hash_sum; //--- save the current number of visible symbols as the previous one this.m_total_symbol_prev=this.m_total_symbols; return; } //--- If the hash sum of symbols in the Market Watch window has changed if(this.m_hash_sum!=this.m_hash_sum_prev) { //--- Define the Market Watch window event this.m_delta_symbol=this.m_total_symbols-this.m_total_symbol_prev; ushort event_id= (ushort( this.m_total_symbols>this.m_total_symbol_prev ? MARKET_WATCH_EVENT_SYMBOL_ADD : this.m_total_symbols<this.m_total_symbol_prev ? MARKET_WATCH_EVENT_SYMBOL_DEL : MARKET_WATCH_EVENT_SYMBOL_SORT) ); //--- Adding a symbol to the Market Watch window if(event_id==MARKET_WATCH_EVENT_SYMBOL_ADD) { string name=""; //--- In the loop by all Market Watch window symbols int total=::SymbolsTotal(true), index=WRONG_VALUE; for(int i=0;i<total;i++) { //--- get the symbol name and check its "visibility". Skip it if invisible name=::SymbolName(i,true); if(!::SymbolInfoInteger(name,SYMBOL_VISIBLE)) continue; //--- If there is no symbol in the collection symbol list yet if(!this.IsPresentSymbolInList(name)) { //--- clear the collection list this.m_list_all_symbols.Clear(); //--- recreate the collection list this.CreateSymbolsList(true); //--- create the symbol collection snapshot this.CopySymbolsNames(); //--- get a new symbol index in the Market Watch window index=this.GetSymbolIndexByName(name); //--- If the "Adding a new symbol" event is successfully added to the event list if(this.EventAdd(event_id,this.TickTime(),index,name)) { //--- send the event to the chart: //--- long value = event time in milliseconds, double value = symbol index, string value = added symbol name ::EventChartCustom(this.m_chart_id,(ushort)event_id,this.TickTime(),index,name); } } } //--- Save the new number of visible symbols in the market watch window this.m_total_symbols=this.SymbolsTotalVisible(); } //--- Remove a symbol from the Market Watch window else if(event_id==MARKET_WATCH_EVENT_SYMBOL_DEL) { //--- clear the collection list this.m_list_all_symbols.Clear(); //--- recreate the collection list this.CreateSymbolsList(true); //--- In a loop by the market watch window snapshot int total=this.m_list_names.Total(); for(int i=0; i<total;i++) { //--- get a symbol name string name=this.m_list_names.At(i); if(name==NULL) continue; //--- if no symbol with such a name exists in the collection symbol list if(!this.IsPresentSymbolInList(name)) { //--- If the "Removing a symbol" event is successfully added to the event list if(this.EventAdd(event_id,this.TickTime(),WRONG_VALUE,name)) { //--- send the event to the chart: //--- long value = event tine in milliseconds, double value = -1 for an absent symbol, string value = a removed symbol name ::EventChartCustom(this.m_chart_id,(ushort)event_id,this.TickTime(),WRONG_VALUE,name); } } } //--- Recreate the market watch snapshot this.CopySymbolsNames(); //--- Save the new number of visible symbols in the market watch window this.m_total_symbols=this.SymbolsTotalVisible(); } //--- Sorting symbols in the Market Watch window else if(event_id==MARKET_WATCH_EVENT_SYMBOL_SORT) { //--- clear the collection list this.m_list_all_symbols.Clear(); //--- set sorting of the collection list as sorting by index this.m_list_all_symbols.Sort(SORT_BY_SYMBOL_INDEX_MW); //--- recreate the collection list this.CreateSymbolsList(true); //--- get the current symbol index in the Market Watch window int index=this.GetSymbolIndexByName(Symbol()); //--- send the event to the chart: //--- long value = event time in milliseconds, double value = current symbol index, string value = current symbol name ::EventChartCustom(this.m_chart_id,(ushort)event_id,this.TickTime(),index,::Symbol()); } //--- save the current number of visible symbols as the previous one this.m_total_symbol_prev=this.m_total_symbols; //--- save the current hash some as the previous one this.m_hash_sum_prev=this.m_hash_sum; } } //+------------------------------------------------------------------+
イベント変数型も、銘柄コレクションイベントリストの操作方法で変更されました。
//+------------------------------------------------------------------+ //| Working with the events of the collection symbol list | //+------------------------------------------------------------------+ void CSymbolsCollection::SymbolsEventsControl(void) { this.m_is_event=false; this.m_list_events.Clear(); this.m_list_events.Sort(); //--- The full update of all collection symbols int total=this.m_list_all_symbols.Total(); for(int i=0;i<total;i++) { CSymbol *symbol=this.m_list_all_symbols.At(i); if(symbol==NULL) continue; symbol.Refresh(); if(!symbol.IsEvent()) continue; this.m_is_event=true; CArrayObj *list=symbol.GetListEvents(); if(list==NULL) continue; this.m_event_code=symbol.GetEventCode(); int n=list.Total(); for(int j=0; j<n; j++) { CEventBaseObj *event=list.At(j); if(event==NULL) continue; ushort event_id=event.ID(); this.m_last_event=event_id; if(this.EventAdd((ushort)event.ID(),event.LParam(),event.DParam(),event.SParam())) { ::EventChartCustom(this.m_chart_id,(ushort)event_id,event.LParam(),event.DParam(),event.SParam()); } } } } //+------------------------------------------------------------------+
イベント列挙定数の名前も、気配値表示ウィンドウイベントの文字列の説明を返すメソッドで変更されました。
//+------------------------------------------------------------------+ //| Return the Market Watch window event description | //+------------------------------------------------------------------+ string CSymbolsCollection::EventMWDescription(const ENUM_MW_EVENT event) { return ( event==MARKET_WATCH_EVENT_SYMBOL_ADD ? TextByLanguage("В окно \"Обзор рынка\" добавлен символ","Added symbol to \"Market Watch\" window") : event==MARKET_WATCH_EVENT_SYMBOL_DEL ? TextByLanguage("Из окна \"Обзор рынка\" удалён символ","Removed symbol from \"Market Watch\" window") : event==MARKET_WATCH_EVENT_SYMBOL_SORT ? TextByLanguage("Изменено расположение символов в окне \"Обзор рынка\"","Changed arrangement of symbols in \"Market Watch\" window") : EnumToString(event) ); } //+------------------------------------------------------------------+
次にCEngineクラスを改善します。 \MQL5\Include\DoEasy\Engine.mqhファイルを開いて、必要な変更を加えます。
銘柄プロパティの最後のイベントを格納する変数、および変数の値を返すメソッドもint型になります。
int m_last_symbol_event; // 銘柄プロパティの最後のイベント
int LastSymbolsEvent(void) const { return this.m_last_symbol_event; }
クラスのpublicセクションで、ushort値のlongパラメータの指定されたストレージインデックスにあるlongコンテナからushort値を取得するメソッドの宣言を追加します。
//--- Retrieve a necessary 'ushort' number from the packed 'long' value ushort LongToUshortFromByte(const long source_value,const uchar index) const;
また、イベントのlongパラメータからイベントミリ秒、理由、ソースをすぐに返す3つのメソッドを記述します。
//--- Return event (1) milliseconds, (2) reason and (3) source from its 'long' value ushort EventMSC(const long lparam) const { return this.LongToUshortFromByte(lparam,0); } ushort EventReason(const long lparam) const { return this.LongToUshortFromByte(lparam,1); } ushort EventSource(const long lparam) const { return this.LongToUshortFromByte(lparam,2); }
ゼロ値はオブジェクトの最初の整数プロパティであるため、クラスコンストラクタの初期化リストで初期化リストの最後の銘柄イベントを格納する変数の初期化値を変更します。これは、負の値で初期化されるようになります。
//+------------------------------------------------------------------+ //| CEngineコンストラクタ | //+------------------------------------------------------------------+ CEngine::CEngine() : m_first_start(true), m_last_trade_event(TRADE_EVENT_NO_EVENT), m_last_account_event(ACCOUNT_EVENT_NO_EVENT), m_last_symbol_event(WRONG_VALUE), m_global_error(ERR_SUCCESS) {
以下は、longコンテナ内の位置のバイトインデックスによってlongコンテナからushort値を取得するメソッドの実装です。
//+------------------------------------------------------------------+ //| Retrieve a necessary 'ushort' number from the packed 'long' value| //+------------------------------------------------------------------+ ushort CEngine::LongToUshortFromByte(const long source_value,const uchar index) const { if(index>3) { ::Print(DFUN,TextByLanguage("Ошибка. Значение \"index\" должно быть в пределах 0 - 3","Error. \"index\" value should be between 0 - 3")); return 0; } long res=source_value>>(16*index); return ushort(res &=0xFFFF); } //+------------------------------------------------------------------+
メソッドは、ushort値を取得するlong値および値が置かれているバイトインデックス(longコンテナでのushort値の場所の値は上記で考慮されています)を受け取ります。次に、インデックス指定の有効性が確認されます。インデックスが無効な場合、エラーメッセージが表示され、0が返されます。
次に、long値のビットを「16
*インデックス」ビット分右シフトし、溢れたビットは抹消してushort値を返します。
MQL4での作業には、コンパイラにERR_ZEROSIZE_ARRAYゼロ配列サイズエラーについて知らせる必要があります。
MQL4コンパイラに知られているもののうち、配列ゼロサイズに最も適したエラーは「無効な配列」です。配列のゼロサイズエラーの代替として設定しましょう。
\MQL5\Include\DoEasy\ToMQL4.mqhファイルを開いて、MQL4コンパイラでは不明なエラーコードを追加します。
//+------------------------------------------------------------------+ //| ToMQL4.mqh | //| Copyright 2017, Artem A. Trishkin, Skype artmedia70 | //| https://www.mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, Artem A. Trishkin, Skype artmedia70" #property link "https://www.mql5.com/ja/users/artmedia70" #property strict #ifdef __MQL4__ //+------------------------------------------------------------------+ //| Error codes | //+------------------------------------------------------------------+ #define ERR_SUCCESS (ERR_NO_ERROR) #define ERR_MARKET_UNKNOWN_SYMBOL (ERR_UNKNOWN_SYMBOL) #define ERR_ZEROSIZE_ARRAY (ERR_ARRAY_INVALID) //+------------------------------------------------------------------+
これらはすべて、CBaseObjオブジェクトによってそのすべての子孫に提供される新しいイベント機能で動作するシンボルを起動するために必要な変更です。
すべてのライブラリオブジェクトの基本オブジェクトのイベント機能のテスト
基本オブジェクトの新しいイベント機能をテストするには、前の記事の EAを\MQL5\Experts\TestDoEasy\ Part17でTestDoEasyPart17.mq5という名前で保存します。
現在の銘柄のスプレッドの変化を4ポイント(増減)でテストし、スプレッドサイズを15ポイント制御します。Bid価格については、その値の増減を+/- 10ポイント制御し、1.13700のレベルを超える価格を追跡します。
前述の監視された値を設定するには、この例のOnInit()ハンドラに次の文字列を追加するだけです。
//+------------------------------------------------------------------+ //| エキスパート初期化関数 | //+------------------------------------------------------------------+ int OnInit() { //--- Calling the function displays the list of enumeration constants in the journal //--- (the list is set in the strings 22 and 25 of the DELib.mqh file) for checking the constants validity //EnumNumbersTest(); //--- Set EA global variables prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_"; for(int i=0;i<TOTAL_BUTT;i++) { butt_data[i].name=prefix+EnumToString((ENUM_BUTTONS)i); butt_data[i].text=EnumToButtText((ENUM_BUTTONS)i); } lot=NormalizeLot(Symbol(),fmax(InpLots,MinimumLots(Symbol())*2.0)); magic_number=InpMagic; stoploss=InpStopLoss; takeprofit=InpTakeProfit; distance_pending=InpDistance; distance_stoplimit=InpDistanceSL; slippage=InpSlippage; trailing_stop=InpTrailingStop*Point(); trailing_step=InpTrailingStep*Point(); trailing_start=InpTrailingStart; stoploss_to_modify=InpStopLossModify; takeprofit_to_modify=InpTakeProfitModify; //--- Check if working with the full list is selected used_symbols_mode=InpModeUsedSymbols; if((ENUM_SYMBOLS_MODE)used_symbols_mode==SYMBOLS_MODE_ALL) { int total=SymbolsTotal(false); string ru_n="\nКоличество символов на сервере "+(string)total+".\nМаксимальное количество: "+(string)SYMBOLS_COMMON_TOTAL+" символов."; string en_n="\nThe number of symbols on server "+(string)total+".\nMaximal number: "+(string)SYMBOLS_COMMON_TOTAL+" symbols."; string caption=TextByLanguage("Внимание!","Attention!"); string ru="Выбран режим работы с полным списком.\nВ этом режиме первичная подготовка списка коллекции символов может занять длительное время."+ru_n+"\nПродолжить?\n\"Нет\" - работа с текущим символом \""+Symbol()+"\""; string en="Full list mode selected.\nIn this mode, the initial preparation of the collection symbols list may take a long time."+en_n+"\nContinue?\n\"No\" - working with the current symbol \""+Symbol()+"\""; string message=TextByLanguage(ru,en); int flags=(MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2); int mb_res=MessageBox(message,caption,flags); switch(mb_res) { case IDNO : used_symbols_mode=SYMBOLS_MODE_CURRENT; break; default: break; } } //--- Fill in the array of used symbols used_symbols=InpUsedSymbols; CreateUsedSymbolsArray((ENUM_SYMBOLS_MODE)used_symbols_mode,used_symbols,array_used_symbols); //--- Set the type of the used symbol list in the symbol collection engine.SetUsedSymbols(array_used_symbols); //--- Displaying the selected mode of working with the symbol object collection Print(engine.ModeSymbolsListDescription(),TextByLanguage(". Количество используемых символов: ",". Number of symbols used: "),engine.GetSymbolsCollectionTotal()); //--- Set controlled values for the current symbol CSymbol* symbol=engine.GetSymbolCurrent(); if(symbol!=NULL) { //--- Set control of the current symbol price increase by 10 points symbol.SetControlBidInc(10*Point()); //--- Set control of the current symbol price decrease by 10 points symbol.SetControlBidDec(10*Point()); //--- Set control of the current symbol spread increase by 4 points symbol.SetControlSpreadInc(4); //--- Set control of the current symbol spread decrease by 4 points symbol.SetControlSpreadDec(4); //--- Set control of the current spread by the value of 15 points symbol.SetControlSpreadLevel(15); //--- Set control of the price crossing the level of 1.13700 symbol.SetControlBidLevel(1.13700); } //--- Check and remove remaining EA graphical objects if(IsPresentObects(prefix)) ObjectsDeleteAll(0,prefix); //--- Create the button panel if(!CreateButtons(InpButtShiftX,InpButtShiftY)) return INIT_FAILED; //--- Set trailing activation button status ButtonState(butt_data[TOTAL_BUTT-1].name,trailing_on); //--- Set CTrade trading class parameters #ifdef __MQL5__ trade.SetDeviationInPoints(slippage); trade.SetExpertMagicNumber(magic_number); trade.SetTypeFillingBySymbol(Symbol()); trade.SetMarginMode(); trade.LogLevel(LOG_LEVEL_NO); #endif //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
これは、追跡された銘柄パラメータの設定のテスト例です。したがって、OnInit()で必要な制御値をすぐに設定します。
ただし、すべてのメソッドが基本オブジェクトに存在するため、操作中に現在の基準に基づいて追跡銘柄値をすばやく変更することを妨げるものはありません。CBaseObjから継承されたオブジェクトにアクセスして、管理されたパラメータを設定するためのメソッドと、変更されたパラメータを受け取るためのメソッドを取得するだけでなく、プログラムに組み込まれたロジックに従って管理されたパラメータを変更します(プログラムまたは後で作成されるライブラリグラフィカルシェルから)。
EA's OnTick()ハンドラから、最後の銘柄イベントを格納している変数を削除します。現在の状態と以前の状態の単純な比較ではなく、銘柄イベントを追跡するための他のツールがあります。
//+------------------------------------------------------------------+ //| エキスパートティック関数 | //+------------------------------------------------------------------+ void OnTick() { //--- Initializing the last events static ENUM_TRADE_EVENT last_trade_event=WRONG_VALUE; static ENUM_ACCOUNT_EVENT last_account_event=WRONG_VALUE; static ENUM_SYMBOL_EVENT last_symbol_event=WRONG_VALUE; //--- If working in the tester if(MQLInfoInteger(MQL_TESTER)) {
銘柄コレクションイベントの処理についてライブラリイベントハンドラを変更します。
//+------------------------------------------------------------------+ //| Handling DoEasy library events | //+------------------------------------------------------------------+ void OnDoEasyEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { int idx=id-CHARTEVENT_CUSTOM; string event="::"+string(idx); //--- Retrieve (1) event time milliseconds, (2) reason and (3) source from lparam, as well as (4) set the exact event time ushort msc=engine.EventMSC(lparam); ushort reason=engine.EventReason(lparam); ushort source=engine.EventSource(lparam); long time=TimeCurrent()*1000+msc; //--- Handling market watch window events if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE) { string name=""; //--- Market Watch window event string descr=engine.GetMWEventDescription((ENUM_MW_EVENT)idx); name=(idx==MARKET_WATCH_EVENT_SYMBOL_SORT ? "" : ": "+sparam); Print(TimeMSCtoString(lparam)," ",descr,name); } //--- Handling symbol events if(source==COLLECTION_SYMBOLS_ID) { CSymbol *symbol=engine.GetSymbolObjByName(sparam); if(symbol==NULL) return; //--- Number of decimal places in the event value - in case of a 'long' event, it is 0, otherwise - Digits() of a symbol int digits=(idx<SYMBOL_PROP_INTEGER_TOTAL ? 0 : symbol.Digits()); //--- Event text description string id_descr=(idx<SYMBOL_PROP_INTEGER_TOTAL ? symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_INTEGER)idx) : symbol.GetPropertyDescription((ENUM_SYMBOL_PROP_DOUBLE)idx)); //--- Property change text value string value=DoubleToString(dparam,digits); //--- Check event reasons and display its description in the journal if(reason==BASE_EVENT_REASON_INC) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_DEC) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_MORE_THEN) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_LESS_THEN) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } if(reason==BASE_EVENT_REASON_EQUALS) { Print(symbol.EventDescription(idx,(ENUM_BASE_EVENT_REASON)reason,source,value,id_descr,digits)); } } //--- Handling trading events if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE) { event=EnumToString((ENUM_TRADE_EVENT)ushort(idx)); int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS); } //--- Handling account events else if(idx>ACCOUNT_EVENT_NO_EVENT && idx<ACCOUNT_EVENTS_NEXT_CODE) { Print(TimeMSCtoString(lparam)," ",sparam,": ",engine.GetAccountEventDescription((ENUM_ACCOUNT_EVENT)idx)); //--- if this is an equity increase if((ENUM_ACCOUNT_EVENT)idx==ACCOUNT_EVENT_EQUITY_INC) { //--- Close a position with the highest profit exceeding zero when the equity exceeds the value, //--- specified in the CAccountsCollection::InitControlsParams() method for //--- the m_control_equity_inc variable tracking the equity increase by 15 units (by default) //--- AccountCollection file, InitControlsParams() method, string 1199 //--- すべてのポジションのリストを取得する CArrayObj* list_positions=engine.GetListMarketPosition(); //--- Select positions with the profit exceeding zero list_positions=CSelect::ByOrderProperty(list_positions,ORDER_PROP_PROFIT_FULL,0,MORE); if(list_positions!=NULL) { //--- 手数料とスワップを考慮して、リストを利益順に並べ替える list_positions.Sort(SORT_BY_ORDER_PROFIT_FULL); //--- Get the position index with the highest profit int index=CSelect::FindOrderMax(list_positions,ORDER_PROP_PROFIT_FULL); if(index>WRONG_VALUE) { COrder* position=list_positions.At(index); if(position!=NULL) { //--- Get a ticket of a position with the highest profit and close the position by a ticket #ifdef __MQL5__ trade.PositionClose(position.Ticket()); #else PositionClose(position.Ticket(),position.Volume()); #endif } } } } } } //+------------------------------------------------------------------+
すべての変更は銘柄オブジェクトからイベントの説明を取得し、イベントの理由に応じて操作ログ表示することにのみ関連するもので、コードでコメントされています。非テストハンドラでは、操作ログにメッセージを表示する代わりに、通常のイベントハンドラを追加します。
EAをコンパイルしてテスターで起動します。
ご覧のとおり、スプレッドが指定された管理値を超えて増減すると、適切なエントリが操作ログに送信されます。Bid価格の変更(10ポイント以上の増減)についても、操作ログエントリが伴います。最後に、Bid価格が指定された管理レベルを超えると、イベントも送信され、操作ログエントリが表示されます。
結果として、ここでは、基本オブジェクトを作成し、任意の子孫オブジェクトのイベントを追跡して制御プログラムに送信できるようにしました。プログラムはそれらを追跡し、組み込みロジックに従って反応することができるとともに新しい追跡値とレベルを設定できるので、プログラム操作ロジックの柔軟な管理が可能になります。
次の段階
次の記事では、CBaseObj基本オブジェクトクラスのイベント機能に基づいて、口座オブジェクトとそのイベントの動作を実装します。
現在のバージョンのライブラリのすべてのファイルは、テスト用EAファイルと一緒に以下に添付されているので、テストするにはダウンロードしてください。
質問、コメント、提案はコメント欄にお願いします。
シリーズのこれまでの記事:
第1部: 概念、データ管理
第2部:
過去の注文と取引のコレクション
第3部:注文と取引のコレクション、検索と並び替え
第4部:
取引イベント概念
第5部: 取引イベントのクラスとコレクション取引イベントのプログラムへの送信
第6部:
ネッティング勘定イベント
第7部: StopLimit注文発動イベント、注文およびポジション変更イベントの機能の準備
第8部:
注文とポジションの変更イベント
第9部:MQL4との互換性 - データの準備
第10部:MQL4との互換性
- ポジションオープンイベントと指値注文発動イベント
第11部:MQL4との互換性 - ポジション決済イベント
第12部:口座オブジェクトクラスと口座オブジェクトコレクション
第13部:口座オブジェクトイベント>第14部銘柄オブジェクト
第15部銘柄オブジェクトコレクション
Part
16. Symbol collection events