DoEasyライブラリのグラフィックス(第82部): ライブラリオブジェクトのリファクタリングとグラフィカルオブジェクトのコレクション
内容
概念
前回の記事で、ライブラリオブジェクトへのグラフィックの処理の統合を開始しました。各ライブラリオブジェクトには、グラフィカルオブジェクトを処理するためのオブジェクトの独自のインスタンスがあり、適切なグラフィカルオブジェクト(標準およびCCanvasベースのオブジェクトの両方)を構築できます。
グラフィックをライブラリオブジェクトに統合するために、前回の記事ではバーオブジェクトの改良を開始しました。とりわけ、グラフィック管理クラスを実装しました。デバッグした後で、新しく作成されたデバッグ済みチャート処理メカニズムを他のオブジェクトに追加するつもりです。
次に、すべてのライブラリオブジェクトを改善します。各オブジェクトには、そのオブジェクトを定義できるようにする一意のID(Type())が必要です。各ライブラリオブジェクトでグラフィカルオブジェクトを作成できる必要がありますが、グラフィカルオブジェクトは誰に作成されたかを「知っている」必要があります。ライブラリオブジェクトを使用して作成されたグラフィカルオブジェクトは、作成した親を認識し、その親へのポインタを持っている必要があります。一方、親は、作成したグラフィカルオブジェクトを認識し、それらへのポインタを持っている必要があります。
同時に、グラフィカルオブジェクトを作成したら、グラフィカルオブジェクトの単一のコレクションリストに追加する必要があります。すべてのグラフィカルオブジェクトには、新しいプロパティ(オブジェクトの所属)が必要です。これにより、プログラムによって、またはターミナルで手動で、グラフィカルオブジェクトがどのように作成されるかを決定できます。ライブラリを使用してプログラムから作成されたオブジェクトは、作成直後にリストに追加されます。ターミナルによって作成されたグラフィック(チャートに手動で追加されたさまざまなグラフィカルオブジェクト)は、グラフィカルオブジェクトのコレクションクラスによって追跡され、リストに追加/リストから削除される必要があります。プログラムがそれらを管理できるように、グラフィカルオブジェクトクラスの個別のプログラムオブジェクトを作成する必要があります。
これを行うには、グラフィカルオブジェクトのコレクションクラスでターミナルで開いているすべてのグラフウィンドウのステータスの追跡を実装する必要があります。つまり、標準のグラフィカルオブジェクトの発生、ライブラリオブジェクトの作成、コレクションリストへの追加です。標準のグラフィカルオブジェクトの削除についても同じことが言えます。
したがって、ライブラリは最終的に、開いているチャートに存在するすべての標準グラフィカルオブジェクトを制御し、手動で作成されていることを考慮しながら、それらを独自のオブジェクトであるかのように処理できるようになります。
これは、今後のいくつかの記事の基礎です。
ここでは、タイプを割り当てることですべてのライブラリオブジェクトを改善し、グラフィカルオブジェクトコレクションクラスで作業します。つまり、ターミナルで開いているチャートで新しいグラフィカルオブジェクトの追跡/既存のグラフィカルオブジェクトの削除を調整します。
ライブラリクラスの改善
\MQL5\Include\DoEasy\Defines.mqhに新しいマクロ置換と列挙を追加しましょう。すべてのライブラリオブジェクトのタイプを追加して、作成直後にオブジェクトの「type」プロパティに値を設定する必要があります。
ただし、最初に、グラフィカルオブジェクトコレクションタイマーのパラメータを指定するためのマクロ置換を追加して、既存のコレクションのタイマーパラメータのリストの最後に追加します。
//--- Parameters of the chart collection timer #define COLLECTION_CHARTS_PAUSE (500) // Chart collection timer pause in milliseconds #define COLLECTION_CHARTS_COUNTER_STEP (16) // Chart timer counter increment #define COLLECTION_CHARTS_COUNTER_ID (9) // Chart timer counter ID //--- Parameters of the graphical objects collection timer #define COLLECTION_GRAPH_OBJ_PAUSE (250) // Graphical objects collection timer pause in milliseconds #define COLLECTION_GRAPH_OBJ_COUNTER_STEP (16) // Graphical objects timer counter increment #define COLLECTION_GRAPH_OBJ_COUNTER_ID (10) // Graphical objects timer counter ID //--- Collection list IDs
このファイルには、すでにコレクションリストIDが含まれています。
オブジェクト型IDのリストを継続することは合理的です。新しいオブジェクトコレクションを引き続き追加し、それらのIDのリストを拡張するため、オブジェクト型値の開始点として使用するラベルを追加する必要があります。
//--- Collection list IDs #define COLLECTION_HISTORY_ID (0x777A) // Historical collection list ID #define COLLECTION_MARKET_ID (0x777B) // Market collection list ID #define COLLECTION_EVENTS_ID (0x777C) // Event collection list ID #define COLLECTION_ACCOUNT_ID (0x777D) // Account collection list ID #define COLLECTION_SYMBOLS_ID (0x777E) // Symbol collection list ID #define COLLECTION_SERIES_ID (0x777F) // Timeseries collection list ID #define COLLECTION_BUFFERS_ID (0x7780) // Indicator buffer collection list ID #define COLLECTION_INDICATORS_ID (0x7781) // Indicator collection list ID #define COLLECTION_INDICATORS_DATA_ID (0x7782) // Indicator data collection list ID #define COLLECTION_TICKSERIES_ID (0x7783) // Tick series collection list ID #define COLLECTION_MBOOKSERIES_ID (0x7784) // DOM series collection list ID #define COLLECTION_MQL5_SIGNALS_ID (0x7785) // MQL5 signals collection list ID #define COLLECTION_CHARTS_ID (0x7786) // Chart collection list ID #define COLLECTION_CHART_WND_ID (0x7787) // Chart window list ID #define COLLECTION_GRAPH_OBJ_ID (0x7788) // Graphical object collection list ID #define COLLECTION_ID_LIST_END (COLLECTION_GRAPH_OBJ_ID) // End of collection ID list //--- Pending request type IDs
ラベル値+1は、ここで追加するライブラリオブジェクト型列挙型の最初の定数の値になります。
//--- Canvas parameters #define PAUSE_FOR_CANV_UPDATE (16) // Canvas update frequency #define NULL_COLOR (0x00FFFFFF) // Zero for the canvas with the alpha channel #define OUTER_AREA_SIZE (16) // Size of one side of the outer area around the workspace //+------------------------------------------------------------------+ //| Enumerations | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| List of library object types | //+------------------------------------------------------------------+ enum ENUM_OBJECT_DE_TYPE { //--- Graphics OBJECT_DE_TYPE_GBASE = COLLECTION_ID_LIST_END+1, // "Base object of all library graphical objects" object type OBJECT_DE_TYPE_GELEMENT, // "Graphical element" object type OBJECT_DE_TYPE_GFORM, // Form object type OBJECT_DE_TYPE_GSHADOW, // Shadow object type //--- Animation OBJECT_DE_TYPE_GFRAME, // "Single animation frame" object type OBJECT_DE_TYPE_GFRAME_TEXT, // "Single text animation frame" object type OBJECT_DE_TYPE_GFRAME_QUAD, // "Single rectangular animation frame" object type OBJECT_DE_TYPE_GFRAME_GEOMETRY, // "Single geometric animation frame" object type OBJECT_DE_TYPE_GANIMATIONS, // "Animations" object type //--- Managing graphical objects OBJECT_DE_TYPE_GELEMENT_CONTROL, // "Managing graphical objects" object type //--- Standard graphical objects OBJECT_DE_TYPE_GSTD_VLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_VLINE, // "Vertical line" object type OBJECT_DE_TYPE_GSTD_HLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_HLINE, // "Horizontal line" object type OBJECT_DE_TYPE_GSTD_TREND = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TREND, // "Trend line" object type OBJECT_DE_TYPE_GSTD_TRENDBYANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRENDBYANGLE, // "Trend line by angle" object type OBJECT_DE_TYPE_GSTD_CYCLES = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CYCLES, // "Cyclic lines" object type OBJECT_DE_TYPE_GSTD_ARROWED_LINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROWED_LINE, // "Arrowed line" object type OBJECT_DE_TYPE_GSTD_CHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHANNEL, // "Equidistant channel" object type OBJECT_DE_TYPE_GSTD_STDDEVCHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_STDDEVCHANNEL, // "Standard deviation channel" object type OBJECT_DE_TYPE_GSTD_REGRESSION = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_REGRESSION, // "Linear regression channel" object type OBJECT_DE_TYPE_GSTD_PITCHFORK = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_PITCHFORK, // "Andrews' pitchfork" object type OBJECT_DE_TYPE_GSTD_GANNLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNLINE, // "Gann line" object type OBJECT_DE_TYPE_GSTD_GANNFAN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNFAN, // "Gann fan" object type OBJECT_DE_TYPE_GSTD_GANNGRID = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNGRID, // "Gann grid" object type OBJECT_DE_TYPE_GSTD_FIBO = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBO, // "Fibo levels" object type OBJECT_DE_TYPE_GSTD_FIBOTIMES = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOTIMES, // "Fibo time zones" object type OBJECT_DE_TYPE_GSTD_FIBOFAN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOFAN, // "Fibo fan" object type OBJECT_DE_TYPE_GSTD_FIBOARC = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOARC, // "Fibo arcs" object type OBJECT_DE_TYPE_GSTD_FIBOCHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOCHANNEL, // "Fibo channel" object type OBJECT_DE_TYPE_GSTD_EXPANSION = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EXPANSION, // "Fibo expansion" object type OBJECT_DE_TYPE_GSTD_ELLIOTWAVE5 = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE5, // "Elliott 5 waves" object type OBJECT_DE_TYPE_GSTD_ELLIOTWAVE3 = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE3, // "Elliott 3 waves" object type OBJECT_DE_TYPE_GSTD_RECTANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE, // "Rectangle" object type OBJECT_DE_TYPE_GSTD_TRIANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRIANGLE, // "Triangle" object type OBJECT_DE_TYPE_GSTD_ELLIPSE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIPSE, // "Ellipse" object type OBJECT_DE_TYPE_GSTD_ARROW_THUMB_UP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_UP, // "Thumb up" object type OBJECT_DE_TYPE_GSTD_ARROW_THUMB_DOWN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_DOWN, // "Thumb down" object type OBJECT_DE_TYPE_GSTD_ARROW_UP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_UP, // "Arrow up" object type OBJECT_DE_TYPE_GSTD_ARROW_DOWN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_DOWN, // "Arrow down" object type OBJECT_DE_TYPE_GSTD_ARROW_STOP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_STOP, // "Stop sign" object type OBJECT_DE_TYPE_GSTD_ARROW_CHECK = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_CHECK, // "Check mark" object type OBJECT_DE_TYPE_GSTD_ARROW_LEFT_PRICE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_LEFT_PRICE, // "Left price label" object type OBJECT_DE_TYPE_GSTD_ARROW_RIGHT_PRICE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_RIGHT_PRICE, // "Right price label" object type OBJECT_DE_TYPE_GSTD_ARROW_BUY = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_BUY, // "Buy sign" object type OBJECT_DE_TYPE_GSTD_ARROW_SELL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_SELL, // "Sell sign" object type OBJECT_DE_TYPE_GSTD_ARROW = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW, // "Arrow" object type OBJECT_DE_TYPE_GSTD_TEXT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TEXT, // "Text" object type OBJECT_DE_TYPE_GSTD_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_LABEL, // "Text label" object type OBJECT_DE_TYPE_GSTD_BUTTON = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BUTTON, // "Button" object type OBJECT_DE_TYPE_GSTD_CHART = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHART, // "Chart" object type OBJECT_DE_TYPE_GSTD_BITMAP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP, // "Bitmap" object type OBJECT_DE_TYPE_GSTD_BITMAP_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP_LABEL, // "Bitmap label" object type OBJECT_DE_TYPE_GSTD_EDIT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EDIT, // "Input field" object type OBJECT_DE_TYPE_GSTD_EVENT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EVENT, // "Event object which corresponds to an event in Economic Calendar" object type OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE_LABEL, // "Rectangle Label object used to create and design the custom graphical interface" object type //--- Objects OBJECT_DE_TYPE_BASE = OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL+1, // Base object for all library objects OBJECT_DE_TYPE_BASE_EXT, // Extended base object for all library objects OBJECT_DE_TYPE_ACCOUNT, // "Account" object type OBJECT_DE_TYPE_BOOK_ORDER, // "Book order" object type OBJECT_DE_TYPE_BOOK_BUY, // "Book buy order" object type OBJECT_DE_TYPE_BOOK_BUY_MARKET, // "Book buy order at market price" object type OBJECT_DE_TYPE_BOOK_SELL, // "Book sell order" object type OBJECT_DE_TYPE_BOOK_SELL_MARKET, // "Book sell order at market price" object type OBJECT_DE_TYPE_BOOK_SNAPSHOT, // "Book snapshot" object type OBJECT_DE_TYPE_BOOK_SERIES, // "Book snapshot series" object type OBJECT_DE_TYPE_CHART, // "Chart" object type OBJECT_DE_TYPE_CHART_WND, // "Chart window" object type OBJECT_DE_TYPE_CHART_WND_IND, // "Chart window indicator" object type OBJECT_DE_TYPE_EVENT, // "Event" object type OBJECT_DE_TYPE_EVENT_BALANCE, // "Balance operation event" object type OBJECT_DE_TYPE_EVENT_MODIFY, // "Pending order/position modification event" object type OBJECT_DE_TYPE_EVENT_ORDER_PLASED, // "Placing a pending order event" object type OBJECT_DE_TYPE_EVENT_ORDER_REMOVED, // "Pending order removal event" object type OBJECT_DE_TYPE_EVENT_POSITION_CLOSE, // "Position closure event" object type OBJECT_DE_TYPE_EVENT_POSITION_OPEN, // "Position opening event" object type OBJECT_DE_TYPE_IND_BUFFER, // "Indicator buffer" object type OBJECT_DE_TYPE_IND_BUFFER_ARROW, // "Arrow rendering buffer" object type OBJECT_DE_TYPE_IND_BUFFER_BAR, // "Bar buffer" object type OBJECT_DE_TYPE_IND_BUFFER_CALCULATE, // "Calculated buffer" object type OBJECT_DE_TYPE_IND_BUFFER_CANDLE, // "Candle buffer" object type OBJECT_DE_TYPE_IND_BUFFER_FILLING, // "Filling buffer" object type OBJECT_DE_TYPE_IND_BUFFER_HISTOGRAMM, // "Histogram buffer" object type OBJECT_DE_TYPE_IND_BUFFER_HISTOGRAMM2, // "Histogram 2 buffer" object type OBJECT_DE_TYPE_IND_BUFFER_LINE, // "Line buffer" object type OBJECT_DE_TYPE_IND_BUFFER_SECTION, // "Section buffer" object type OBJECT_DE_TYPE_IND_BUFFER_ZIGZAG, // "Zigzag buffer" object type OBJECT_DE_TYPE_INDICATOR, // "Indicator" object type OBJECT_DE_TYPE_IND_DATA, // "Indicator data" object type OBJECT_DE_TYPE_IND_DATA_LIST, // "Indicator data list" object type OBJECT_DE_TYPE_IND_AC, // "Accelerator Oscillator indicator" object type OBJECT_DE_TYPE_IND_AD, // "Accumulation/Distribution indicator" object type OBJECT_DE_TYPE_IND_ADX, // "Average Directional Index indicator" object type OBJECT_DE_TYPE_IND_ADXW, // "ADX indicator by Welles Wilder" object type OBJECT_DE_TYPE_IND_ALLIGATOR, // "Alligator indicator" object type OBJECT_DE_TYPE_IND_AMA, // "Adaptive Moving Average indicator" object type OBJECT_DE_TYPE_IND_AO, // "Awesome Oscillator indicator" object type OBJECT_DE_TYPE_IND_ATR, // "Average True Range" object type OBJECT_DE_TYPE_IND_BANDS, // "Bollinger Bands® indicator" object type OBJECT_DE_TYPE_IND_BEARS, // "Bears Power indicator" object type OBJECT_DE_TYPE_IND_BULLS, // "Bulls Power indicator" object type OBJECT_DE_TYPE_IND_BWMFI, // "Market Facilitation Index indicator" object type OBJECT_DE_TYPE_IND_CCI, // "Commodity Channel Index indicator" object type OBJECT_DE_TYPE_IND_CHAIKIN, // "Chaikin Oscillator indicator" object type OBJECT_DE_TYPE_IND_CUSTOM, // "Custom indicator" object type OBJECT_DE_TYPE_IND_DEMA, // "Double Exponential Moving Average indicator" object type OBJECT_DE_TYPE_IND_DEMARKER, // "DeMarker indicator" object type OBJECT_DE_TYPE_IND_ENVELOPES, // "Envelopes indicator" object type OBJECT_DE_TYPE_IND_FORCE, // "Force Index indicator" object type OBJECT_DE_TYPE_IND_FRACTALS, // "Fractals indicator" object type OBJECT_DE_TYPE_IND_FRAMA, // "Fractal Adaptive Moving Average indicator" object type OBJECT_DE_TYPE_IND_GATOR, // "Gator Oscillator indicator" object type OBJECT_DE_TYPE_IND_ICHIMOKU, // "Ichimoku Kinko Hyo indicator" object type OBJECT_DE_TYPE_IND_MA, // "Moving Average indicator" object type OBJECT_DE_TYPE_IND_MACD, // "Moving Average Convergence/Divergence indicator" object type OBJECT_DE_TYPE_IND_MFI, // "Money Flow Index indicator" object type OBJECT_DE_TYPE_IND_MOMENTUM, // "Momentum indicator" object type OBJECT_DE_TYPE_IND_OBV, // "On Balance Volume indicator" object type OBJECT_DE_TYPE_IND_OSMA, // "Moving Average of Oscillator indicator" object type OBJECT_DE_TYPE_IND_RSI, // "Relative Strength Index indicator" object type OBJECT_DE_TYPE_IND_RVI, // "Relative Vigor Index indicator" object type OBJECT_DE_TYPE_IND_SAR, // "Parabolic SAR indicator" object type OBJECT_DE_TYPE_IND_STDEV, // "Standard Deviation indicator" object type OBJECT_DE_TYPE_IND_STOCH, // "Stochastic Oscillator indicator" object type OBJECT_DE_TYPE_IND_TEMA, // "Triple Exponential Moving Average indicator" object OBJECT_DE_TYPE_IND_TRIX, // "Triple Exponential Moving Averages Oscillator indicator" object type OBJECT_DE_TYPE_IND_VIDYA, // "Variable Index Dynamic Average indicator" object type OBJECT_DE_TYPE_IND_VOLUMES, // "Volumes indicator" object type OBJECT_DE_TYPE_IND_WPR, // "Williams' Percent Range indicator" object type OBJECT_DE_TYPE_MQL5_SIGNAL, // "mql5 signal" object type OBJECT_DE_TYPE_ORDER_DEAL_POSITION, // "Order/Deal/Position" object type OBJECT_DE_TYPE_HISTORY_BALANCE, // "Historical balance operation" object type OBJECT_DE_TYPE_HISTORY_DEAL, // "Historical deal" object type OBJECT_DE_TYPE_HISTORY_ORDER_MARKET, // "Historical market order" object type OBJECT_DE_TYPE_HISTORY_ORDER_PENDING, // "Historical removed pending order" object type OBJECT_DE_TYPE_MARKET_ORDER, // "Market order" object type OBJECT_DE_TYPE_MARKET_PENDING, // "Pending order" object type OBJECT_DE_TYPE_MARKET_POSITION, // "Market position" object type OBJECT_DE_TYPE_PENDING_REQUEST, // "Pending trading request" object type OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_OPEN, // "Pending request to open a position" object type OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_CLOSE, // "Pending request to close a position" object type OBJECT_DE_TYPE_PENDING_REQUEST_POSITION_SLTP, // "Pending request to modify position stop orders" object type OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_PLACE, // "Pending request to place a pending order" object type OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_REMOVE, // "Pending request to delete a pending order" object type OBJECT_DE_TYPE_PENDING_REQUEST_ORDER_MODIFY, // "Pending request to modify pending order parameters" object type OBJECT_DE_TYPE_SERIES_BAR, // "Bar" object type OBJECT_DE_TYPE_SERIES_PERIOD, // "Period timeseries" object type OBJECT_DE_TYPE_SERIES_SYMBOL, // "Symbol timeseries" object type OBJECT_DE_TYPE_SYMBOL, // "Symbol" object type OBJECT_DE_TYPE_SYMBOL_BONDS, // "Bond symbol" object type OBJECT_DE_TYPE_SYMBOL_CFD, // "CFD (contract for difference) symbol" object type OBJECT_DE_TYPE_SYMBOL_COLLATERAL, // "Non-tradable asset symbol" object type" object type OBJECT_DE_TYPE_SYMBOL_COMMODITY, // "Commodity symbol" object type OBJECT_DE_TYPE_SYMBOL_COMMON, // "Common group symbol" object type OBJECT_DE_TYPE_SYMBOL_CRYPTO, // "Cryptocurrency symbol" object type OBJECT_DE_TYPE_SYMBOL_CUSTOM, // "Custom symbol" object type OBJECT_DE_TYPE_SYMBOL_EXCHANGE, // "Exchange symbol" object type OBJECT_DE_TYPE_SYMBOL_FUTURES, // "Futures symbol" object type OBJECT_DE_TYPE_SYMBOL_FX, // "Forex symbol" object type OBJECT_DE_TYPE_SYMBOL_FX_EXOTIC, // "Exotic Forex symbol" object type OBJECT_DE_TYPE_SYMBOL_FX_MAJOR, // "Major Forex symbol" object type OBJECT_DE_TYPE_SYMBOL_FX_MINOR, // "Minor Forex symbol" object type OBJECT_DE_TYPE_SYMBOL_FX_RUB, // "RUB Forex symbol" object type OBJECT_DE_TYPE_SYMBOL_INDEX, // "Index symbol" object type OBJECT_DE_TYPE_SYMBOL_INDICATIVE, // "Indicative symbol" object type OBJECT_DE_TYPE_SYMBOL_METALL, // "Metal symbol" object type OBJECT_DE_TYPE_SYMBOL_OPTION, // "Option symbol" object type OBJECT_DE_TYPE_SYMBOL_STOCKS, // "Stock symbol" object type OBJECT_DE_TYPE_TICK, // "Tick" object type OBJECT_DE_TYPE_NEW_TICK, // "New tick" object type OBJECT_DE_TYPE_TICKSERIES, // "Tick data series" object type OBJECT_DE_TYPE_TRADE, // "Trading object" object type }; //+------------------------------------------------------------------+ //| Search and sorting data | //+------------------------------------------------------------------+
列挙定数を注意深く調べると、標準のグラフィカルオブジェクトに対応するオブジェクトのタイプがライブラリオブジェクト列挙の前の定数の値+1+対応するグラフィカルオブジェクトの標準列挙値を使用していることがわかります。 標準のグラフィカルオブジェクトのリストの列挙が完了した後、最後のグラフィカルオブジェクトの定数値+1から開始して、ライブラリオブジェクト型のリストの列挙を続行します。
//--- Managing graphical objects OBJECT_DE_TYPE_GELEMENT_CONTROL, // "Managing graphical objects" object type //--- Standard graphical objects OBJECT_DE_TYPE_GSTD_VLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_VLINE, // "Vertical line" object type OBJECT_DE_TYPE_GSTD_HLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_HLINE, // "Horizontal line" object type OBJECT_DE_TYPE_GSTD_TREND = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TREND, // "Trend line" object type OBJECT_DE_TYPE_GSTD_TRENDBYANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRENDBYANGLE, // "Trend line by angle" object type OBJECT_DE_TYPE_GSTD_CYCLES = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CYCLES, // "Cyclic lines" object type OBJECT_DE_TYPE_GSTD_ARROWED_LINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROWED_LINE, // "Arrowed line" object type OBJECT_DE_TYPE_GSTD_CHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHANNEL, // "Equidistant channel" object type OBJECT_DE_TYPE_GSTD_STDDEVCHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_STDDEVCHANNEL, // "Standard deviation channel" object type OBJECT_DE_TYPE_GSTD_REGRESSION = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_REGRESSION, // "Linear regression channel" object type OBJECT_DE_TYPE_GSTD_PITCHFORK = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_PITCHFORK, // "Andrews' pitchfork" object type OBJECT_DE_TYPE_GSTD_GANNLINE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNLINE, // "Gann line" object type OBJECT_DE_TYPE_GSTD_GANNFAN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNFAN, // "Gann fan" object type OBJECT_DE_TYPE_GSTD_GANNGRID = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_GANNGRID, // "Gann grid" object type OBJECT_DE_TYPE_GSTD_FIBO = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBO, // "Fibo levels" object type OBJECT_DE_TYPE_GSTD_FIBOTIMES = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOTIMES, // "Fibo time zones" object type OBJECT_DE_TYPE_GSTD_FIBOFAN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOFAN, // "Fibo fan" object type OBJECT_DE_TYPE_GSTD_FIBOARC = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOARC, // "Fibo arcs" object type OBJECT_DE_TYPE_GSTD_FIBOCHANNEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_FIBOCHANNEL, // "Fibo channel" object type OBJECT_DE_TYPE_GSTD_EXPANSION = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EXPANSION, // "Fibo expansion" object type OBJECT_DE_TYPE_GSTD_ELLIOTWAVE5 = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE5, // "Elliott 5 waves" object type OBJECT_DE_TYPE_GSTD_ELLIOTWAVE3 = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIOTWAVE3, // "Elliott 3 waves" object type OBJECT_DE_TYPE_GSTD_RECTANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE, // "Rectangle" object type OBJECT_DE_TYPE_GSTD_TRIANGLE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TRIANGLE, // "Triangle" object type OBJECT_DE_TYPE_GSTD_ELLIPSE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ELLIPSE, // "Ellipse" object type OBJECT_DE_TYPE_GSTD_ARROW_THUMB_UP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_UP, // "Thumb up" object type OBJECT_DE_TYPE_GSTD_ARROW_THUMB_DOWN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_THUMB_DOWN, // "Thumb down" object type OBJECT_DE_TYPE_GSTD_ARROW_UP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_UP, // "Arrow up" object type OBJECT_DE_TYPE_GSTD_ARROW_DOWN = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_DOWN, // "Arrow down" object type OBJECT_DE_TYPE_GSTD_ARROW_STOP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_STOP, // "Stop sign" object type OBJECT_DE_TYPE_GSTD_ARROW_CHECK = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_CHECK, // "Check mark" object type OBJECT_DE_TYPE_GSTD_ARROW_LEFT_PRICE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_LEFT_PRICE, // "Left price label" object type OBJECT_DE_TYPE_GSTD_ARROW_RIGHT_PRICE = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_RIGHT_PRICE, // "Right price label" object type OBJECT_DE_TYPE_GSTD_ARROW_BUY = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_BUY, // "Buy sign" object type OBJECT_DE_TYPE_GSTD_ARROW_SELL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW_SELL, // "Sell sign" object type OBJECT_DE_TYPE_GSTD_ARROW = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_ARROW, // "Arrow" object type OBJECT_DE_TYPE_GSTD_TEXT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_TEXT, // "Text" object type OBJECT_DE_TYPE_GSTD_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_LABEL, // "Text label" object type OBJECT_DE_TYPE_GSTD_BUTTON = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BUTTON, // "Button" object type OBJECT_DE_TYPE_GSTD_CHART = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_CHART, // "Chart" object type OBJECT_DE_TYPE_GSTD_BITMAP = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP, // "Bitmap" object type OBJECT_DE_TYPE_GSTD_BITMAP_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_BITMAP_LABEL, // "Bitmap label" object type OBJECT_DE_TYPE_GSTD_EDIT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EDIT, // "Input field" object type OBJECT_DE_TYPE_GSTD_EVENT = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_EVENT, // "Event object which corresponds to an event in Economic Calendar" object type OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL = OBJECT_DE_TYPE_GELEMENT_CONTROL+1+OBJ_RECTANGLE_LABEL, // "Rectangle Label object used to create and design the custom graphical interface" object type //--- Objects OBJECT_DE_TYPE_BASE = OBJECT_DE_TYPE_GSTD_RECTANGLE_LABEL+1, // Base object for all library objects
したがって、標準のグラフィカルオブジェクトに基づくグラフィカルライブラリオブジェクトには、標準のグラフィカルオブジェクト型に対応するタイプ値があります。このタイプは簡単に計算できますが、後続のタイプは引き続き最後の標準グラフィカルオブジェクトの定数を超える値を取得し、列挙定数の値間で衝突を引き起こしません。
次に、グラフィカルオブジェクトプロパティのリストを少し改善する必要があります。つまり、プログラムまたはターミナル(作成方法-プログラムまたは手動)を使用してオブジェクトの所属の列挙を追加し、このプロパティをグラフィカルオブジェクトの整数プロパティの列挙に追加する必要があります。
//+------------------------------------------------------------------+ //| List of graphical objects affiliations | //+------------------------------------------------------------------+ enum ENUM_GRAPH_OBJ_BELONG { GRAPH_OBJ_BELONG_PROGRAM, // Graphical object belongs to a program GRAPH_OBJ_BELONG_TERMINAL, // Graphical object does not belong to a program }; //+------------------------------------------------------------------+ //| The list of graphical element types | //+------------------------------------------------------------------+ enum ENUM_GRAPH_ELEMENT_TYPE { GRAPH_ELEMENT_TYPE_ELEMENT, // Element GRAPH_ELEMENT_TYPE_SHADOW_OBJ, // Shadow object GRAPH_ELEMENT_TYPE_FORM, // Form GRAPH_ELEMENT_TYPE_WINDOW, // Window }; //+------------------------------------------------------------------+ //| Integer properties of the graphical element on the canvas | //+------------------------------------------------------------------+ enum ENUM_CANV_ELEMENT_PROP_INTEGER { CANV_ELEMENT_PROP_ID = 0, // Element ID CANV_ELEMENT_PROP_TYPE, // Graphical element type CANV_ELEMENT_PROP_BELONG, // Graphical element affiliation CANV_ELEMENT_PROP_NUM, // Element index in the list CANV_ELEMENT_PROP_CHART_ID, // Chart ID CANV_ELEMENT_PROP_WND_NUM, // Chart subwindow index CANV_ELEMENT_PROP_COORD_X, // Form's X coordinate on the chart CANV_ELEMENT_PROP_COORD_Y, // Form's Y coordinate on the chart CANV_ELEMENT_PROP_WIDTH, // Element width CANV_ELEMENT_PROP_HEIGHT, // Element height CANV_ELEMENT_PROP_RIGHT, // Element right border CANV_ELEMENT_PROP_BOTTOM, // Element bottom border CANV_ELEMENT_PROP_ACT_SHIFT_LEFT, // Active area offset from the left edge of the element CANV_ELEMENT_PROP_ACT_SHIFT_TOP, // Active area offset from the upper edge of the element CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT, // Active area offset from the right edge of the element CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM, // Active area offset from the bottom edge of the element CANV_ELEMENT_PROP_MOVABLE, // Element moveability flag CANV_ELEMENT_PROP_ACTIVE, // Element activity flag CANV_ELEMENT_PROP_COORD_ACT_X, // X coordinate of the element active area CANV_ELEMENT_PROP_COORD_ACT_Y, // Y coordinate of the element active area CANV_ELEMENT_PROP_ACT_RIGHT, // Right border of the element active area CANV_ELEMENT_PROP_ACT_BOTTOM, // Bottom border of the element active area }; #define CANV_ELEMENT_PROP_INTEGER_TOTAL (22) // Total number of integer properties #define CANV_ELEMENT_PROP_INTEGER_SKIP (0) // Number of integer properties not used in sorting //+------------------------------------------------------------------+
新しいプロパティが追加されたため、これらのプロパティの総数を増やす必要があります(21から22)。さらに、プロパティによる並べ替えを可能なグラフィカルオブジェクトの並べ替え基準の列挙に追加する必要があります。
//+------------------------------------------------------------------+ //| Possible sorting criteria of graphical elements on the canvas | //+------------------------------------------------------------------+ #define FIRST_CANV_ELEMENT_DBL_PROP (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP) #define FIRST_CANV_ELEMENT_STR_PROP (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP+CANV_ELEMENT_PROP_DOUBLE_TOTAL-CANV_ELEMENT_PROP_DOUBLE_SKIP) enum ENUM_SORT_CANV_ELEMENT_MODE { //--- Sort by integer properties SORT_BY_CANV_ELEMENT_ID = 0, // Sort by element ID SORT_BY_CANV_ELEMENT_TYPE, // Sort by graphical element type SORT_BY_CANV_ELEMENT_BELONG, // Sort by a graphical element affiliation SORT_BY_CANV_ELEMENT_NUM, // Sort by form index in the list SORT_BY_CANV_ELEMENT_CHART_ID, // Sort by chart ID SORT_BY_CANV_ELEMENT_WND_NUM, // Sort by chart window index SORT_BY_CANV_ELEMENT_COORD_X, // Sort by the element X coordinate on the chart SORT_BY_CANV_ELEMENT_COORD_Y, // Sort by the element Y coordinate on the chart SORT_BY_CANV_ELEMENT_WIDTH, // Sort by the element width SORT_BY_CANV_ELEMENT_HEIGHT, // Sort by the element height SORT_BY_CANV_ELEMENT_RIGHT, // Sort by the element right border SORT_BY_CANV_ELEMENT_BOTTOM, // Sort by the element bottom border SORT_BY_CANV_ELEMENT_ACT_SHIFT_LEFT, // Sort by the active area offset from the left edge of the element SORT_BY_CANV_ELEMENT_ACT_SHIFT_TOP, // Sort by the active area offset from the top edge of the element SORT_BY_CANV_ELEMENT_ACT_SHIFT_RIGHT, // Sort by the active area offset from the right edge of the element SORT_BY_CANV_ELEMENT_ACT_SHIFT_BOTTOM, // Sort by the active area offset from the bottom edge of the element SORT_BY_CANV_ELEMENT_MOVABLE, // Sort by the element moveability flag SORT_BY_CANV_ELEMENT_ACTIVE, // Sort by the element activity flag SORT_BY_CANV_ELEMENT_COORD_ACT_X, // Sort by X coordinate of the element active area SORT_BY_CANV_ELEMENT_COORD_ACT_Y, // Sort by Y coordinate of the element active area SORT_BY_CANV_ELEMENT_ACT_RIGHT, // Sort by the right border of the element active area SORT_BY_CANV_ELEMENT_ACT_BOTTOM, // Sort by the bottom border of the element active area //--- Sort by real properties //--- Sort by string properties SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,// Sort by an element object name SORT_BY_CANV_ELEMENT_NAME_RES, // Sort by the graphical resource name }; //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Data.mqhに、グラフィカルオブジェクトの新しいメッセージインデックスを追加します。
//--- CShadowObj MSG_SHADOW_OBJ_IMG_SMALL_BLUR_LARGE, // Error! Image size too small or blur too extensive //--- CGraphElementsCollection MSG_CHART_OBJ_COLLECTION_ERR_OBJ_ALREADY_EXISTS, // Error. A chart control object already exists with chart id MSG_CHART_OBJ_COLLECTION_ERR_FAILED_CREATE_CTRL_OBJ,// Failed to create chart control object with chart id }; //+------------------------------------------------------------------+
また、新しく追加したインデックスに対応するメッセージテキストも追加します。
//--- CShadowObj {"Ошибка! Размер изображения очень маленький или очень большое размытие","Error! Image size is very small or very large blur"}, //--- CGraphElementsCollection {"Ошибка. Уже существует объект управления чартами с идентификатором чарта ","Error. A chart control object already exists with chart id "}, {"Не удалось создать объект управления чартами с идентификатором чарта ","Failed to create chart control object with chart id "}, }; //+---------------------------------------------------------------------+
次に、作成時に各重要な(補助ではない)ライブラリオブジェクトのタイプを指定する必要があります。補助オブジェクトは、メインオブジェクトの操作に必要なオブジェクトです。これらはコレクションオブジェクトではないため、このようなオブジェクトにタイプを割り当てる必要はありません。代わりに、メインライブラリオブジェクトでの作業を整理し、計算を簡素化するためにのみ使用されます。
多くのライブラリオブジェクトは、すべてのライブラリオブジェクトの基本オブジェクトから派生しており、オブジェクト型値を格納するm_type変数と、変数に設定されたオブジェクト型を返すType()仮想メソッドをすでに備えています。したがって、その子孫のコンストラクタでオブジェクト型に対応するm_type変数の値を指定するだけで十分です。
オブジェクトアフィリエーションの概念を導入しましたが、アフィリエーションは、グラフィカルオブジェクト名にプログラム名が含まれていることによって定義されます。これを実現するには、\MQL5\Include\DoEasy\Objects\BaseObj.mqh内のすべてのライブラリオブジェクトの基本オブジェクトがクラスのprotectedセクションにプログラム名を格納するための新しい変数を用意する必要があります。
//+------------------------------------------------------------------+ //| Base object class for all library objects | //+------------------------------------------------------------------+ class CBaseObj : public CObject { protected: CGraphElmControl m_graph_elm; // Instance of the class for managing graphical elements ENUM_LOG_LEVEL m_log_level; // Logging level ENUM_PROGRAM_TYPE m_program; // Program type bool m_first_start; // First launch flag bool m_use_sound; // Flag of playing the sound set for an object bool m_available; // Flag of using a descendant object in the program int m_global_error; // Global error code long m_chart_id_main; // Control program chart ID long m_chart_id; // Chart ID string m_name_program; // Program name string m_name; // Object name string m_folder_name; // Name of the folder storing CBaseObj descendant objects string m_sound_name; // Object sound file name int m_type; // Object type (corresponds to the object type from the ENUM_OBJECT_DE_TYPE enumeration) public:
クラスコンストラクタで、プログラム名を指定し、オブジェクト型を基本オブジェクトとして指定します。
//--- Constructor CBaseObj() : m_program((ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE)), m_name_program(::MQLInfoString(MQL_PROGRAM_NAME)), m_global_error(ERR_SUCCESS), m_log_level(LOG_LEVEL_ERROR_MSG), m_chart_id_main(::ChartID()), m_chart_id(::ChartID()), m_folder_name(DIRECTORY), m_sound_name(""), m_name(__FUNCTION__), m_type(OBJECT_DE_TYPE_BASE), m_use_sound(false), m_available(true), m_first_start(true) {} }; //+------------------------------------------------------------------+
基本オブジェクトクラスとは別に、ファイルにはすべてのライブラリオブジェクトの拡張基本オブジェクトクラスも含まれています。コンストラクタでオブジェクト型をbase-extended として指定します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CBaseObjExt::CBaseObjExt() : m_hash_sum(0),m_hash_sum_prev(0), m_is_event(false),m_event_code(WRONG_VALUE), m_long_prop_total(0), m_double_prop_total(0) { this.m_type=OBJECT_DE_TYPE_BASE_EXT; ::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(); } //+------------------------------------------------------------------+
これら2つのクラス(baseおよびbase-extended)の子孫であるすべてのライブラリオブジェクトの場合、コンストラクタのm_type変数でオブジェクト型を指定するだけで十分です。
\MQL5\Include\DoEasy\Objects\Accounts\Account.mqhのアカウントオブジェクトの場合、これは次のようになります(コンストラクタ全体)。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CAccount::CAccount(void) { this.m_type=OBJECT_DE_TYPE_ACCOUNT; //--- Initialize control data this.SetControlDataArraySizeLong(ACCOUNT_PROP_INTEGER_TOTAL); this.SetControlDataArraySizeDouble(ACCOUNT_PROP_DOUBLE_TOTAL); this.ResetChangesParams(); this.ResetControlsParams(); //--- Save integer properties this.m_long_prop[ACCOUNT_PROP_LOGIN] = ::AccountInfoInteger(ACCOUNT_LOGIN); this.m_long_prop[ACCOUNT_PROP_TRADE_MODE] = ::AccountInfoInteger(ACCOUNT_TRADE_MODE); this.m_long_prop[ACCOUNT_PROP_LEVERAGE] = ::AccountInfoInteger(ACCOUNT_LEVERAGE); this.m_long_prop[ACCOUNT_PROP_LIMIT_ORDERS] = ::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); this.m_long_prop[ACCOUNT_PROP_MARGIN_SO_MODE] = ::AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE); this.m_long_prop[ACCOUNT_PROP_TRADE_ALLOWED] = ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED); this.m_long_prop[ACCOUNT_PROP_TRADE_EXPERT] = ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT); this.m_long_prop[ACCOUNT_PROP_MARGIN_MODE] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_MARGIN_MODE) #else ACCOUNT_MARGIN_MODE_RETAIL_HEDGING #endif ; this.m_long_prop[ACCOUNT_PROP_CURRENCY_DIGITS] = #ifdef __MQL5__::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif ; this.m_long_prop[ACCOUNT_PROP_SERVER_TYPE] = (::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); this.m_long_prop[ACCOUNT_PROP_FIFO_CLOSE] = (#ifdef __MQL5__::TerminalInfoInteger(TERMINAL_BUILD)<2155 ? false : ::AccountInfoInteger(ACCOUNT_FIFO_CLOSE) #else false #endif ); //--- Save real properties this.m_double_prop[this.IndexProp(ACCOUNT_PROP_BALANCE)] = ::AccountInfoDouble(ACCOUNT_BALANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_CREDIT)] = ::AccountInfoDouble(ACCOUNT_CREDIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_PROFIT)] = ::AccountInfoDouble(ACCOUNT_PROFIT); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_EQUITY)] = ::AccountInfoDouble(ACCOUNT_EQUITY); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN)] = ::AccountInfoDouble(ACCOUNT_MARGIN); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_FREE)] = ::AccountInfoDouble(ACCOUNT_MARGIN_FREE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_LEVEL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_LEVEL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_CALL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_SO_SO)] = ::AccountInfoDouble(ACCOUNT_MARGIN_SO_SO); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_INITIAL)] = ::AccountInfoDouble(ACCOUNT_MARGIN_INITIAL); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_MARGIN_MAINTENANCE)]=::AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_ASSETS)] = ::AccountInfoDouble(ACCOUNT_ASSETS); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_LIABILITIES)] = ::AccountInfoDouble(ACCOUNT_LIABILITIES); this.m_double_prop[this.IndexProp(ACCOUNT_PROP_COMMISSION_BLOCKED)]=::AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED); //--- Save string properties this.m_string_prop[this.IndexProp(ACCOUNT_PROP_NAME)] = ::AccountInfoString(ACCOUNT_NAME); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_SERVER)] = ::AccountInfoString(ACCOUNT_SERVER); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_CURRENCY)] = ::AccountInfoString(ACCOUNT_CURRENCY); this.m_string_prop[this.IndexProp(ACCOUNT_PROP_COMPANY)] = ::AccountInfoString(ACCOUNT_COMPANY); //--- Account object name, object and account type (MetaTrader 5 or 4) this.m_name=CMessage::Text(MSG_LIB_PROP_ACCOUNT)+" "+(string)this.Login()+": "+this.Name()+" ("+this.Company()+")"; this.m_type=COLLECTION_ACCOUNT_ID; this.m_type_server=(::TerminalInfoString(TERMINAL_NAME)=="MetaTrader 5" ? 5 : 4); //--- Filling in the current account data for(int i=0;i<ACCOUNT_PROP_INTEGER_TOTAL;i++) this.m_long_prop_event[i][3]=this.m_long_prop[i]; for(int i=0;i<ACCOUNT_PROP_DOUBLE_TOTAL;i++) this.m_double_prop_event[i][3]=this.m_double_prop[i]; //--- Update the base object data and search for changes CBaseObjExt::Refresh(); } //+-------------------------------------------------------------------+
ご覧のとおり、m_type変数に必要なオブジェクト型のみを設定する必要があります。この場合、それは「アカウント」型です。基本オブジェクトクラスで宣言された新しいオブジェクト型値を書き込むと、オブジェクト型が「ベース」から「アカウント」に再定義されます。これで、仮想Type()メソッドは、m_type変数値を返し、基本オブジェクトにも実装され、アカウントオブジェクトクラスコンストラクタで再定義された変数値も返します。
\MQL5\Include\DoEasy\Objects\Book\MarketBookOrd.mqhの板情報抽象注文のクラスは、デフォルトとパラメトリックの2つのコンストラクタを備えています。両方のコンストラクタでオブジェクト型を設定します。
以下は、デフォルトのコンストラクタです。
//--- Compare CMarketBookOrd objects by all properties (to search for equal request objects) bool IsEqual(CMarketBookOrd* compared_req) const; //--- Default constructor CMarketBookOrd(){ this.m_type=OBJECT_DE_TYPE_BOOK_ORDER; } protected: //--- Protected parametric constructor CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol); public: //+-------------------------------------------------------------------+ //|Methods of a simplified access to the DOM request object properties| //+-------------------------------------------------------------------+
以下はパラメトリックコンストラクタです。
//+------------------------------------------------------------------+ //| Protected parametric constructor | //+------------------------------------------------------------------+ CMarketBookOrd::CMarketBookOrd(const ENUM_MBOOK_ORD_STATUS status,const MqlBookInfo &book_info,const string symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_ORDER; //--- Save symbol’s Digits this.m_digits=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS); //--- Save integer object properties this.SetProperty(MBOOK_ORD_PROP_STATUS,status); this.SetProperty(MBOOK_ORD_PROP_TYPE,book_info.type); this.SetProperty(MBOOK_ORD_PROP_VOLUME,book_info.volume); //--- Save real object properties this.SetProperty(MBOOK_ORD_PROP_PRICE,book_info.price); this.SetProperty(MBOOK_ORD_PROP_VOLUME_REAL,book_info.volume_real); //--- Save additional object properties this.SetProperty(MBOOK_ORD_PROP_SYMBOL,(symbol==NULL || symbol=="" ? ::Symbol() : symbol)); //--- Order time is not present in the parameters and is considered in the DOM snapshot class. Reset the time this.SetProperty(MBOOK_ORD_PROP_TIME_MSC,0); } //+------------------------------------------------------------------+
板情報抽象注文の子孫で、適切なオブジェクト型を追加します。
以下は、\MQL5\Include\DoEasy\Objects\Book\MarketBookBuy.mqhの板情報買い注文です。
//+------------------------------------------------------------------+ //| Buy order in DOM | //+------------------------------------------------------------------+ class CMarketBookBuy : public CMarketBookOrd { private: public: //--- Constructor CMarketBookBuy(const string symbol,const MqlBookInfo &book_info) : CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_BUY; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property); //--- Return the object short name virtual string Header(const bool symbol=false); //--- Return the description of order type (ENUM_BOOK_TYPE) virtual string TypeDescription(void); }; //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Book\MarketBookBuyMarket.mqhの市場価格での板情報買い注文
//+------------------------------------------------------------------+ //| Buy order by Market in DOM | //+------------------------------------------------------------------+ class CMarketBookBuyMarket : public CMarketBookOrd { private: public: //--- Constructor CMarketBookBuyMarket(const string symbol,const MqlBookInfo &book_info) : CMarketBookOrd(MBOOK_ORD_STATUS_BUY,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_BUY_MARKET; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property); //--- Return the object short name virtual string Header(const bool symbol=false); //--- Return the description of order type (ENUM_BOOK_TYPE) virtual string TypeDescription(void); }; //+------------------------------------------------------------------+
以下は、\MQL5\Include\DoEasy\Objects\Book\MarketBookSell.mqhの板情報売り注文です。
//+------------------------------------------------------------------+ //| Sell order in DOM | //+------------------------------------------------------------------+ class CMarketBookSell : public CMarketBookOrd { private: public: //--- Constructor CMarketBookSell(const string symbol,const MqlBookInfo &book_info) : CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_SELL; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property); //--- Return the object short name virtual string Header(const bool symbol=false); //--- Return the description of order type (ENUM_BOOK_TYPE) virtual string TypeDescription(void); }; //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Book\MarketBookSellMarket.mqhの市場価格での板情報売り注文
//+------------------------------------------------------------------+ //| Sell order by Market in DOM | //+------------------------------------------------------------------+ class CMarketBookSellMarket : public CMarketBookOrd { private: public: //--- Constructor CMarketBookSellMarket(const string symbol,const MqlBookInfo &book_info) : CMarketBookOrd(MBOOK_ORD_STATUS_SELL,book_info,symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_SELL_MARKET; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_MBOOK_ORD_PROP_INTEGER property); //--- Return the object short name virtual string Header(const bool symbol=false); //--- Return the description of order type (ENUM_BOOK_TYPE) virtual string TypeDescription(void); }; //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Book\MarketBookSnapshot.mqhの「市場の深度スナップショット」クラスには2つのコンストラクタがあります(デフォルトとパラメトリック)。ここでは、両方のコンストラクタでオブジェクト型を指定する必要があります。
以下は、デフォルトのコンストラクタです。
//--- Return the DOM snapshot change string Header(void); //--- Display (1) description and (2) short description of a DOM snapshot virtual void Print(const bool full_prop=false,const bool dash=false); virtual void PrintShort(const bool dash=false,const bool symbol=false); //--- Constructors CMBookSnapshot(){ this.m_type=OBJECT_DE_TYPE_BOOK_SNAPSHOT; } CMBookSnapshot(const string symbol,const long time,MqlBookInfo &book_array[]); //+---------------------------------------------------------------------+ //|Methods of a simplified access to the DOM snapshot object properties | //+---------------------------------------------------------------------+
以下はパラメトリックコンストラクタです。
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CMBookSnapshot::CMBookSnapshot(const string symbol,const long time,MqlBookInfo &book_array[]) : m_time(time) { this.m_type=OBJECT_DE_TYPE_BOOK_SNAPSHOT; //--- Set a symbol this.SetSymbol(symbol); //--- Clear the list this.m_list.Clear(); //--- In the loop by the structure array int total=::ArraySize(book_array); this.m_volume_buy=this.m_volume_sell=0; this.m_volume_buy_real=this.m_volume_sell_real=0; for(int i=0;i<total;i++) { //--- Create order objects of the current DOM snapshot depending on the order type CMarketBookOrd *mbook_ord=NULL; switch(book_array[i].type) { case BOOK_TYPE_BUY : mbook_ord=new CMarketBookBuy(this.m_symbol,book_array[i]); break; case BOOK_TYPE_SELL : mbook_ord=new CMarketBookSell(this.m_symbol,book_array[i]); break; case BOOK_TYPE_BUY_MARKET : mbook_ord=new CMarketBookBuyMarket(this.m_symbol,book_array[i]); break; case BOOK_TYPE_SELL_MARKET : mbook_ord=new CMarketBookSellMarket(this.m_symbol,book_array[i]); break; default: break; } if(mbook_ord==NULL) continue; //--- Set the DOM snapshot time for the order mbook_ord.SetTime(this.m_time); //--- Set the sorted list flag for the list (by the price value) and add the current order object to it //--- If failed to add the object to the DOM order list, remove the order object this.m_list.Sort(SORT_BY_MBOOK_ORD_PRICE); if(!this.m_list.InsertSort(mbook_ord)) delete mbook_ord; //--- If the order object is successfully added to the DOM order list, supplement the total snapshot volumes else { switch(mbook_ord.TypeOrd()) { case BOOK_TYPE_BUY : this.m_volume_buy+=mbook_ord.Volume(); this.m_volume_buy_real+=mbook_ord.VolumeReal(); break; case BOOK_TYPE_SELL : this.m_volume_sell+=mbook_ord.Volume(); this.m_volume_sell_real+=mbook_ord.VolumeReal(); break; case BOOK_TYPE_BUY_MARKET : this.m_volume_buy+=mbook_ord.Volume(); this.m_volume_buy_real+=mbook_ord.VolumeReal(); break; case BOOK_TYPE_SELL_MARKET : this.m_volume_buy+=mbook_ord.Volume(); this.m_volume_buy_real+=mbook_ord.VolumeReal(); break; default: break; } } } } //+------------------------------------------------------------------+
「板情報スナップショットシリーズ」クラスにも2つのコンストラクタがあります。両方にオブジェクト型を設定しましょう。
以下はデフォルトです。
//--- Display (1) description and (2) short description of a DOM snapshot series virtual void Print(const bool full_prop=false,const bool dash=false); virtual void PrintShort(const bool dash=false,const bool symbol=false); //--- Constructors CMBookSeries(){ this.m_type=OBJECT_DE_TYPE_BOOK_SERIES; } CMBookSeries(const string symbol,const uint required=0); //+------------------------------------------------------------------+ //| Methods of working with objects and accessing their properties | //+------------------------------------------------------------------+
以下はパラメトリックコンストラクタです。
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CMBookSeries::CMBookSeries(const string symbol,const uint required=0) : m_symbol(symbol) { this.m_type=OBJECT_DE_TYPE_BOOK_SERIES; this.m_list.Clear(); this.m_list.Sort(SORT_BY_MBOOK_ORD_TIME_MSC); this.SetRequiredUsedDays(required); } //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Events\Event.mqhの抽象イベントクラスは、基本オブジェクトの子孫でも、すべてのライブラリオブジェクトの拡張基本オブジェクトの子孫でもありません。したがって、 m_type 変数はなく、変数値を返す仮想Type()メソッドもありません(このようなメソッドは CObject基本オブジェクトに存在します) クラスはから継承されますが、0を返すため、子孫で再定義する必要があります)。これは、変数とメソッドを追加し、作成した変数のクラスコンストラクタに必要な型を設定する必要があることを意味します。
//+------------------------------------------------------------------+ //| Abstract event class | //+------------------------------------------------------------------+ class CEvent : public CObject { private: int m_event_code; // Event code //--- Return the index of the array the event's (1) double and (2) string properties are located at int IndexProp(ENUM_EVENT_PROP_DOUBLE property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_EVENT_PROP_STRING property)const { return(int)property-EVENT_PROP_INTEGER_TOTAL-EVENT_PROP_DOUBLE_TOTAL; } protected: ENUM_TRADE_EVENT m_trade_event; // Trading event bool m_is_hedge; // Hedge account flag long m_chart_id_main; // Control program chart ID int m_type; // Object type int m_digits; // Symbol's Digits() int m_digits_acc; // Number of decimal places for the account currency long m_long_prop[EVENT_PROP_INTEGER_TOTAL]; // Event integer properties double m_double_prop[EVENT_PROP_DOUBLE_TOTAL]; // Event real properties string m_string_prop[EVENT_PROP_STRING_TOTAL]; // Event string properties //--- return the flag presence in the trading event bool IsPresentEventFlag(const int event_code) const { return (this.m_event_code & event_code)==event_code; } //--- Return (1) the specified magic number, the ID of (2) the first group, (3) second group, (4) pending request from the magic number value ushort GetMagicID(void) const { return ushort(this.Magic() & 0xFFFF); } uchar GetGroupID1(void) const { return uchar(this.Magic()>>16) & 0x0F; } uchar GetGroupID2(void) const { return uchar((this.Magic()>>16) & 0xF0)>>4; } uchar GetPendReqID(void) const { return uchar(this.Magic()>>24) & 0xFF; } //--- Protected parametric constructor CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket); public: //--- Default constructor CEvent(void){ this.m_type=OBJECT_DE_TYPE_EVENT; } //--- Set event's (1) integer, (2) real and (3) string properties void SetProperty(ENUM_EVENT_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_EVENT_PROP_DOUBLE property,double value){ this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_EVENT_PROP_STRING property,string value){ this.m_string_prop[this.IndexProp(property)]=value; } //--- Return the event's (1) integer, (2) real and (3) string properties from the property array long GetProperty(ENUM_EVENT_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_EVENT_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_EVENT_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Return the flag of the event supporting the property virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_EVENT_PROP_STRING property) { return true; } //--- Return an object type virtual int Type(void) const { return this.m_type;} //--- Decode the event code and set the trading event, (2) return the trading event void SetTypeEvent(void); ENUM_TRADE_EVENT TradeEvent(void) const { return this.m_trade_event; } //--- Send the event to the chart (implementation in descendant classes) virtual void SendEvent(void) {;} //--- Compare CEvent objects by a specified property (to sort the lists by a specified event object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CEvent objects by all properties (to search for equal event objects) bool IsEqual(CEvent* compared_event); //+------------------------------------------------------------------+ //| Methods of simplified access to event object properties | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CEvent::CEvent(const ENUM_EVENT_STATUS event_status,const int event_code,const ulong ticket) : m_event_code(event_code),m_digits(0) { this.m_type=OBJECT_DE_TYPE_EVENT; this.m_long_prop[EVENT_PROP_STATUS_EVENT] = event_status; this.m_long_prop[EVENT_PROP_TICKET_ORDER_EVENT] = (long)ticket; this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif; this.m_digits_acc=#ifdef __MQL4__ 2 #else (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #endif; this.m_chart_id_main=::ChartID(); } //+------------------------------------------------------------------+
抽象イベントクラスオブジェクトの子孫では、コンストラクタで必要なオブジェクト型を指定する必要があります。
以下は、\MQL5\Include\DoEasy\Objects\Events\EventBalanceOperation.mqhにある残高操作イベントのクラスです。
//+------------------------------------------------------------------+ //| Balance operation event | //+------------------------------------------------------------------+ class CEventBalanceOperation : public CEvent { public: //--- Constructor CEventBalanceOperation(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_BALANCE,event_code,ticket) { this.m_type=OBJECT_DE_TYPE_EVENT_BALANCE; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_EVENT_PROP_STRING property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
以下は、MQL5\Include\DoEasy\Objects\Events\EventModify.mqhにある未決注文またはポジション変更イベントクラスです。
//+------------------------------------------------------------------+ //| Pending order or position modification event | //+------------------------------------------------------------------+ class CEventModify : public CEvent { private: double m_price; // Price sent to an event //--- Create and return a short event message string EventsMessage(void); public: //--- Constructor CEventModify(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MODIFY,event_code,ticket),m_price(0) { this.m_type=OBJECT_DE_TYPE_EVENT_MODIFY; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
以下は、\MQL5\Include\DoEasy\Objects\Events\EventOrderPlaced.mqhにある未決注文配置イベントのクラスです。
//+------------------------------------------------------------------+ //| Pending order placing event | //+------------------------------------------------------------------+ class CEventOrderPlased : public CEvent { public: //--- Constructor CEventOrderPlased(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MARKET_PENDING,event_code,ticket) { this.m_type=OBJECT_DE_TYPE_EVENT_ORDER_PLASED; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
以下は、\MQL5\Include\DoEasy\Objects\Events\EventOrderRemoved.mqhにある未決注文削除イベントのクラスです。
//+------------------------------------------------------------------+ //| Pending order removal event | //+------------------------------------------------------------------+ class CEventOrderRemoved : public CEvent { public: //--- Constructor CEventOrderRemoved(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_HISTORY_PENDING,event_code,ticket) { this.m_type=OBJECT_DE_TYPE_EVENT_ORDER_REMOVED; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
以下は、\MQL5\Include\DoEasy\Objects\Events\EventPositionClose.mqhにあるポジション決済イベントのクラスです。
//+------------------------------------------------------------------+ //| Position closure event | //+------------------------------------------------------------------+ class CEventPositionClose : public CEvent { private: //--- Create and return a short event message string EventsMessage(void); public: //--- Constructor CEventPositionClose(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_HISTORY_POSITION,event_code,ticket) { this.m_type=OBJECT_DE_TYPE_EVENT_POSITION_CLOSE; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
以下は、\MQL5\Include\DoEasy\Objects\Events\EventPositionOpen.mqhにあるポジションオープンイベントのクラスです。
//+------------------------------------------------------------------+ //| Position opening event | //+------------------------------------------------------------------+ class CEventPositionOpen : public CEvent { private: //--- Create and return a short event message string EventsMessage(void); public: //--- Constructor CEventPositionOpen(const int event_code,const ulong ticket=0) : CEvent(EVENT_STATUS_MARKET_POSITION,event_code,ticket) { this.m_type=OBJECT_DE_TYPE_EVENT_POSITION_OPEN; } //--- Supported order properties (1) real, (2) integer virtual bool SupportProperty(ENUM_EVENT_PROP_INTEGER property); virtual bool SupportProperty(ENUM_EVENT_PROP_DOUBLE property); //--- (1) Display a brief message about the event in the journal, (2) Send the event to the chart virtual void PrintShort(void); virtual void SendEvent(void); }; //+------------------------------------------------------------------+
ご覧のとおり、以前に作成されたオブジェクトのクラスを改善することを目的としたすべてのアクションは、次のように要約されます。
- オブジェクトがすべてのライブラリオブジェクトの基本オブジェクトまたは拡張基本オブジェクトから派生している場合は、Defines.mqhで作成されたENUM_OBJECT_DE_TYPE列挙型のコンストラクタ(デフォルトおよびパラメトリックオブジェクト)からオブジェクト型を指定します。
- それ以外の場合は、クラスのprotectedセクションにm_type変数を追加します。変数は、オブジェクト型を格納するためのものです。publicセクションで、m_type変数値を返す仮想Type()メソッドを追加します。クラスコンストラクタ(デフォルトおよびパラメトリックコンストラクタ)で、ENUM_OBJECT_DE_TYPE列挙型からオブジェクト型を指定します。
すべての変更は、ライブラリオブジェクトクラスのファイルですでに行われています。アクションが同様なので説明は省きます。
\MQL5\Include\DoEasy\Objectsライブラリディレクトリにある改善されたクラスのリストは次のとおりです。
- Chartフォルダ: ChartObj.mqh、ChartWnd.mqh
- Indicatorsフォルダ: Buffer.mqh、BufferArrow.mqh、BufferBars.mqh、BufferCalculate.mqh、BufferCandles.mqh、 BufferFilling.mqh、BufferHistogram.mqh、BufferHistogram2.mqh、BufferLine.mqh、BufferSection.mqh、BufferZigZag.mqh、DataInd.mqh、IndicatorDE.mqh、SeriesDataInd.mqh
Standartフォルダ: IndAC.mqh、IndAD.mqh、IndADX.mqh、IndADXW.mqh、IndAlligator.mqh、IndAMA.mqh、IndAO.mqh、IndATR.mqh、IndBands.mqh、IndBears.mqh、IndBulls.mqh、IndBWMFI.mqh、IndCCI.mqh、IndChaikin.mqh、IndCustom.mqh、IndDEMA.mqh、IndDeMarker.mqh、IndEnvelopes.mqh、IndForce.mqh、IndFractals.mqh、IndFRAMA.mqh、IndGator.mqh、IndIchimoku.mqh、IndMA.mqh、IndMACD.mqh、IndMFI.mqh、IndMomentum.mqh、IndOBV.mqh、IndOsMA.mqh、IndRSI.mqh、IndRVI.mqh、IndSAR.mqh、IndStDev.mqh、IndStoch.mqh、IndTEMA.mqh、IndTRIX.mqh、IndVIDYA.mqh、IndVolumes.mqh、IndWPR.mqh
- MQLSignalBaseフォルダ: MQLSignal.mqh
- Ordersフォルダ: HistoryBalance.mqh、HistoryDeal.mqh、HistoryOrder.mqh、HistoryPending.mqh、MarketOrder.mqh、MarketPending.mqh、MarketPosition.mqh、Order.mqh
- PendRequestフォルダ: PendReqClose.mqh、PendReqModify.mqh、PendReqOpen.mqh、PendReqPlace.mqh、PendReqRemove.mqh、PendReqSLTP.mqh、PendRequest.mqh
- Seriesフォルダ: Bar.mqh、SeriesDE.mqh、TimeSeriesDE.mqh
- Symbolsフォルダ: Symbol.mqh、SymbolBonds.mqh、SymbolCFD.mqh、SymbolCollateral.mqh、SymbolCommodity.mqh、SymbolCommon.mqh、SymbolCrypto.mqh、SymbolCustom.mqh、SymbolExchange.mqh、SymbolFutures.mqh、SymbolFX.mqh、SymbolFXExotic.mqh、SymbolFXMajor.mqh、SymbolFXMinor.mqh、SymbolFXRub.mqh、SymbolIndex.mqh、SymbolIndicative.mqh、SymbolMetall.mqh、SymbolOption.mqh、SymbolStocks.mqh
- Ticksフォルダ: DataTick.mqh、NewTickObj.mqh、TickSeries.mqh
- Tradeフォルダ: TradeObj.mqh
- Graphフォルダ: Form.mqh、GCnvElement.mqh、GraphElmControl.mqh、ShadowObj.mqh
Animationsフォルダ: Animations.mqh、Frame.mqh、FrameGeometry.mqh、FrameQuad.mqh、FrameText.mqh
すべてのファイルは以下に添付されています。
また、\MQL5\Include\DoEasy\Objects\Graph\GBaseObj.mqh内のすべてのライブラリグラフィカルオブジェクトの基本オブジェクトクラスを忘れないでください。オブジェクト型の指定とは別に、は「プログラム/ターミナルに属す」プロパティも備えており、ライブラリ管理プログラムによって作成されたグラフィカルオブジェクトと ターミナルで手動でチャートに追加されたオブジェクトを定義できます。
//+------------------------------------------------------------------+ //| GBaseObj.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\..\Services\DELib.mqh" #include <Graphics\Graphic.mqh> //+------------------------------------------------------------------+ //| Class of the base object of the library graphical objects | //+------------------------------------------------------------------+ class CGBaseObj : public CObject { private: protected: string m_name_prefix; // Object name prefix string m_name; // Object name long m_chart_id; // Chart ID int m_subwindow; // Subwindow index int m_shift_y; // Subwindow Y coordinate shift int m_type; // Object type bool m_visible; // Object visibility ENUM_GRAPH_OBJ_BELONG m_belong; // Program/terminal affiliation //--- Create (1) the object structure and (2) the object from the structure virtual bool ObjectToStruct(void) { return true; } virtual void StructToObject(void){;} public: //--- Return the values of class variables string Name(void) const { return this.m_name; } long ChartID(void) const { return this.m_chart_id; } int SubWindow(void) const { return this.m_subwindow; } ENUM_GRAPH_OBJ_BELONG Belong(void) const { return this.m_belong; } //--- (1) Set and (2) return the object visibility void SetVisible(const bool flag) { long value=(flag ? OBJ_ALL_PERIODS : 0); if(::ObjectSetInteger(this.m_chart_id,this.m_name,OBJPROP_TIMEFRAMES,value)) this.m_visible=flag; } bool IsVisible(void) const { return this.m_visible; } //--- The virtual method returning the object type virtual int Type(void) const { return this.m_type; } //--- Set affiliation void SetBelong(const ENUM_GRAPH_OBJ_BELONG belong){ this.m_belong=belong; } //--- Constructor/destructor CGBaseObj(); ~CGBaseObj(); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CGBaseObj::CGBaseObj() : m_shift_y(0),m_visible(false), m_name_prefix(::MQLInfoString(MQL_PROGRAM_NAME)+"_"),m_belong(GRAPH_OBJ_BELONG_PROGRAM) { this.m_type=OBJECT_DE_TYPE_GBASE; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CGBaseObj::~CGBaseObj() { } //+------------------------------------------------------------------+
ライブラリオブジェクトクラスファイルに実装されているものと同様の改善が、\MQL5\Include\DoEasy\Collections\にあるライブラリオブジェクトコレクションクラスのファイルに実装されました。
以下は、改善されたオブジェクトコレクションクラスのファイルのリストです。
AccountsCollection.mqh、BookSeriesCollection.mqh、BuffersCollection.mqh、ChartObjCollection.mqh、EventsCollection.mqh、HistoryCollection.mqh、IndicatorsCollection.mqh、MarketCollection.mqh、MQLSignalsCollection.mqh、ResourceCollection.mqh、SymbolsCollection.mqh、TickSeriesCollection.mqh、TimeSeriesCollection.mqh
すべてのファイルは以下に添付されています。
これで、ライブラリクラスの改善は終わりです。
グラフィカルオブジェクトのコレクションクラス
前回の記事では、ライブラリのグラフィカルオブジェクトコレクションクラス(\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqh)のワークピースを作成しました。本稿では、その開発を続けていきます。
ターミナルで開いたチャートのいずれかでグラフィカルオブジェクトを作成する場合、ライブラリは、オブジェクトの種類、追加または削除したかどうか、およびライブラリからプログラムで、または手動で作成した方法を定義できる必要があります。プログラムで追加されたオブジェクトは、ライブラリのグラフィカルオブジェクトのコレクションに自動的に追加されるべきではありません。作成時にコレクションリストに追加されます(これについては、以降の記事で説明します)。手動で追加されたグラフィカルオブジェクトの場合、ライブラリはそれらを識別し、それらのグラフィカルオブジェクト(要素)を作成して、コレクションリストに追加する必要があります。チャートからグラフィカルオブジェクトを削除する場合も、ライブラリで同じことを行う必要があります。プログラムオブジェクトは、削除中にリストから削除されます。手動で削除された場合、ライブラリはそれらを追跡し、削除されたグラフィカルオブジェクトに一致する要素をコレクションリストから削除する必要があります。
この機能は1つの記事にはまらないので、すべてを順番に行います。現在の記事では、グラフィカルオブジェクトのコレクションクラスのターミナルチャートのいずれかでグラフィカルオブジェクトの出現を追跡することを実装します。グラフィカルオブジェクトがプログラム的であるか手動的であるかは重要ではありません。コレクションクラスは、チャートの出現と削除を追跡し、その結果を操作ログに送信します(特定のターミナルチャートに追加/削除されたグラフィカルオブジェクトの量)。
チャート上のグラフィカルオブジェクトの数を取得するには、 ObjectsTotal()関数を使用して、指定されたチャートおよびサブウィンドウ内の指定されたタイプのグラフィカルオブジェクト の数を返します。 サブウィンドウ(メインウィンドウを含む)のいずれかで指定されたチャート上の任意のタイプのグラフィカルオブジェクトの数を取得するには、残りのパラメータをデフォルト値(-1)のままにして、必要なチャートIDを関数に渡す必要があります。 )。これにより、サブウィンドウを含むすべてのチャートオブジェクトの数を取得できます。
現在追加されているオブジェクトの数を定義するには、それらの以前の数と現在の数を知る必要があります。これら2つの値の違いは、追加されたオブジェクトの数です。これには、チャート上の現在のグラフィカルオブジェクトの数と、前回のチェック時の数の2つの変数が必要です。数が変更された場合は、チャートに追加された/チャートから削除されたオブジェクトの種類を定義します。
この時点で、この値を正しく計算するという問題が発生します。ObjectsTotal()関数の説明に戻ると、すべてのチャートを一度に返すのではなく、単一のチャートのみのオブジェクトの数を返すことが明らかになります。したがって、各チャートには、現在および以前の数のグラフィカルオブジェクトを格納するための独自の変数が必要です。ここでできる最も簡単なことは、グラフィカルオブジェクトを管理するための小さなクラスを作成することです。開いている各チャートには、クラスの独自のインスタンスが必要です。この場合、他のチャートに関係なく、オブジェクト数の変化を簡単に追跡できます。
このようなクラスを、グラフィカルオブジェクトのコレクションクラス\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqhのファイルに直接実装してみましょう。
//+------------------------------------------------------------------+ //| GraphElementsCollection.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Services\Select.mqh" #include "..\Objects\Graph\Form.mqh" //+------------------------------------------------------------------+ //| Chart object management class | //+------------------------------------------------------------------+ class CChartObjectsControl : public CObject { private: ENUM_TIMEFRAMES m_chart_timeframe; // Chart timeframe long m_chart_id; // Chart ID string m_chart_symbol; // Chart symbol bool m_is_graph_obj_event; // Event flag in the list of graphical objects int m_total_objects; // Number of graphical objects int m_last_objects; // Number of graphical objects during the previous check int m_index_object; // Index of the last graphical object added to the collection from the terminal object list int m_delta_graph_obj; // Difference in the number of graphical objects compared to the previous check public: //--- Return the variable values ENUM_TIMEFRAMES Timeframe(void) const { return this.m_chart_timeframe; } long ChartID(void) const { return this.m_chart_id; } string Symbol(void) const { return this.m_chart_symbol; } bool IsEvent(void) const { return this.m_is_graph_obj_event; } int TotalObjects(void) const { return this.m_total_objects; } int Delta(void) const { return this.m_delta_graph_obj; } //--- Check the chart objects void Refresh(void); //--- Constructors CChartObjectsControl(void) { this.m_chart_id=::ChartID(); this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id); this.m_chart_symbol=::ChartSymbol(this.m_chart_id); this.m_is_graph_obj_event=false; this.m_total_objects=0; this.m_last_objects=0; this.m_index_object=0; this.m_delta_graph_obj=0; } CChartObjectsControl(const long chart_id) { this.m_chart_id=chart_id; this.m_chart_timeframe=(ENUM_TIMEFRAMES)::ChartPeriod(this.m_chart_id); this.m_chart_symbol=::ChartSymbol(this.m_chart_id); this.m_is_graph_obj_event=false; this.m_total_objects=0; this.m_last_objects=0; this.m_index_object=0; this.m_delta_graph_obj=0; } //--- Compare CChartObjectsControl objects by a chart ID (for sorting the list by an object property) virtual int Compare(const CObject *node,const int mode=0) const { const CChartObjectsControl *obj_compared=node; return(this.ChartID()>obj_compared.ChartID() ? 1 : this.ChartID()<obj_compared.ChartID() ? -1 : 0); } }; //+------------------------------------------------------------------+ //| CChartObjectsControl Check objects on a chart | //+------------------------------------------------------------------+ void CChartObjectsControl::Refresh(void) { //--- Graphical objects on the chart this.m_total_objects=::ObjectsTotal(this.ChartID()); int i=this.m_index_object; int delta=this.m_total_objects-this.m_last_objects; //--- If the number of objects has changed if(delta!=0) { //--- Create the string and display it in the journal with the chart ID, its symbol and timeframe string txt=", "+(delta>0 ? "Added: " : "Deleted: ")+(string)fabs(delta)+" obj"; Print(DFUN,"ChartID=",this.ChartID(),", ",this.Symbol(),", ",TimeframeDescription(this.Timeframe()),txt); } //--- save the index of the last added order and the difference with the last check this.m_delta_graph_obj=i-this.m_index_object; this.m_index_object=i; this.m_last_objects=this.m_total_objects; this.m_is_graph_obj_event=(bool)this.m_delta_graph_obj; } //+------------------------------------------------------------------+
一般に、ここではすべてが明確である必要があります。「現在」および前回のチェック中にグラフィカルオブジェクトの量を格納するための変数があります。現在のループインデックス値を格納するための変数:最初からループが常に実行されるのを避けるために、現在のインデックス値を記憶し、次回は最初からではなく保存された値からループを開始します。これは、注文、取引、およびポジション管理ループがどのように機能するかです。ここも同じです。2つのコンストラクタがあります。1つ目は現在のチャートのオブジェクトを作成し、2つ目はIDで指定されたチャートに対して同じことを行います。Compare()メソッドは、チャートIDによって2つのオブジェクトを比較します。これにより、指定されたIDを持つチャートにそのようなオブジェクトがすでに存在することを定義できます。
Refresh()メソッドで、現在および最後のチェック中にオブジェクトの数をチェックするだけです。数が変更されている場合は、操作ログエントリを表示します。次に、m_index_object変数に保存されているループインデックスからオブジェクトをループして、すべての新しいオブジェクトを追跡し、イベントオブジェクトを作成します。現時点では、リソース節約計算のためにループを次に開始するために、ループインデックスが変数にすでに保存されています。これは、将来の使用のための基礎です。
これで、コレクションクラスのターミナルで開いているチャートごとにこのようなオブジェクトを作成すると、各チャートのオブジェクト数の変化を互いに独立して追跡できるようになります。
以前に作成したCGraphElementsCollectionクラスに新しい変数とメソッドを追加します。
クラスのprivateセクションで、チャート管理オブジェクトへのポインタのリスト、チャート上のグラフィカルオブジェクトを追加/削除するためのイベントフラグ変数、 開いているすべてのチャートにオブジェクトの数を格納するための変数および開いているすべてのターミナルチャートに追加/削除されたオブジェクトの総数を格納するための変数を宣言します。
//+------------------------------------------------------------------+ //| Collection of graphical objects | //+------------------------------------------------------------------+ class CGraphElementsCollection : public CBaseObj { private: CArrayObj m_list_charts_control; // List of chart management objects CListObj m_list_all_graph_obj; // List of all graphical objects bool m_is_graph_obj_event; // Event flag in the list of graphical objects int m_total_objects; // Number of graphical objects int m_delta_graph_obj; // Difference in the number of graphical objects compared to the previous check //--- Return the flag indicating the graphical element object in the list of graphical objects bool IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj);
同じセクションで、指定されたチャートのオブジェクトを管理するためのオブジェクトへのポインタを返すメソッド、指定されたチャートのグラフィカルオブジェクトを管理するための新しいオブジェクトを作成してリストに追加するメソッド、チャートIDによってグラフィカルオブジェクトのリストを更新するメソッドを宣言します。
//--- Return the flag indicating the graphical element object in the list of graphical objects bool IsPresentGraphElmInList(const int id,const ENUM_GRAPH_ELEMENT_TYPE type_obj); //--- Return the pointer to the object of managing objects of the specified chart CChartObjectsControl *GetChartObjectCtrlObj(const long chart_id); //--- Create a new object of managing graphical objects of a specified chart and add it to the list CChartObjectsControl *CreateChartObjectCtrlObj(const long chart_id); //--- Update the list of graphical objects by chart ID void RefreshByChartID(const long chart_id); public:
publicセクションで、グラフィカルオブジェクトのリストに発生した変更のフラグを返すメソッドを追加し、チャート管理オブジェクトのリストを作成するメソッドおよび ターミナルチャート上のグラフィカルオブジェクトのリストを更新するメソッドの2つを宣言します。
public: //--- Return itself CGraphElementsCollection *GetObject(void) { return &this; } //--- Return the full collection list 'as is' CArrayObj *GetList(void) { return &this.m_list_all_graph_obj; } //--- Return the list by selected (1) integer, (2) real and (3) string properties meeting the compared criterion CArrayObj *GetList(ENUM_CANV_ELEMENT_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode); } CArrayObj *GetList(ENUM_CANV_ELEMENT_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode); } CArrayObj *GetList(ENUM_CANV_ELEMENT_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByGraphCanvElementProperty(this.GetList(),property,value,mode); } //--- Return the number of new graphical objects, (3) the flag of the occurred change in the list of graphical objects int NewObjects(void) const { return this.m_delta_graph_obj; } bool IsEvent(void) const { return this.m_is_graph_obj_event; } //--- Constructor CGraphElementsCollection(); //--- Display the description of the object properties in the journal (full_prop=true - all properties, false - supported ones only - implemented in descendant classes) virtual void Print(const bool full_prop=false,const bool dash=false); //--- Display a short description of the object in the journal virtual void PrintShort(const bool dash=false,const bool symbol=false); //--- Create the list of chart management objects and return the number of charts int CreateChartControlList(void); //--- Update the list of (1) all graphical objects, (2) on the specified chart, fill in the data on the number of new ones and set the event flag void Refresh(void); void Refresh(const long chart_id); }; //+------------------------------------------------------------------+
クラスコンストラクタで、オブジェクトに適切なタイプを割り当て、チャート管理オブジェクトへのポインタのリストにソート済みリストフラグを設定、リストをクリア、すべてのチャートのオブジェクトの総数をゼロに設定し、グラフィカルオブジェクトコレクションのイベントフラグをリセットします。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CGraphElementsCollection::CGraphElementsCollection() { this.m_type=COLLECTION_GRAPH_OBJ_ID; ::ChartSetInteger(::ChartID(),CHART_EVENT_MOUSE_MOVE,true); ::ChartSetInteger(::ChartID(),CHART_EVENT_MOUSE_WHEEL,true); this.m_list_all_graph_obj.Type(COLLECTION_GRAPH_OBJ_ID); this.m_list_all_graph_obj.Sort(SORT_BY_CANV_ELEMENT_ID); this.m_list_all_graph_obj.Clear(); this.m_list_charts_control.Sort(); this.m_list_charts_control.Clear(); this.m_total_objects=0; this.m_is_graph_obj_event=false; } //+------------------------------------------------------------------+
宣言されたメソッドの実装について考えてみましょう。
以下は、指定されたチャートのグラフィカルオブジェクトを管理する新しいオブジェクトを作成し、それをリストに追加するメソッドです。
//+------------------------------------------------------------------+ //| Create a new graphical object management object | //| for a specified and add it to the list | //+------------------------------------------------------------------+ CChartObjectsControl *CGraphElementsCollection::CreateChartObjectCtrlObj(const long chart_id) { //--- Create a new object for managing chart objects by ID CChartObjectsControl *obj=new CChartObjectsControl(chart_id); //--- If the object is not created, inform of the error and return NULL if(obj==NULL) { ::Print(DFUN,CMessage::Text(MSG_CHART_OBJ_COLLECTION_ERR_FAILED_CREATE_CTRL_OBJ),(string)chart_id); return NULL; } //--- If failed to add the object to the list, inform of the error, remove the object and return NULL if(!this.m_list_charts_control.Add(obj)) { CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST); delete obj; return NULL; } //--- Return the pointer to the object that was created and added to the list return obj; } //+------------------------------------------------------------------+
以下は、指定されたチャートのオブジェクトを管理するオブジェクトへのポインタを返すメソッドです。
//+------------------------------------------------------------------+ //| Return the pointer to the object | //| for managing objects of a specified chart | //+------------------------------------------------------------------+ CChartObjectsControl *CGraphElementsCollection::GetChartObjectCtrlObj(const long chart_id) { //--- In the loop by the total number of objects in the list for(int i=0;i<this.m_list_charts_control.Total();i++) { //--- Get the pointer to the next object CChartObjectsControl *obj=this.m_list_charts_control.At(i); //--- If failed to get the pointer, move on to the next one if(obj==NULL) continue; //--- If the object chart ID is equal to the required one, return the pointer to the object in the list if(obj.ChartID()==chart_id) return obj; } //--- Failed to find the object - return NULL return NULL; } //+------------------------------------------------------------------+
以下は、チャート管理オブジェクトのリストを作成するメソッドです。
//+------------------------------------------------------------------+ //| Create the list of chart management objects | //+------------------------------------------------------------------+ int CGraphElementsCollection::CreateChartControlList(void) { //--- Clear the list of chart management objects and set the sorted list flag to it this.m_list_charts_control.Clear(); this.m_list_charts_control.Sort(); //--- Declare variables to search for charts long chart_id=0; int i=0; //--- In the loop by all open charts in the terminal (no more than 100) while(i<CHARTS_MAX) { //--- Get the chart ID chart_id=::ChartNext(chart_id); if(chart_id<0) break; //--- Create the object for managing chart objects based on the current chart ID in the loop and add it to the list CChartObjectsControl *chart_control=new CChartObjectsControl(chart_id); if(chart_control==NULL) continue; //--- If such an object is already present in the list, inform of that, delete the object and move on to the next chart if(this.m_list_charts_control.Search(chart_control)>WRONG_VALUE) { ::Print(DFUN,CMessage::Text(MSG_CHART_OBJ_COLLECTION_ERR_OBJ_ALREADY_EXISTS),(string)chart_id); delete chart_control; continue; } //--- If failed to add the object to the list, inform of that, remove the object and move on to the next chart if(!this.m_list_charts_control.Add(chart_control)) { CMessage::ToLog(DFUN_ERR_LINE,MSG_LIB_SYS_FAILED_OBJ_ADD_TO_LIST); delete chart_control; continue; } //--- Increase the loop index i++; } //--- The list filled in successfully - return the number of its elements return this.m_list_charts_control.Total(); } //+------------------------------------------------------------------+
以下は、チャートIDによってグラフィカルオブジェクトのリストを更新するメソッドです。
//+------------------------------------------------------------------+ //| Update the list of graphical objects by chart ID | //+------------------------------------------------------------------+ void CGraphElementsCollection::RefreshByChartID(const long chart_id) { //--- Get the pointer to the object for managing graphical objects CChartObjectsControl *obj=GetChartObjectCtrlObj(chart_id); //--- If there is no such an object in the list, create a new one and add it to the list if(obj==NULL) obj=this.CreateChartObjectCtrlObj(chart_id); //--- If the pointer to the object is valid, update the list of graphical objects on a specified chart if(obj!=NULL) obj.Refresh(); } //+------------------------------------------------------------------+
以下は、指定されたチャートのグラフィカルオブジェクトのリストを更新するメソッドです。
//+------------------------------------------------------------------+ //| Update the list of graphical objects on a specified chart | //+------------------------------------------------------------------+ void CGraphElementsCollection::Refresh(const long chart_id) { //--- Get the pointer to the object for managing graphical objects CChartObjectsControl *obj=GetChartObjectCtrlObj(chart_id); //--- If failed to get the pointer, exit the method if(obj==NULL) return; //--- Update the list of graphical objects on a specified chart obj.Refresh(); } //+------------------------------------------------------------------+
以下は、ターミナルで開いているすべてのチャートのすべてのグラフィカルオブジェクトのリストを更新するメソッドです。
//+------------------------------------------------------------------+ //| Update the list of all graphical objects | //+------------------------------------------------------------------+ void CGraphElementsCollection::Refresh(void) { //--- Declare variables to search for charts long chart_id=0; int i=0; //--- In the loop by all open charts in the terminal (no more than 100) while(i<CHARTS_MAX) { //--- Get the chart ID chart_id=::ChartNext(chart_id); if(chart_id<0) break; //--- Update the list of graphical objects by chart ID this.RefreshByChartID(chart_id); //--- Increase the loop index i++; } } //+------------------------------------------------------------------+
提供されている各メソッドのロジックは、適切なコードコメントで詳細に説明されています。ご質問がある場合は、コメント欄でお気軽にお問い合わせください。
次に、新しく作成したグラフィカルオブジェクトのコレクションをCEngineライブラリのメインオブジェクトに含めて、プログラムからコレクション機能にアクセスできるようにする必要があります。
\MQL5\Include\DoEasy\Engine.mqhのクラスのprivateセクションで、グラフィカルオブジェクトコレクションクラスのインスタンスおよびグラフィカルオブジェクトのリストでのイベントフラグ変数 、グラフィカルオブジェクトイベントを管理するメソッドを宣言します。
//+------------------------------------------------------------------+ //| Library basis class | //+------------------------------------------------------------------+ class CEngine { private: CHistoryCollection m_history; // Collection of historical orders and deals CMarketCollection m_market; // Collection of market orders and deals CEventsCollection m_events; // Event collection CAccountsCollection m_accounts; // Account collection CSymbolsCollection m_symbols; // Symbol collection CTimeSeriesCollection m_time_series; // Timeseries collection CBuffersCollection m_buffers; // Collection of indicator buffers CIndicatorsCollection m_indicators; // Indicator collection CTickSeriesCollection m_tick_series; // Collection of tick series CMBookSeriesCollection m_book_series; // Collection of DOM series CMQLSignalsCollection m_signals_mql5; // Collection of MQL5.com Signals service signals CChartObjCollection m_charts; // Chart collection CGraphElementsCollection m_graph_objects; // Collection of graphical objects CResourceCollection m_resource; // Resource list CTradingControl m_trading; // Trading management object CPause m_pause; // Pause object CArrayObj m_list_counters; // List of timer counters int m_global_error; // Global error code bool m_first_start; // First launch flag bool m_is_hedge; // Hedge account flag bool m_is_tester; // Flag of working in the tester bool m_is_market_trade_event; // Account trading event flag bool m_is_history_trade_event; // Account history trading event flag bool m_is_account_event; // Account change event flag bool m_is_symbol_event; // Symbol change event flag bool m_is_graph_obj_event; // Event flag in the list of graphical objects ENUM_TRADE_EVENT m_last_trade_event; // Last account trading event int m_last_account_event; // Last event in the account properties int m_last_symbol_event; // Last event in the symbol properties ENUM_PROGRAM_TYPE m_program; // Program type string m_name; // Program name //--- Return the counter index by id int CounterIndex(const int id) const; //--- Return the first launch flag bool IsFirstStart(void); //--- Handling events of (1) orders, deals and positions, (2) accounts and (3) graphical objects void TradeEventsControl(void); void AccountEventsControl(void); void GraphObjEventsControl(void); //--- (1) Working with a symbol collection and (2) symbol list events in the market watch window void SymbolEventsControl(void); void MarketWatchEventsControl(void); //--- Return the last (1) market pending order, (2) market order, (3) last position, (4) position by ticket COrder *GetLastMarketPending(void); COrder *GetLastMarketOrder(void); COrder *GetLastPosition(void); COrder *GetPosition(const ulong ticket); //--- Return the last (1) removed pending order, (2) historical market order, (3) historical order (market or pending one) by its ticket COrder *GetLastHistoryPending(void); COrder *GetLastHistoryOrder(void); COrder *GetHistoryOrder(const ulong ticket); //--- Return the (1) first and the (2) last historical market orders from the list of all position orders, (3) the last deal COrder *GetFirstOrderPosition(const ulong position_id); COrder *GetLastOrderPosition(const ulong position_id); COrder *GetLastDeal(void); //--- Retrieve a necessary 'ushort' number from the packed 'long' value ushort LongToUshortFromByte(const long source_value,const uchar index) const; public:
クラスコンストラクタで、グラフィカルオブジェクトコレクションのカウンタを作成します。
//+------------------------------------------------------------------+ //| CEngine constructor | //+------------------------------------------------------------------+ CEngine::CEngine() : m_first_start(true), m_last_trade_event(TRADE_EVENT_NO_EVENT), m_last_account_event(WRONG_VALUE), m_last_symbol_event(WRONG_VALUE), m_global_error(ERR_SUCCESS) { this.m_is_hedge=#ifdef __MQL4__ true #else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif; this.m_is_tester=::MQLInfoInteger(MQL_TESTER); this.m_program=(ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE); this.m_name=::MQLInfoString(MQL_PROGRAM_NAME); this.m_list_counters.Sort(); this.m_list_counters.Clear(); this.CreateCounter(COLLECTION_ORD_COUNTER_ID,COLLECTION_ORD_COUNTER_STEP,COLLECTION_ORD_PAUSE); this.CreateCounter(COLLECTION_ACC_COUNTER_ID,COLLECTION_ACC_COUNTER_STEP,COLLECTION_ACC_PAUSE); this.CreateCounter(COLLECTION_SYM_COUNTER_ID1,COLLECTION_SYM_COUNTER_STEP1,COLLECTION_SYM_PAUSE1); this.CreateCounter(COLLECTION_SYM_COUNTER_ID2,COLLECTION_SYM_COUNTER_STEP2,COLLECTION_SYM_PAUSE2); this.CreateCounter(COLLECTION_REQ_COUNTER_ID,COLLECTION_REQ_COUNTER_STEP,COLLECTION_REQ_PAUSE); this.CreateCounter(COLLECTION_TS_COUNTER_ID,COLLECTION_TS_COUNTER_STEP,COLLECTION_TS_PAUSE); this.CreateCounter(COLLECTION_IND_TS_COUNTER_ID,COLLECTION_IND_TS_COUNTER_STEP,COLLECTION_IND_TS_PAUSE); this.CreateCounter(COLLECTION_TICKS_COUNTER_ID,COLLECTION_TICKS_COUNTER_STEP,COLLECTION_TICKS_PAUSE); this.CreateCounter(COLLECTION_CHARTS_COUNTER_ID,COLLECTION_CHARTS_COUNTER_STEP,COLLECTION_CHARTS_PAUSE); this.CreateCounter(COLLECTION_GRAPH_OBJ_COUNTER_ID,COLLECTION_GRAPH_OBJ_COUNTER_STEP,COLLECTION_GRAPH_OBJ_PAUSE); ::ResetLastError(); #ifdef __MQL5__ if(!::EventSetMillisecondTimer(TIMER_FREQUENCY)) { ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_TIMER),(string)::GetLastError()); this.m_global_error=::GetLastError(); } //---__MQL4__ #else if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY)) { ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_TIMER),(string)::GetLastError()); this.m_global_error=::GetLastError(); } #endif //--- } //+------------------------------------------------------------------+
クラスタイマーで、グラフィカルオブジェクトコレクションのタイマーの処理を追加します。
//+------------------------------------------------------------------+ //| CEngine timer | //+------------------------------------------------------------------+ void CEngine::OnTimer(SDataCalculate &data_calculate) { //--- If this is not a tester, work with collection events by timer if(!this.IsTester()) { //--- Timer of the collections of historical orders and deals, as well as of market orders and positions int index=this.CounterIndex(COLLECTION_ORD_COUNTER_ID); CTimerCounter* cnt1=this.m_list_counters.At(index); if(cnt1!=NULL) { //--- If unpaused, work with the order, deal and position collections events if(cnt1.IsTimeDone()) this.TradeEventsControl(); } //--- Account collection timer index=this.CounterIndex(COLLECTION_ACC_COUNTER_ID); CTimerCounter* cnt2=this.m_list_counters.At(index); if(cnt2!=NULL) { //--- If unpaused, work with the account collection events if(cnt2.IsTimeDone()) this.AccountEventsControl(); } //--- Timer 1 of the symbol collection (updating symbol quote data in the collection) index=this.CounterIndex(COLLECTION_SYM_COUNTER_ID1); CTimerCounter* cnt3=this.m_list_counters.At(index); if(cnt3!=NULL) { //--- If the pause is over, update quote data of all symbols in the collection if(cnt3.IsTimeDone()) this.m_symbols.RefreshRates(); } //--- Timer 2 of the symbol collection (updating all data of all symbols in the collection and tracking symbl and symbol search events in the market watch window) index=this.CounterIndex(COLLECTION_SYM_COUNTER_ID2); CTimerCounter* cnt4=this.m_list_counters.At(index); if(cnt4!=NULL) { //--- If the pause is over if(cnt4.IsTimeDone()) { //--- update data and work with events of all symbols in the collection this.SymbolEventsControl(); //--- When working with the market watch list, check the market watch window events if(this.m_symbols.ModeSymbolsList()==SYMBOLS_MODE_MARKET_WATCH) this.MarketWatchEventsControl(); } } //--- Trading class timer index=this.CounterIndex(COLLECTION_REQ_COUNTER_ID); CTimerCounter* cnt5=this.m_list_counters.At(index); if(cnt5!=NULL) { //--- If unpaused, work with the list of pending requests if(cnt5.IsTimeDone()) this.m_trading.OnTimer(); } //--- Timeseries collection timer index=this.CounterIndex(COLLECTION_TS_COUNTER_ID); CTimerCounter* cnt6=this.m_list_counters.At(index); if(cnt6!=NULL) { //--- If the pause is over, work with the timeseries list (update all except the current one) if(cnt6.IsTimeDone()) this.SeriesRefreshAllExceptCurrent(data_calculate); } //--- Timer of timeseries collection of indicator buffer data index=this.CounterIndex(COLLECTION_IND_TS_COUNTER_ID); CTimerCounter* cnt7=this.m_list_counters.At(index); if(cnt7!=NULL) { //--- If the pause is over, work with the timeseries list of indicator data (update all except for the current one) if(cnt7.IsTimeDone()) this.IndicatorSeriesRefreshAll(); } //--- Tick series collection timer index=this.CounterIndex(COLLECTION_TICKS_COUNTER_ID); CTimerCounter* cnt8=this.m_list_counters.At(index); if(cnt8!=NULL) { //--- If the pause is over, work with the tick series list (update all except the current one) if(cnt8.IsTimeDone()) this.TickSeriesRefreshAllExceptCurrent(); } //--- Chart collection timer index=this.CounterIndex(COLLECTION_CHARTS_COUNTER_ID); CTimerCounter* cnt9=this.m_list_counters.At(index); if(cnt9!=NULL) { //--- If unpaused, work with the chart list if(cnt9.IsTimeDone()) this.ChartsRefreshAll(); } //--- Graphical objects collection timer index=this.CounterIndex(COLLECTION_GRAPH_OBJ_COUNTER_ID); CTimerCounter* cnt10=this.m_list_counters.At(index); if(cnt10!=NULL) { //--- If unpaused, work with the list of graphical objects if(cnt10.IsTimeDone()) this.GraphObjEventsControl(); } } //--- If this is a tester, work with collection events by tick else { //--- work with events of collections of orders, deals and positions by tick this.TradeEventsControl(); //--- work with events of collections of accounts by tick this.AccountEventsControl(); //--- update quote data of all collection symbols by tick this.m_symbols.RefreshRates(); //--- work with events of all symbols in the collection by tick this.SymbolEventsControl(); //--- work with the list of pending orders by tick this.m_trading.OnTimer(); //--- work with the timeseries list by tick this.SeriesRefresh(data_calculate); //--- work with the timeseries list of indicator buffers by tick this.IndicatorSeriesRefreshAll(); //--- work with the list of tick series by tick this.TickSeriesRefreshAll(); //--- work with the list of graphical objects by tick this.GraphObjEventsControl(); } } //+------------------------------------------------------------------+
クラス本体の外で、グラフィカルオブジェクトイベントを確認するメソッドを実装します。
//+------------------------------------------------------------------+ //| Check the events of graphical objects | //+------------------------------------------------------------------+ void CEngine::GraphObjEventsControl(void) { //--- Check the changes in the list of graphical objects and set the flag of their events this.m_graph_objects.Refresh(); this.m_is_graph_obj_event=this.m_graph_objects.IsEvent(); //--- If there are changes in the list of graphical objects if(this.m_is_graph_obj_event) { Print(DFUN,"Graph obj is event. NewObjects: ",m_graph_objects.NewObjects()); //--- Get the last event of the graphical object property change // ... } } //+------------------------------------------------------------------+
ここでは、開いているすべてのターミナルチャートを更新するメソッドを呼び出すだけです。
強調表示された文字列以降のすべてのメソッド文字列はまだ処理されていません。適切な機能は、今後の記事で実装されます。その間、グラフィカルオブジェクトコレクションクラスのRefresh()メソッドは、上記で検討したグラフィカルオブジェクト管理オブジェクトの適切なRefresh()メソッドを呼び出すことにより、すべてのチャートイベントを検索するメソッドを交互に呼び出します。このメソッド(開いているチャートごとに一意のメソッド)は、操作ログエントリを介して適切なチャート上のグラフィカルオブジェクトの数を変更することを通知します。この動作をテストしてみましょう。
検証
テストを実行するには、前の記事のEAを使用して、\MQL5\Experts\TestDoEasy\Part82\にTestDoEasyPart82.mq5として保存します。
ここで、変更を少しだけ加える必要があります。
テスターの外部で作業が実行される場合にライブラリタイマーを呼び出すOnTimer()ハンドラを追加します。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- Launch the library timer (only not in the tester) if(!MQLInfoInteger(MQL_TESTER)) engine.OnTimer(rates_data); } //+------------------------------------------------------------------+
OnChartEvent()ハンドラで、Ctrlキーが押された場合にマウスの右ボタンを使用してコンテキストメニューを呼び出すことを禁止します。この場合、 バータイプの説明を含むバーオブジェクト(これは前の記事で行いました)と作成したオブジェクトの幅をわずかに広くして、長いバーの説明(「実体がゼロのローソク足」)に合うようにします。
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- If working in the tester, exit if(MQLInfoInteger(MQL_TESTER)) return; //--- If the mouse is moved if(id==CHARTEVENT_MOUSE_MOVE) { CForm *form=NULL; datetime time=0; double price=0; int wnd=0; //--- If Ctrl is not pressed, if(!IsCtrlKeyPressed()) { //--- clear the list of created form objects, allow scrolling a chart with the mouse and show the context menu list_forms.Clear(); ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true); ChartSetInteger(ChartID(),CHART_CONTEXT_MENU,true); return; } //--- If X and Y chart coordinates are successfully converted into time and price, if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price)) { //--- get the bar index the cursor is hovered over int index=iBarShift(Symbol(),PERIOD_CURRENT,time); if(index==WRONG_VALUE) return; //--- Get the bar index by index CBar *bar=engine.SeriesGetBar(Symbol(),Period(),index); if(bar==NULL) return; //--- Convert the coordinates of a chart from the time/price representation of the bar object to the X and Y coordinates int x=(int)lparam,y=(int)dparam; if(!ChartTimePriceToXY(ChartID(),0,bar.Time(),(bar.Open()+bar.Close())/2.0,x,y)) return; //--- Disable moving a chart with the mouse and showing the context menu ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false); ChartSetInteger(ChartID(),CHART_CONTEXT_MENU,false); //--- Create the form object name and hide all objects except one having such a name string name="FormBar_"+(string)index; HideFormAllExceptOne(name); //--- If the form object with such a name does not exist yet, if(!IsPresentForm(name)) { //--- create a new form object form=bar.CreateForm(index,name,x,y,114,16); if(form==NULL) return; //--- Set activity and unmoveability flags for the form form.SetActive(true); form.SetMovable(false); //--- Set the opacity of 200 form.SetOpacity(200); //--- The form background color is set as the first color from the color array form.SetColorBackground(array_clr[0]); //--- Form outlining frame color form.SetColorFrame(C'47,70,59'); //--- Draw the shadow drawing flag form.SetShadow(true); //--- Calculate the shadow color as the chart background color converted to the monochrome one color clrS=form.ChangeColorSaturation(form.ColorBackground(),-100); //--- If the settings specify the usage of the chart background color, replace the monochrome color with 20 units //--- Otherwise, use the color specified in the settings for drawing the shadow color clr=(InpUseColorBG ? form.ChangeColorLightness(clrS,-20) : InpColorForm3); //--- Draw the form shadow with the right-downwards offset from the form by three pixels along all axes //--- Set the shadow opacity to 200, while the blur radius is equal to 4 form.DrawShadow(2,2,clr,200,3); //--- Fill the form background with a vertical gradient form.Erase(array_clr,form.Opacity()); //--- Draw an outlining rectangle at the edges of the form form.DrawRectangle(0,0,form.Width()-1,form.Height()-1,form.ColorFrame(),form.Opacity()); //--- If failed to add the form object to the list, remove the form and exit the handler if(!list_forms.Add(form)) { delete form; return; } //--- Capture the form appearance form.Done(); } //--- If the form object exists, if(form!=NULL) { //--- draw a text with the bar type description on it and show the form. The description corresponds to the mouse cursor position form.TextOnBG(0,bar.BodyTypeDescription(),form.Width()/2,form.Height()/2-1,FRAME_ANCHOR_CENTER,C'7,28,21'); form.Show(); } //--- Redraw the chart ChartRedraw(); } } } //+------------------------------------------------------------------+
EAの改善はこれですべてです。
銘柄チャート(複数の開いているチャートがあるはずです)で起動し、各チャートにグラフィカルオブジェクトを追加すると、操作ログに適切なメッセージが表示されます。次に、各チャートで[削除]をクリックして、強調表示されているすべてのグラフィカルオブジェクトを削除します。適切なメッセージが操作ログに再度表示されます。
次の段階
次の記事では、グラフィカルオブジェクトコレクションの改良を続けます。
すべてのグラフィカルオブジェクトの準備ができているわけではありません。これにより、オブジェクトへのポインタをコレクションリストに格納してさらに開発する必要があるため、グラフィカルオブジェクトコレクションの作成がさらに合理的になります。コレクションを処理した直後にポインタを実装します。
ライブラリの現在のバージョンのすべてのファイルは、テストおよびダウンロードできるように、MQL5のテストEAファイルと一緒に以下に添付されています。
質問や提案はコメント欄にお願いします。
**連載のこれまでの記事:
DoEasyライブラリのグラフィックス(第73部): グラフィック要素のフォームオブジェクト
DoEasyライブラリのグラフィックス(第74部): CCanvasクラスを使用した基本的グラフィック要素
DoEasyライブラリのグラフィックス(第75部): 基本的なグラフィック要素でプリミティブとテキストを処理するメソッド
DoEasyライブラリのグラフィックス(第76部): フォームオブジェクトと事前定義されたカラースキーム
DoEasyライブラリのグラフィックス(第77部): 影オブジェクトクラス
DoEasyライブラリのグラフィックス(第78部): ライブラリのアニメーションの原則イメージスライス
DoEasyライブラリのグラフィックス(第79部): 「アニメーションフレーム」オブジェクトクラスとその子孫オブジェクト
DoEasyライブラリのグラフィックス(第80部): 「幾何学的アニメーションフレーム」オブジェクトクラス
DoEasyライブラリのグラフィックス(第81部): ライブラリオブジェクトへのグラフィックの統合
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/9850
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索