
DoEasyライブラリでのその他のクラス(第68部): チャットウィンドウオブジェクトクラスとチャートでの指標オブジェクトクラス
内容
概念
前回の記事では、チャートオブジェクトクラスの開発を開始して最初のバージョンを準備しました。オブジェクトのすべてのパラメータは1つのターミナルチャートを記述します。プロパティの管理が可能になり、ウィンドウサイズとチャート要素の表示パラメータを取得して設定できます。
この場合、チャートには複数のウィンドウがあり、そのウィンドウに指標が含まれている場合があります。ウィンドウには独自のサイズがありますが、今のところ、チャートオブジェクトは、その上にある指定されたサブウィンドウのパラメータを返し、その高さを管理できるだけです。サブウィンドウには、メインチャートウィンドウと同様、異なる数の指標が含まれる場合があります。チャートオブジェクトにアクセスしているときにチャート上にある必要なウィンドウを要求できるためには、これを考慮する必要があります。取得したウィンドウオブジェクトを使用すれば、指標のリストを要求し、さらに処理するために必要なもののハンドルを取得できます。
今日は、2つのオブジェクトを作成します。チャートウィンドウ内の指標オブジェクトは、その識別のためのいくつかの指標パラメータを記述し、チャートウィンドウオブジェクトは、サイズとそれに取り付けられている指標のリスト(チャートウィンドウ内の指標オブジェクト)を格納します。前回の記事で開発を開始したチャートオブジェクトには、ウィンドウオブジェクトのリスト(メインのチャートウィンドウを含む)が接続されるようになります。
将来的には、このような階層により、指標のリストを含む多くのチャートとそのサブウィンドウでの作業が大幅に容易になります。残念ながら、前の記事で発表したチャートオブジェクトのコレクションクラスを作成するにはまだ早すぎます。まず、すべてのメインチャートオブジェクトの改善を完了する必要があります。これが私がここでやろうとしていることです。
指標オブジェクトを含むチャートウィンドウのクラス
まず、必要なすべてのメッセージをライブラリに追加しましょう。
\MQL5\Include\DoEasy\Data.mqhファイルに新しいメッセージのインデックスを追加します。
MSG_CHART_OBJ_CHART_WINDOW, // Main chart window MSG_CHART_OBJ_CHART_SUBWINDOW, // Chart subwindow MSG_CHART_OBJ_CHART_SUBWINDOWS_NUM, // Subwindows MSG_CHART_OBJ_INDICATORS_MW_NAME_LIST, // Indicators in the main chart window MSG_CHART_OBJ_INDICATORS_SW_NAME_LIST, // Indicators in the chart window MSG_CHART_OBJ_INDICATOR, // Indicator MSG_CHART_OBJ_INDICATORS_TOTAL, // Indicators MSG_CHART_OBJ_WINDOW_N, // Window MSG_CHART_OBJ_INDICATORS_NONE, // No indicators }; //+------------------------------------------------------------------+
新しく追加したインデックスに対応するメッセージテキストも追加します。
{"Главное окно графика","Main chart window"}, {"Подокно графика","Chart subwindow"}, {"Подокон","Subwindows"}, {"Индикаторы в главном окне графика","Indicators in the main chart window"}, {"Индикаторы в окне графика","Indicators in the chart window"}, {"Индикатор","Indicator"}, {"Индикаторов","Indicators total"}, {"Окно","Window"}, {"Отсутствуют","No indicators"}, }; //+---------------------------------------------------------------------+
整数チャートオブジェクトプロパティの列挙を作成する際に、メインウィンドウオブジェクトだけでなくすべてのチャートサブウィンドウに対しても固有である3つのプロパティを意図的にスキップしました。
- サブウィンドウの可視性
- 指標サブウィンドウの上部フレームとチャートメインウィンドウの上部フレームの間のY軸の距離(ピクセル単位)
- チャートの高さ(ピクセル単位)
これらは、チャートウィンドウオブジェクトの主なプロパティになります(チャートオブジェクトから定義するサブウィンドウの可視性は別として)。チャートウィンドウのリストは各チャートオブジェクトに存在し、各オブジェクトはこれらのプロパティに対して独自の値を持っている必要があります。各ウィンドウオブジェクトには、ウィンドウに接続された指標のリストが備わるため、整数および文字列チャートオブジェクトプロパティの列挙に追加の定数を設定する必要があります。
\MQL5\Include\DoEasy\Defines.mqhで、以前に定義されコメントアウトされたプロパティをアンコメントします。 これらはチャートウィンドウオブジェクトのプロパティです。チャートウィンドウの指標オブジェクトに対して新しいプロパティを追加します。
//+------------------------------------------------------------------+ //| Chart integer property | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_INTEGER { CHART_PROP_ID = 0, // Chart ID CHART_PROP_TIMEFRAME, // Chart timeframe CHART_PROP_SHOW, // Price chart drawing CHART_PROP_IS_OBJECT, // Chart object (OBJ_CHART) identification attribute CHART_PROP_BRING_TO_TOP, // Show chart above all others CHART_PROP_CONTEXT_MENU, // Enable/disable access to the context menu using the right click CHART_PROP_CROSSHAIR_TOOL, // Enable/disable access to the Crosshair tool using the middle click CHART_PROP_MOUSE_SCROLL, // Scroll the chart horizontally using the left mouse button CHART_PROP_EVENT_MOUSE_WHEEL, // Send messages about mouse wheel events (CHARTEVENT_MOUSE_WHEEL) to all MQL5 programs on a chart CHART_PROP_EVENT_MOUSE_MOVE, // Send messages about mouse button click and movement events (CHARTEVENT_MOUSE_MOVE) to all MQL5 programs on a chart CHART_PROP_EVENT_OBJECT_CREATE, // Send messages about the graphical object creation event (CHARTEVENT_OBJECT_CREATE) to all MQL5 programs on a chart CHART_PROP_EVENT_OBJECT_DELETE, // Send messages about the graphical object destruction event (CHARTEVENT_OBJECT_DELETE) to all MQL5 programs on a chart CHART_PROP_MODE, // Type of the chart (candlesticks, bars or line (ENUM_CHART_MODE)) CHART_PROP_FOREGROUND, // Price chart in the foreground CHART_PROP_SHIFT, // Mode of shift of the price chart from the right border CHART_PROP_AUTOSCROLL, // The mode of automatic shift to the right border of the chart CHART_PROP_KEYBOARD_CONTROL, // Allow managing the chart using a keyboard CHART_PROP_QUICK_NAVIGATION, // Allow the chart to intercept Space and Enter key strokes to activate the quick navigation bar CHART_PROP_SCALE, // Scale CHART_PROP_SCALEFIX, // Fixed scale mode CHART_PROP_SCALEFIX_11, // 1:1 scale mode CHART_PROP_SCALE_PT_PER_BAR, // The mode of specifying the scale in points per bar CHART_PROP_SHOW_TICKER, // Display a symbol ticker in the upper left corner CHART_PROP_SHOW_OHLC, // Display OHLC values in the upper left corner CHART_PROP_SHOW_BID_LINE, // Display Bid value as a horizontal line on the chart CHART_PROP_SHOW_ASK_LINE, // Display Ask value as a horizontal line on a chart CHART_PROP_SHOW_LAST_LINE, // Display Last value as a horizontal line on a chart CHART_PROP_SHOW_PERIOD_SEP, // Display vertical separators between adjacent periods CHART_PROP_SHOW_GRID, // Display a grid on the chart CHART_PROP_SHOW_VOLUMES, // Display volumes on a chart CHART_PROP_SHOW_OBJECT_DESCR, // Display text descriptions of objects CHART_PROP_VISIBLE_BARS, // Number of bars on a chart that are available for display CHART_PROP_WINDOWS_TOTAL, // The total number of chart windows including indicator subwindows CHART_PROP_WINDOW_IS_VISIBLE, // Subwindow visibility CHART_PROP_WINDOW_HANDLE, // Chart window handle CHART_PROP_WINDOW_YDISTANCE, // Distance in Y axis pixels between the upper frame of the indicator subwindow and the upper frame of the chart main window CHART_PROP_FIRST_VISIBLE_BAR, // Number of the first visible bar on the chart CHART_PROP_WIDTH_IN_BARS, // Width of the chart in bars CHART_PROP_WIDTH_IN_PIXELS, // Width of the chart in pixels CHART_PROP_HEIGHT_IN_PIXELS, // Height of the chart in pixels CHART_PROP_COLOR_BACKGROUND, // Color of background of the chart CHART_PROP_COLOR_FOREGROUND, // Color of axes, scale and OHLC line CHART_PROP_COLOR_GRID, // Grid color CHART_PROP_COLOR_VOLUME, // Color of volumes and position opening levels CHART_PROP_COLOR_CHART_UP, // Color for the up bar, shadows and body borders of bull candlesticks CHART_PROP_COLOR_CHART_DOWN, // Color of down bar, its shadow and border of body of the bullish candlestick CHART_PROP_COLOR_CHART_LINE, // Color of the chart line and the Doji candlesticks CHART_PROP_COLOR_CANDLE_BULL, // Color of body of a bullish candlestick CHART_PROP_COLOR_CANDLE_BEAR, // Color of body of a bearish candlestick CHART_PROP_COLOR_BID, // Color of the Bid price line CHART_PROP_COLOR_ASK, // Color of the Ask price line CHART_PROP_COLOR_LAST, // Color of the last performed deal's price line (Last) CHART_PROP_COLOR_STOP_LEVEL, // Color of stop order levels (Stop Loss and Take Profit) CHART_PROP_SHOW_TRADE_LEVELS, // Display trade levels on the chart (levels of open positions, Stop Loss, Take Profit and pending orders) CHART_PROP_DRAG_TRADE_LEVELS, // Enable the ability to drag trading levels on a chart using mouse CHART_PROP_SHOW_DATE_SCALE, // Display the time scale on a chart CHART_PROP_SHOW_PRICE_SCALE, // Display a price scale on a chart CHART_PROP_SHOW_ONE_CLICK, // Display the quick trading panel on the chart CHART_PROP_IS_MAXIMIZED, // Chart window maximized CHART_PROP_IS_MINIMIZED, // Chart window minimized CHART_PROP_IS_DOCKED, // Chart window docked CHART_PROP_FLOAT_LEFT, // Left coordinate of the undocked chart window relative to the virtual screen CHART_PROP_FLOAT_TOP, // Upper coordinate of the undocked chart window relative to the virtual screen CHART_PROP_FLOAT_RIGHT, // Right coordinate of the undocked chart window relative to the virtual screen CHART_PROP_FLOAT_BOTTOM, // Bottom coordinate of the undocked chart window relative to the virtual screen //--- CWndInd CHART_PROP_WINDOW_IND_HANDLE, // Indicator handle in the chart window CHART_PROP_WINDOW_IND_INDEX, // Indicator index in the chart window }; #define CHART_PROP_INTEGER_TOTAL (67) // Total number of integer properties #define CHART_PROP_INTEGER_SKIP (0) // Number of integer DOM properties not used in sorting //+------------------------------------------------------------------+ //| Chart real properties | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_DOUBLE { CHART_PROP_SHIFT_SIZE = CHART_PROP_INTEGER_TOTAL, // Shift size of the zero bar from the right border in % CHART_PROP_FIXED_POSITION, // Chart fixed position from the left border in % CHART_PROP_FIXED_MAX, // Chart fixed maximum CHART_PROP_FIXED_MIN, // Chart fixed minimum CHART_PROP_POINTS_PER_BAR, // Scale in points per bar CHART_PROP_PRICE_MIN, // Chart minimum CHART_PROP_PRICE_MAX, // Chart maximum }; #define CHART_PROP_DOUBLE_TOTAL (7) // Total number of real properties #define CHART_PROP_DOUBLE_SKIP (0) // Number of real properties not used in sorting //+------------------------------------------------------------------+ //| Chart string properties | //+------------------------------------------------------------------+ enum ENUM_CHART_PROP_STRING { CHART_PROP_COMMENT = (CHART_PROP_INTEGER_TOTAL+CHART_PROP_DOUBLE_TOTAL), // Chart comment text CHART_PROP_EXPERT_NAME, // Name of an EA launched on the chart CHART_PROP_SCRIPT_NAME, // Name of a script launched on the chart CHART_PROP_INDICATOR_NAME, // Name of an indicator launched on the chart CHART_PROP_SYMBOL, // Chart symbol }; #define CHART_PROP_STRING_TOTAL (5) // Total number of string properties //+------------------------------------------------------------------+
新しい定数を使用して列挙を特徴とするプロパティの数を変更しましょう。整数プロパティの数が62から67に増加し、文字列のプロパティの数が4から5に増加しました。
可能なチャートオブジェクトの並べ替え基準の列挙で、新しく追加されたプロパティに対応する新しい基準を追加します。
//+------------------------------------------------------------------+ //| Possible chart sorting criteria | //+------------------------------------------------------------------+ #define FIRST_CHART_DBL_PROP (CHART_PROP_INTEGER_TOTAL-CHART_PROP_INTEGER_SKIP) #define FIRST_CHART_STR_PROP (CHART_PROP_INTEGER_TOTAL-CHART_PROP_INTEGER_SKIP+CHART_PROP_DOUBLE_TOTAL-CHART_PROP_DOUBLE_SKIP) enum ENUM_SORT_CHART_MODE { //--- Sort by integer properties SORT_BY_CHART_SHOW = 0, // Sort by the price chart drawing attribute SORT_BY_CHART_IS_OBJECT, // Sort by chart object (OBJ_CHART) identification attribute SORT_BY_CHART_BRING_TO_TOP, // Sort by the flag of displaying a chart above all others SORT_BY_CHART_CONTEXT_MENU, // Sort by the flag of enabling/disabling access to the context menu using the right click SORT_BY_CHART_CROSSHAIR_TOO, // Sort by the flag of enabling/disabling access to the Crosshair tool using the middle click SORT_BY_CHART_MOUSE_SCROLL, // Sort by the flag of scrolling the chart horizontally using the left mouse button SORT_BY_CHART_EVENT_MOUSE_WHEEL, // Sort by the flag of sending messages about mouse wheel events to all MQL5 programs on a chart SORT_BY_CHART_EVENT_MOUSE_MOVE, // Sort by the flag of sending messages about mouse button click and movement events to all MQL5 programs on a chart SORT_BY_CHART_EVENT_OBJECT_CREATE, // Sort by the flag of sending messages about the graphical object creation event to all MQL5 programs on a chart SORT_BY_CHART_EVENT_OBJECT_DELETE, // Sort by the flag of sending messages about the graphical object destruction event to all MQL5 programs on a chart SORT_BY_CHART_MODE, // Sort by chart type SORT_BY_CHART_FOREGROUND, // Sort by the "Price chart in the foreground" flag SORT_BY_CHART_SHIFT, // Sort by the "Mode of shift of the price chart from the right border" flag SORT_BY_CHART_AUTOSCROLL, // Sort by the "The mode of automatic shift to the right border of the chart" flag SORT_BY_CHART_KEYBOARD_CONTROL, // Sort by the flag allowing the chart management using a keyboard SORT_BY_CHART_QUICK_NAVIGATION, // Sort by the flag allowing the chart to intercept Space and Enter key strokes to activate the quick navigation bar SORT_BY_CHART_SCALE, // Sort by scale SORT_BY_CHART_SCALEFIX, // Sort by the fixed scale flag SORT_BY_CHART_SCALEFIX_11, // Sort by the 1:1 scale flag SORT_BY_CHART_SCALE_PT_PER_BAR, // Sort by the flag of specifying the scale in points per bar SORT_BY_CHART_SHOW_TICKER, // Sort by the flag displaying a symbol ticker in the upper left corner SORT_BY_CHART_SHOW_OHLC, // Sort by the flag displaying OHLC values in the upper left corner SORT_BY_CHART_SHOW_BID_LINE, // Sort by the flag displaying Bid value as a horizontal line on the chart SORT_BY_CHART_SHOW_ASK_LINE, // Sort by the flag displaying Ask value as a horizontal line on the chart SORT_BY_CHART_SHOW_LAST_LINE, // Sort by the flag displaying Last value as a horizontal line on the chart SORT_BY_CHART_SHOW_PERIOD_SEP, // Sort by the flag displaying vertical separators between adjacent periods SORT_BY_CHART_SHOW_GRID, // Sort by the flag of displaying a grid on the chart SORT_BY_CHART_SHOW_VOLUMES, // Sort by the mode of displaying volumes on a chart SORT_BY_CHART_SHOW_OBJECT_DESCR, // Sort by the flag of displaying object text descriptions SORT_BY_CHART_VISIBLE_BARS, // Sort by the number of bars on a chart that are available for display SORT_BY_CHART_WINDOWS_TOTAL, // Sort by the total number of chart windows including indicator subwindows SORT_BY_CHART_WINDOW_IS_VISIBLE, // Sort by the subwindow visibility flag SORT_BY_CHART_WINDOW_HANDLE, // Sort by the chart handle SORT_BY_CHART_WINDOW_YDISTANCE, // Sort by the distance in Y axis pixels between the upper frame of the indicator subwindow and the upper frame of the chart main window SORT_BY_CHART_FIRST_VISIBLE_BAR, // Sort by the number of the first visible bar on the chart SORT_BY_CHART_WIDTH_IN_BARS, // Sort by the width of the chart in bars SORT_BY_CHART_WIDTH_IN_PIXELS, // Sort by the width of the chart in pixels SORT_BY_CHART_HEIGHT_IN_PIXELS, // Sort by the height of the chart in pixels SORT_BY_CHART_COLOR_BACKGROUND, // Sort by the color of the chart background SORT_BY_CHART_COLOR_FOREGROUND, // Sort by color of axes, scale and OHLC line SORT_BY_CHART_COLOR_GRID, // Sort by grid color SORT_BY_CHART_COLOR_VOLUME, // Sort by the color of volumes and position opening levels SORT_BY_CHART_COLOR_CHART_UP, // Sort by the color for the up bar, shadows and body borders of bull candlesticks SORT_BY_CHART_COLOR_CHART_DOWN, // Sort by the color of down bar, its shadow and border of body of the bullish candlestick SORT_BY_CHART_COLOR_CHART_LINE, // Sort by the color of the chart line and the Doji candlesticks SORT_BY_CHART_COLOR_CANDLE_BULL, // Sort by the color of a bullish candlestick body SORT_BY_CHART_COLOR_CANDLE_BEAR, // Sort by the color of a bearish candlestick body SORT_BY_CHART_COLOR_BID, // Sort by the color of the Bid price line SORT_BY_CHART_COLOR_ASK, // Sort by the color of the Ask price line SORT_BY_CHART_COLOR_LAST, // Sort by the color of the last performed deal's price line (Last) SORT_BY_CHART_COLOR_STOP_LEVEL, // Sort by the color of stop order levels (Stop Loss and Take Profit) SORT_BY_CHART_SHOW_TRADE_LEVELS, // Sort by the flag of displaying trading levels on the chart SORT_BY_CHART_DRAG_TRADE_LEVELS, // Sort by the flag enabling the ability to drag trading levels on a chart using mouse SORT_BY_CHART_SHOW_DATE_SCALE, // Sort by the flag of displaying the time scale on the chart SORT_BY_CHART_SHOW_PRICE_SCALE, // Sort by the flag of displaying the price scale on the chart SORT_BY_CHART_SHOW_ONE_CLICK, // Sort by the flag of displaying the quick trading panel on the chart SORT_BY_CHART_IS_MAXIMIZED, // Sort by the "Chart window maximized" flag SORT_BY_CHART_IS_MINIMIZED, // Sort by the "Chart window minimized" flag SORT_BY_CHART_IS_DOCKED, // Sort by the "Chart window docked" flag SORT_BY_CHART_FLOAT_LEFT, // Sort by the left coordinate of the undocked chart window relative to the virtual screen SORT_BY_CHART_FLOAT_TOP, // Sort by the upper coordinate of the undocked chart window relative to the virtual screen SORT_BY_CHART_FLOAT_RIGHT, // Sort by the right coordinate of the undocked chart window relative to the virtual screen SORT_BY_CHART_FLOAT_BOTTOM, // Sort by the bottom coordinate of the undocked chart window relative to the virtual screen SORT_BY_CHART_WINDOW_IND_HANDLE, // Sort by the indicator handle in the chart window SORT_BY_CHART_WINDOW_IND_INDEX, // Sort by the indicator index in the chart window //--- Sort by real properties SORT_BY_CHART_SHIFT_SIZE = FIRST_CHART_DBL_PROP, // Sort by the shift size of the zero bar from the right border in % SORT_BY_CHART_FIXED_POSITION, // Sort by the chart fixed position from the left border in % SORT_BY_CHART_FIXED_MAX, // Sort by the fixed chart maximum SORT_BY_CHART_FIXED_MIN, // Sort by the fixed chart minimum SORT_BY_CHART_POINTS_PER_BAR, // Sort by the scale value in points per bar SORT_BY_CHART_PRICE_MIN, // Sort by the chart minimum SORT_BY_CHART_PRICE_MAX, // Sort by the chart maximum //--- Sort by string properties SORT_BY_CHART_COMMENT = FIRST_CHART_STR_PROP, // Sort by a comment text on the chart SORT_BY_CHART_EXPERT_NAME, // Sort by a name of an EA launched on the chart SORT_BY_CHART_SCRIPT_NAME, // Sort by a name of a script launched on the chart SORT_BY_CHART_INDICATOR_NAME, // Sort by a name of an indicator launched on the chart SORT_BY_CHART_SYMBOL, // Sort by chart symbol }; //+------------------------------------------------------------------+
最初のチャートオブジェクトバージョンでは、コメントアウトされた整数チャートプロパティが並べ替え条件に追加され、銘柄名による並べ替えがなかったため、条件のリストが正しくありませんでした。本稿でこれを修正しました。
次に、チャートウィンドウの指標オブジェクトのクラスとチャートウィンドウオブジェクトのクラスの2つのクラスを作成する必要があります。それらを一度に1つのファイルに追加しましょう。
\MQL5\Include\DoEasy\Objects\Chart\で、CWndInd(チャートウィンドウの指標)およびCChartWnd(チャートウィンドウ)クラスの新しいファイルChartWnd.mqhを作成します。
CWndIndクラスはCObject標準ライブラリの基本クラス、CChartWndクラスはすべてのCBaseObjライブラリオブジェクトの基本オブジェクトから継承する必要があります。
チャートウィンドウにはさまざまな指標を添付できます。チャートウィンドウから必要な指標のハンドルを常に取得して操作できるためには。チャートウィンドウオブジェクトはそれらについて知っている必要があります。指標を識別するために多くの異なるパラメータは必要ありません。指標ハンドル、その短縮名、および指標が接続されているチャートウィンドウのインデックスで十分です。したがって、チャートウィンドウの指標オブジェクトクラスは最も単純なものになり、標準ライブラリの基本オブジェクトから継承されるため、これらすべてのオブジェクトをCArrayObjオブジェクトへのポインタのリストに追加できます。これは、チャートウィンドウオブジェクトにあります。
新しく作成したChartWnd.mqhファイルに新しいクラスのコードを書きます。
//+------------------------------------------------------------------+ //| ChartWnd.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 "..\..\Objects\BaseObj.mqh" //+------------------------------------------------------------------+ //| Chart window indicator object class | //+------------------------------------------------------------------+ class CWndInd : public CObject { private: long m_chart_id; // Chart ID string m_name; // Indicator short name int m_index; // Window index on the chart int m_handle; // Indicator handle public: //--- Return itself CWndInd *GetObject(void) { return &this; } //--- Return (1) indicator name, (2) window index and (3) indicator handle string Name(void) const { return this.m_name; } int Index(void) const { return this.m_index; } int Handle(void) const { return this.m_handle; } //--- Display the description of object properties in the journal (dash=true - hyphen before the description, false - description only) void Print(const bool dash=false) { ::Print((dash ? "- " : "")+this.Header()); } //--- Return the object short name string Header(void) const { return CMessage::Text(MSG_CHART_OBJ_INDICATOR)+" "+this.Name(); } //--- Compare CWndInd objects with each other by the specified property virtual int Compare(const CObject *node,const int mode=0) const; //--- Constructors CWndInd(void); CWndInd(const int handle,const string name,const int index) : m_handle(handle),m_name(name),m_index(index) {} }; //+------------------------------------------------------------------+ //| Compare CWndInd objects with each other by the specified property| //+------------------------------------------------------------------+ int CWndInd::Compare(const CObject *node,const int mode=0) const { const CWndInd *obj_compared=node; if(mode==CHART_PROP_WINDOW_IND_HANDLE) return(this.Handle()>obj_compared.Handle() ? 1 : this.Handle()<obj_compared.Handle() ? -1 : 0); else if(mode==CHART_PROP_WINDOW_IND_INDEX) return(this.Index()>obj_compared.Index() ? 1 : this.Index()<obj_compared.Index() ? -1 : 0); return(this.Name()==obj_compared.Name() ? 0 : this.Name()<obj_compared.Name() ? -1 : 1); } //+------------------------------------------------------------------+
チャートウィンドウの指標オブジェクトクラスはこれで全部です。
privateセクションには、格納されるクラスメンバー変数があります。
- 指標のあるウィンドウが配置されているチャートのID
- 指標の短縮名(チャートウィンドウでは指標はターミナルによって短縮名で識別されます)
- 指標が配置されているチャートウィンドウのインデックス(0 —メインチャートウィンドウ、1など—チャートサブウィンドウ)
- 指標ハンドル
このデータは、ウィンドウに接続されているすべての指標のリストをチャートウィンドウオブジェクトに保存するのに十分です。リスト自体にはオブジェクトが含まれているため、必要な指標を見つけて、さらに作業するためにそのハンドルを返すことができます。
上記の変数の値を返すpublicメソッドは自明です。他のいくつかのクラスメソッドについて考えてみましょう。
以下は、指標オブジェクトの短縮名を返すメソッドです。
//--- Return the object short name string Header(void) const { return CMessage::Text(MSG_CHART_OBJ_INDICATOR)+" "+this.Name(); }
このメソッドは、指標ヘッダーと指標の短縮名を返すだけです。
以下は、操作ログに指標オブジェクトプロパティの説明を表示するメソッドです。
//--- Display the description of object properties in the journal (dash=true - hyphen before the description, false - description only) void Print(const bool dash=false) { ::Print((dash ? "- " : "")+this.Header()); }
チャートウィンドウには複数の指標が表示される場合があるため、ヘッダー付きのリストとして表示されます。操作ログのリストをより視覚的に魅力的にするために、指標名の前にハイフンを使用します。メソッドの入力は、ハイフンを表示する必要があることを示します。
コンストラクタにはデフォルトとパラメトリックの2つがあります。デフォルトのコンストラクタは、ウィンドウに「空の」指標オブジェクトを作成するのに役立ちますが、チャートウィンドウオブジェクトクラスに指標のリストを作成するときにはメインクラスのコンストラクタとしてパラメトリックコンストラクタが使用されます。
パラメトリックコンストラクタは、指標ハンドル、その短縮名、および指標が配置されているサブウィンドウのインデックスを受け取ります 。
//--- Constructors CWndInd(void); CWndInd(const int handle,const string name,const int index) : m_handle(handle),m_name(name),m_index(index) {}
メソッドに渡されたすべてのパラメータ値は、初期化リストのクラス変数にすぐに割り当てられます。
以下は、指定されたプロパティによってチャートウィンドウ指標オブジェクトを比較するメソッドです。
//+------------------------------------------------------------------+ //| Compare CWndInd objects with each other by the specified property| //+------------------------------------------------------------------+ int CWndInd::Compare(const CObject *node,const int mode=0) const { const CWndInd *obj_compared=node; if(mode==CHART_PROP_WINDOW_IND_HANDLE) return(this.Handle()>obj_compared.Handle() ? 1 : this.Handle()<obj_compared.Handle() ? -1 : 0); else if(mode==CHART_PROP_WINDOW_IND_INDEX) return(this.Index()>obj_compared.Index() ? 1 : this.Index()<obj_compared.Index() ? -1 : 0); return(this.Name()==obj_compared.Name() ? 0 : this.Name()<obj_compared.Name() ? -1 : 1); } //+------------------------------------------------------------------+
このオブジェクトではプロパティのカスタム列挙はありません。そのすべてのプロパティは、チャートオブジェクトプロパティの列挙に存在します。したがって、メソッドは任意のチャートオブジェクトプロパティを受け取る可能性があります。ただし、渡されたプロパティによる比較は、モードが「指標ハンドル」プロパティまたは「チャートウィンドウインデックス」を受け取った場合にのみ実行されます。それ以外の場合、比較は指標の短縮名で実行されます。
比較メソッドは、すべてのライブラリオブジェクトの標準です。現在のオブジェクトのパラメータ値が比較対象の値を超えると1が返され、小さい場合は-1、その他の場合は0が返されます。
チャートウィンドウオブジェクトクラスの開発を始めましょう。
コードの開発を続け、チャートウィンドウの指標オブジェクトのクラスを含むファイル(ChartWnd.mqh)にチャートウィンドウオブジェクトクラスを記述します。クラスは、すべてのCBaseObjライブラリオブジェクトの基本オブジェクトから派生します。
//+------------------------------------------------------------------+ //| Chart window object class | //+------------------------------------------------------------------+ class CChartWnd : public CBaseObj { }
クラスのprivateセクションには、このウィンドウ内の指標オブジェクトへのポインタのリスト、オブジェクトによって記述されたサブウィンドウのインデックス、およびクラス操作の配置の追加メソッドが含まれます。
//+------------------------------------------------------------------+ //| Chart window object class | //+------------------------------------------------------------------+ class CChartWnd : public CBaseObj { private: CArrayObj m_list_ind; // Indicator list int m_window_num; // Subwindow index //--- Return the flag indicating the presence of an indicator from the list in the window bool IsPresentInWindow(const CWndInd *ind); //--- Remove indicators not present in the window from the list void IndicatorsDelete(void); //--- Add new indicators to the list void IndicatorsAdd(void); //--- Set a subwindow index void SetWindowNum(const int num) { this.m_window_num=num; } public:
クラスのpublicセクションには標準メソッドがあります(プロパティ値を設定するメソッドを除きます。オブジェクトにはカスタムプロパティ列挙リストがないため、チャートウィンドウに属するいくつかのチャートオブジェクトプロパティによって記述された必要な値のみを返します)。これらのメソッドについては、以前の記事で何度も説明しました。
さらに、このクラスには、ウィンドウプロパティ値を設定するメソッド、返すためのメソッド、クラスを操作するためのメソッドがあります。以下でさらに詳しく検討します。
//+------------------------------------------------------------------+ //| Chart window object class | //+------------------------------------------------------------------+ class CChartWnd : public CBaseObj { private: CArrayObj m_list_ind; // Indicator list int m_window_num; // Subwindow index //--- Return the flag indicating the presence of an indicator from the list in the window bool IsPresentInWindow(const CWndInd *ind); //--- Remove indicators not present in the window from the list void IndicatorsDelete(void); //--- Add new indicators to the list void IndicatorsAdd(void); //--- Set a subwindow index void SetWindowNum(const int num) { this.m_window_num=num; } public: //--- Return itself CChartWnd *GetObject(void) { return &this; } //--- Return the flag of the object supporting this property virtual bool SupportProperty(ENUM_CHART_PROP_INTEGER property) { return(property==CHART_PROP_WINDOW_YDISTANCE || property==CHART_PROP_HEIGHT_IN_PIXELS ? true : false); } virtual bool SupportProperty(ENUM_CHART_PROP_DOUBLE property) { return false; } virtual bool SupportProperty(ENUM_CHART_PROP_STRING property) { return (property==CHART_PROP_INDICATOR_NAME ? true : false); } //--- Get description of (1) integer, (2) real and (3) string properties string GetPropertyDescription(ENUM_CHART_PROP_INTEGER property); string GetPropertyDescription(ENUM_CHART_PROP_DOUBLE property) { return CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED); } string GetPropertyDescription(ENUM_CHART_PROP_STRING property) { return CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED); } //--- Display the description of object properties in the journal (full_prop=true - all properties, false - supported ones only) void Print(const bool full_prop=false); //--- Display a short description of the object in the journal virtual void PrintShort(const bool dash=false); //--- Return the object short name virtual string Header(void); //--- Compare CChartWnd objects by a specified property (to sort the list by an MQL5 signal object) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CChartWnd objects by all properties (to search for equal MQL5 signal objects) bool IsEqual(CChartWnd* compared_obj) const; //--- Constructors CChartWnd(void); CChartWnd(const long chart_id,const int wnd_num); //--- Return the distance in pixels between the window borders int YDistance(void) const { return (int)::ChartGetInteger(this.m_chart_id,CHART_WINDOW_YDISTANCE,this.m_window_num);} //--- (1) Return and (2) set the window height in pixels int HeightInPixels(void) const { return (int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_window_num);} bool SetHeightInPixels(const int value,const bool redraw=false); //--- Return (1) the subwindow index and (2) the number of indicators attached to the window int WindowNum(void) const { return this.m_window_num;} int IndicatorsTotal(void) const { return this.m_list_ind.Total(); } //--- Return (1) the indicator list and (2) the window indicator object from the list by index CArrayObj *GetIndicatorsList(void) { return &this.m_list_ind; } CWndInd *GetIndicator(const int index) { return this.m_list_ind.At(index); } //--- Display the description of indicators attached to the chart window in the journal void PrintIndicators(const bool dash=false); //--- Display the description of the window parameters in the journal void PrintParameters(const bool dash=false); //--- Create the list of indicators attached to the window void IndicatorsListCreate(void); //--- Update data on attached indicators void Refresh(void); }; //+------------------------------------------------------------------+
以下は、ウィンドウの境界間の距離をピクセル単位で返すメソッドです。
//--- Return the distance in pixels between the window borders int YDistance(void) const { return (int)::ChartGetInteger(this.m_chart_id,CHART_WINDOW_YDISTANCE,this.m_window_num);}
CHART_WINDOW_YDISTANCEチャートプロパティは読み取り専用であるため、ここで値を設定するメソッドはありません。このメソッドは、この特定のチャートサブウィンドウのプロパティの値を返すだけです。
以下は、ウィンドウの高さをピクセル単位で返すメソッドです。
int HeightInPixels(void) const { return (int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_window_num);}
このメソッドは上記のメソッドと同様に機能し、m_window_num変数で指定されたウィンドウのインデックスのプロパティ値を返します。
以下は、ウィンドウの高さをピクセル単位で設定するメソッド(クラス本体で宣言され、クラス本体の外部で実装されます)です。
//+------------------------------------------------------------------+ //| Set the window height in pixels | //+------------------------------------------------------------------+ bool CChartWnd::SetHeightInPixels(const int value,const bool redraw=false) { ::ResetLastError(); if(!::ChartSetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_window_num,value)) { CMessage::ToLog(DFUN,::GetLastError(),true); return false; } if(redraw) ::ChartRedraw(this.m_chart_id); return true; } //+------------------------------------------------------------------+
このメソッドは、前の記事で検討したグラフオブジェクトのプロパティの値を設定するメソッドと似ています。このメソッドは、設定に必要な値を受け取り、ChartSetInteger()関数を使用してそれをウィンドウに割り当てようとします。チャート変更イベントがキューに入れられていない場合は、そのことを通知してfalseを返します。イベントが正常にキューに入れられた場合は、redrawフラグをアクティブにしてチャートを事前に再描画することにより、trueを返します。チャートの強制的な再描画は、変更を表示するためにチャートイベント(見積もりの到着、サイズの変更、マウスクリックなど)を待つのを避けるために必要ですが、代わりにチャートを再描画して結果を確認します。
以下は、指定されたプロパティによってチャートウィンドウオブジェクトを比較するメソッドです。
//+------------------------------------------------------------------+ //| Compare CChartWnd objects with each other by a specified property| //+------------------------------------------------------------------+ int CChartWnd::Compare(const CObject *node,const int mode=0) const { const CChartWnd *obj_compared=node; if(mode==CHART_PROP_WINDOW_YDISTANCE) return(this.YDistance()>obj_compared.YDistance() ? 1 : this.YDistance()<obj_compared.YDistance() ? -1 : 0); else if(mode==CHART_PROP_HEIGHT_IN_PIXELS) return(this.HeightInPixels()>obj_compared.HeightInPixels() ? 1 : this.HeightInPixels()<obj_compared.HeightInPixels() ? -1 : 0); return -1; } //+------------------------------------------------------------------+
上記のチャートウィンドウ指標クラスで比較する方法と同様に、チャートオブジェクトプロパティの列挙で指定された一部のプロパティのみを比較します。
- 指標サブウィンドウの上部フレームとメインチャートウィンドウの上部フレームの間のY軸ピクセル単位の距離
- ピクセル単位のグラフの高さ
- それ以外の場合はすべて-1を返します
以下は、すべてのプロパティでチャートウィンドウオブジェクトを比較するメソッドです。
//+------------------------------------------------------------------+ //| Compare the CChartWnd objects by all properties | //+------------------------------------------------------------------+ bool CChartWnd::IsEqual(CChartWnd *compared_obj) const { return(this.YDistance()!=compared_obj.YDistance() || this.HeightInPixels()!=compared_obj.HeightInPixels() ? false : true); } //+------------------------------------------------------------------+
ここで、比較されたオブジェクトの2つのプロパティの少なくとも1つが不等式を返す場合、falseを返します(オブジェクトは等しくありません)。それ以外の場合は、trueを返します(オブジェクトは同一です)。
以下は、整数プロパティの説明を返すメソッドです。
//+------------------------------------------------------------------+ //| Return description of object's integer property | //+------------------------------------------------------------------+ string CChartWnd::GetPropertyDescription(ENUM_CHART_PROP_INTEGER property) { return ( property==CHART_PROP_WINDOW_YDISTANCE ? CMessage::Text(MSG_CHART_OBJ_WINDOW_YDISTANCE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.YDistance() ) : property==CHART_PROP_HEIGHT_IN_PIXELS ? CMessage::Text(MSG_CHART_OBJ_HEIGHT_IN_PIXELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.HeightInPixels() ) : "" ); } //+------------------------------------------------------------------+
メソッドに渡されるチャートウィンドウオブジェクトの整数プロパティに応じて、説明を含む文字列が作成されて返されます。
以下は、操作ログにオブジェクトのプロパティを表示するメソッドです。
//+------------------------------------------------------------------+ //| Display object properties in the journal | //+------------------------------------------------------------------+ void CChartWnd::Print(const bool full_prop=false) { ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") ============="); int beg=0, end=CHART_PROP_INTEGER_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_INTEGER prop=(ENUM_CHART_PROP_INTEGER)i; if(prop!=CHART_PROP_WINDOW_YDISTANCE && prop!=CHART_PROP_HEIGHT_IN_PIXELS) continue; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); beg=end; end+=CHART_PROP_DOUBLE_TOTAL; for(int i=beg; i<end; i++) { //ENUM_CHART_PROP_DOUBLE prop=(ENUM_CHART_PROP_DOUBLE)i; //if(!full_prop && !this.SupportProperty(prop)) continue; //::Print(this.GetPropertyDescription(prop)); } beg=end; end+=CHART_PROP_STRING_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_STRING prop=(ENUM_CHART_PROP_STRING)i; if(prop==CHART_PROP_INDICATOR_NAME) { this.PrintIndicators(); continue; } if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n"); } //+------------------------------------------------------------------+
すべてのチャートオブジェクトプロパティによる3つのループで、次のプロパティを受け取り、その説明を操作ログに表示します。チャートウィンドウオブジェクトにはそのプロパティのカスタム列挙リストがないため、チャートウィンドウオブジェクトに固有のチャートオブジェクトプロパティ(整数と文字列のプロパティ)のみを表示する必要があります。オブジェクトには実際のプロパティがないため、表示できません。各ループの開始と終了に厳密なフレームワークを設定することもできます... しかし、このようなソリューションは、チャートオブジェクトのプロパティを後で変更するという点では、オブジェクトに戻って各ループの開始と終了の値を編集する必要があるため、最適なソリューションではありません。したがって、単純にプロパティループを空にします(これは、将来チャートウィンドウオブジェクトにプロパティが必要になるまでの一時的なものである可能性があります)。したがって、プロパティの数を変更しても、各ループの開始と終了は常に正しいものになります。
以下は、チャートウィンドウオブジェクトの簡単な説明を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the object short name | //+------------------------------------------------------------------+ string CChartWnd::Header(void) { return(this.m_window_num==0 ? CMessage::Text(MSG_CHART_OBJ_CHART_WINDOW) : (string)this.WindowNum()+" "+CMessage::Text(MSG_CHART_OBJ_CHART_SUBWINDOW)); } //+------------------------------------------------------------------+
このメソッドはサブウィンドウのインデックスをチェックします。これがメインチャートウィンドウ(インデックス0)の場合、「Main chart window」文字列が返されます。メインのチャートサブウィンドウの場合、サブウィンドウインデックス+「Chart subwindow」文字列が返されます。
以下は、操作ログにチャートウィンドウオブジェクトの短い説明を表示するメソッドです。
//+------------------------------------------------------------------+ //| Display a short description of the object in the journal | //+------------------------------------------------------------------+ void CChartWnd::PrintShort(const bool dash=false) { ::Print((dash ? "- " : ""),this.Header()," ID: ",(string)this.GetChartID(),", ",CMessage::Text(MSG_CHART_OBJ_INDICATORS_TOTAL),": ",this.IndicatorsTotal()); } //+------------------------------------------------------------------+
ここでは、短いオブジェクト名、チャートID、ウィンドウに接続された指標の数で構成される文字列を作成します。メソッドがオブジェクトの説明の前にハイフンを表示する必要があることを示すフラグ(ダッシュ)を受け取った場合、作成された文字列の前にハイフンが表示されます。
以下は、操作ログのウィンドウに添付されているすべての指標の説明を表示するメソッドです。
//+------------------------------------------------------------------+ //| Display the description of indicators attached to the window | //+------------------------------------------------------------------+ void CChartWnd::PrintIndicators(const bool dash=false) { string header= ( this.WindowNum()==0 ? CMessage::Text(MSG_CHART_OBJ_INDICATORS_MW_NAME_LIST) : CMessage::Text(MSG_CHART_OBJ_INDICATORS_SW_NAME_LIST)+" "+(string)this.WindowNum() ); ::Print(header,":"); int total=this.IndicatorsTotal(); if(total==0) ::Print("- ",CMessage::Text(MSG_CHART_OBJ_INDICATORS_NONE)); else for(int i=0;i<total;i++) { CWndInd *ind=this.m_list_ind.At(i); if(ind==NULL) continue; ind.Print(dash); } } //+------------------------------------------------------------------+
まず、ウィンドウに一致するヘッダーを作成して操作ログに表示します。
これがメインチャートウィンドウの場合、ヘッダーテキストは「メインチャートウィンドウの指標」である必要があります。そうでない場合、ヘッダーテキストは「チャートウィンドウの指標」+ウィンドウインデックスになります。
次に、ウィンドウに接続される指標の数を定義します。そのような指標がない場合は、「No indicators」が表示されます。
それ以外の場合は、すべての指標のリストによるループで、チャートウィンドウで次の指標オブジェクトを取得し、そのデータを出力します。
以下は、操作ログでウィンドウパラメータの説明を表示するメソッドです。
//+------------------------------------------------------------------+ //| Display the description of the window parameters in the journal | //+------------------------------------------------------------------+ void CChartWnd::PrintParameters(const bool dash=false) { string header= ( this.WindowNum()==0 ? CMessage::Text(MSG_CHART_OBJ_CHART_WINDOW) : CMessage::Text(MSG_CHART_OBJ_CHART_SUBWINDOW)+" "+(string)this.WindowNum() ); ::Print((dash ? " " : ""),header,":"); if(this.WindowNum()>0) ::Print((dash ? " - " : ""),GetPropertyDescription(CHART_PROP_WINDOW_YDISTANCE)); ::Print((dash ? " - " : ""),GetPropertyDescription(CHART_PROP_HEIGHT_IN_PIXELS)); } //+------------------------------------------------------------------+
まず、ウィンドウに一致するヘッダーを作成して操作ログに表示します。
これがメインチャートウィンドウの場合、ヘッダーテキストは「Main chart window」である必要があります。それ以外の場合、ヘッダーテキストは「Chart subwindow」+ウィンドウインデックスになります。
これがチャートサブウィンドウの場合(インデックスがゼロを超える場合)、指標サブウィンドウの上部境界とメインチャートウィンドウの上部境界の間の垂直(Y軸)距離をピクセル単位で表示します ( メインウィンドウは常に0であり、表示されません)。次に、操作ログの2番目のオブジェクトプロパティ(ピクセル単位のチャートの高さ)を表示します。
以下は、ウィンドウに添付された指標のリストを作成するメソッドです。
//+------------------------------------------------------------------+ //| Create the list of indicators attached to the window | //+------------------------------------------------------------------+ void CChartWnd::IndicatorsListCreate(void) { //--- Clear the list of indicators this.m_list_ind.Clear(); //--- Get the total number of indicators in the window int total=::ChartIndicatorsTotal(this.m_chart_id,this.m_window_num); //--- In the loop by the number of indicators, for(int i=0;i<total;i++) { //--- obtain and save the short indicator name, string name=::ChartIndicatorName(this.m_chart_id,this.m_window_num,i); //--- get and save the indicator handle by its short name int handle=::ChartIndicatorGet(this.m_chart_id,this.m_window_num,name); //--- Free the indicator handle ::IndicatorRelease(handle); //--- Create the new indicator object in the chart window CWndInd *ind=new CWndInd(handle,name,i); if(ind==NULL) continue; //--- set the sorted list flag to the list this.m_list_ind.Sort(); //--- If failed to add the object to the list, remove it if(!this.m_list_ind.Add(ind)) delete ind; } } //+------------------------------------------------------------------+
メソッドはコードで詳細にコメントされています。ウィンドウ内の指標のリストを取得するとき、ChartIndicatorGetGet()を使用して短縮名で指標ハンドルを取得します。これにより、いくつかの「責任」が課せられます。ターミナルは、各指標の使用を追跡します。ハンドルを受け取るたびに、指標使用の内部カウンターが増加します。プログラムですでに不要な指標ハンドルを解放しないと、後で「失われた」ハンドルをキャッチすることができなくなります。そのため、必要な指標データをすべて取得したらすぐにハンドルを解放し、指標使用の内部カウンターを減らします。
以下は、リストに新しい指標を追加するメソッドです。
//+------------------------------------------------------------------+ //| Add new indicators to the list | //+------------------------------------------------------------------+ void CChartWnd::IndicatorsAdd(void) { //--- Get the total number of indicators in the window int total=::ChartIndicatorsTotal(this.m_chart_id,this.m_window_num); //--- In the loop by the number of indicators, for(int i=0;i<total;i++) { //--- obtain and save the short indicator name, string name=::ChartIndicatorName(this.m_chart_id,this.m_window_num,i); //--- get and save the indicator handle by its short name int handle=::ChartIndicatorGet(this.m_chart_id,this.m_window_num,name); //--- Release the indicator handle ::IndicatorRelease(handle); //--- Create the new indicator object in the chart window CWndInd *ind=new CWndInd(handle,name,i); if(ind==NULL) continue; //--- set the sorted list flag to the list this.m_list_ind.Sort(); //--- If the object is already in the list or an attempt to add it to the list failed, remove it if(this.m_list_ind.Search(ind)>WRONG_VALUE || !this.m_list_ind.Add(ind)) delete ind; } } //+------------------------------------------------------------------+
メソッドロジックは、上記で検討したものと同じです。コードにもコメントがあります。唯一の違いは、リストが最初にメソッドでクリアされないことです。指標がリストに追加されると、リスト内のそのような指標の存在が最初に確認されます。すでに存在する場合、指標オブジェクトは削除されます。
ウィンドウ内の指標のリストを実際の数と同期できるようにするには(結局のところ指標をウィンドウに追加したり、チャートウィンドウから削除したりできます)、ウィンドウ内の指標の数をリスト内の数と比較する必要があります。これは後続の記事で行います。
ただし、ターミナルウィンドウのリストから指標の存在を返すメソッドは実装します。
//+--------------------------------------------------------------------------------------+ //| Return the flag indicating the presence of an indicator from the list in the window | //+--------------------------------------------------------------------------------------+ bool CChartWnd::IsPresentInWindow(const CWndInd *ind) { int total=::ChartIndicatorsTotal(this.m_chart_id,this.m_window_num); for(int i=0;i<total;i++) { string name=::ChartIndicatorName(this.m_chart_id,this.m_window_num,i); int handle=::ChartIndicatorGet(this.m_chart_id,this.m_window_num,name); ::IndicatorRelease(handle); if(ind.Name()==name && ind.Handle()==handle) return true; } return false; } //+------------------------------------------------------------------+
このメソッドは、実際の存在を確認する必要があるチャートウィンドウ内の指標オブジェクトへのポインタを受け取ります。次に、チャートウィンドウ内の指標の総数によるループ内、次の指標の名前を取得、ハンドルを取得、すぐにリリースします。現在の指標の短縮名とハンドルがチェックされたオブジェクトのものと一致する場合は、trueを返します。指標は引き続きチャートウィンドウに表示されます。ループが完了した場合はfalseを返します。一致が見つからないため、チャートウィンドウにそのような指標がありません。
リストに含まれているチャートに存在しない指標は、リストから削除する必要があります。
以下は、ウィンドウに存在しない指標をリストから削除するメソッドです。
//+------------------------------------------------------------------+ //| Remove indicators not present in the window from the list | //+------------------------------------------------------------------+ void CChartWnd::IndicatorsDelete(void) { int total=this.m_list_ind.Total(); for(int i=total-1;i>WRONG_VALUE;i--) { CWndInd *ind=this.m_list_ind.At(i); if(!this.IsPresentInWindow(ind)) this.m_list_ind.Delete(i); } } //+------------------------------------------------------------------+
ここで、指標オブジェクトのリストによるループでループインデックスによる次の指標オブジェクトを取得し、実際のチャートウィンドウでその存在を確認します。存在しない場合は、Delete()メソッドを使用してリストからそのポインタを削除します。
後で、チャートコレクションクラスを実装するときに、すべてのチャートオブジェクトのサブウィンドウで指標のステータスを追跡する必要があります。チャートサブウィンドウの実際の数の指標とチャートウィンドウオブジェクトのリストの説明が一致しない場合は、リストから不要な指標を削除し、可能な場合は新しい指標を追加する必要があります。
これを実現するために、チャートウィンドウに接続された指標のデータを更新するメソッドを作成します。
//+------------------------------------------------------------------+ //| Update data on attached indicators | //+------------------------------------------------------------------+ void CChartWnd::Refresh(void) { this.IndicatorsDelete(); this.IndicatorsAdd(); } //+------------------------------------------------------------------+
ここでは、最初に実際のチャートウィンドウに存在しない指標を検出し、リストから削除します。次に、上記のメソッドを使用して、ウィンドウには存在するがリストには存在しない新しい指標を検索して追加します。
最後に、パラメトリッククラスコンストラクタについて考えてみましょう。
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CChartWnd::CChartWnd(const long chart_id,const int wnd_num) : m_window_num(wnd_num) { CBaseObj::SetChartID(chart_id); this.IndicatorsListCreate(); } //+------------------------------------------------------------------+
ここでは、最初にCBaseObj親オブジェクトチャートIDを設定します。次に、チャートウィンドウに添付された指標のリストを作成します。チャートサブウィンドウインデックスは、コンストラクタ初期化リストで設定されます。
これで、チャートウィンドウとチャートウィンドウオブジェクトでの指標オブジェクトクラスの作成は完了です。
両方のクラスの完全なコードは1つのファイルにあり、以下に添付されているファイルで確認できます。
チャートウィンドウとそのサブウィンドウを説明するオブジェクトができたので、\MQL5\Include\DoEasy\Objects\Chart\ChartObj.mqhチャートオブジェクトクラスを改善するときが来ました。 これで、メインウィンドウにすべてのサブウィンドウのリストが表示されます。ウィンドウのプロパティを取得するには、上記で作成した必要なチャートウィンドウオブジェクトへのポインタを参照する必要があります。取得したウィンドウオブジェクトから、それに接続されているすべてのインジケーターのリストを取得できます。次に、その指標から、それを操作するために必要なインジケーターのハンドルを受け取ることができます。
まずウィンドウ内のウィンドウオブジェクトと指標のファイルをチャートオブジェクトファイルに含め、すべてのチャートオブジェクトウィンドウへのポインタを格納するリストオブジェクトを宣言します。
//+------------------------------------------------------------------+ //| ChartObj.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 "..\..\Objects\BaseObj.mqh" #include "ChartWnd.mqh" //+------------------------------------------------------------------+ //| Chart object class | //+------------------------------------------------------------------+ class CChartObj : public CBaseObj { private: CArrayObj m_list_wnd; // List of chart window objects long m_long_prop[CHART_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[CHART_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[CHART_PROP_STRING_TOTAL]; // String properties int m_digits; // Symbol's Digits()
クラスのprivateセクションのプロパティ値を設定するためのメソッドのリストで、チャートウィンドウの可視性を設定するメソッドを追加します。
//--- The methods of setting property values bool SetMode(const string source,const ENUM_CHART_MODE mode,const bool redraw=false); bool SetScale(const string source,const int scale,const bool redraw=false); bool SetModeVolume(const string source,const ENUM_CHART_VOLUME_MODE mode,const bool redraw=false); void SetVisibleBars(void); void SetWindowsTotal(void); void SetVisible(void); void SetFirstVisibleBars(void); void SetWidthInBars(void); void SetWidthInPixels(void); void SetMaximizedFlag(void); void SetMinimizedFlag(void); void SetExpertName(void); void SetScriptName(void); public:
「指標サブウィンドウの上部フレームとチャートメインウィンドウの上部フレームの間のY軸ピクセル単位の距離」プロパティはメインウィンドウには適用されないため(常に0)、これが整数プロパティをサポートするオブジェクトのフラグを返すメソッドのCHART_PROP_WINDOW_YDISTANCEプロパティである場合は、戻り値を変更します。
//--- Return the flag of the object supporting this property virtual bool SupportProperty(ENUM_CHART_PROP_INTEGER property) { return (property!=CHART_PROP_WINDOW_YDISTANCE ? true : false); } virtual bool SupportProperty(ENUM_CHART_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_CHART_PROP_STRING property) { return true; }
メソッドに渡されたプロパティがCHART_PROP_WINDOW_YDISTANCEと等しくない場合はtrueを返し、それ以外の場合はfalseを返します。
オブジェクトのプロパティに簡単にアクセスするためのメソッドのリストで、ウィンドウの可視性を返すメソッドを追加します。
//--- Return the total number of chart windows including indicator subwindows int WindowsTotal(void) const { return (int)this.GetProperty(CHART_PROP_WINDOWS_TOTAL); } //--- Return the window visibility bool Visible(void) const { return (bool)this.GetProperty(CHART_PROP_WINDOW_IS_VISIBLE); } //--- Return the chart window handle int Handle(void) const { return (int)this.GetProperty(CHART_PROP_WINDOW_HANDLE); }
ここでのメソッドは、メインのチャートウィンドウのみのプロパティを返すことです。
指標サブウィンドウの上部フレームとチャートのメインウィンドウの上部フレームの間の距離をY軸ピクセルで返すメソッド、および指定されたチャートの高さをピクセルで返すメソッドと設定するメソッドが変更されました。次に、これらのプロパティを設定および返すために必要なウィンドウオブジェクトを見つけて、オブジェクトプロパティでこれらの値を設定または取得する必要があります。メソッドの実装については、少し後で検討します。
//--- Return the name of a script launched on the chart string ScriptName(void) const { return this.GetProperty(CHART_PROP_SCRIPT_NAME); } //--- Return the distance in Y axis pixels between the upper frame of the indicator subwindow and the upper frame of the chart main window int WindowYDistance(const int sub_window) const; //--- (1) Return and (2) set the height of the specified chart in pixels int WindowHeightInPixels(const int sub_window) const; bool SetWindowHeightInPixels(const int height,const int sub_window,const bool redraw=false); //--- Return the specified subwindow visibility
クラス本体の一番下で、必要なウィンドウオブジェクトを受け取り、操作ログ内の指定されたチャートウィンドウに接続されたすべてのチャートサブウィンドウのプロパティとすべての指標のデータを表示するための追加のメソッドを宣言します。
//--- Emulate a tick (chart updates - similar to the terminal Refresh command) void EmulateTick(void) { ::ChartSetSymbolPeriod(this.ID(),this.Symbol(),this.Timeframe());} //--- Return the chart window specified by index CChartWnd *GetWindowByIndex(const int index) const { return this.m_list_wnd.At(index); } //--- Return the window object by its subwindow index CChartWnd *GetWindowByNum(const int win_num) const; //--- Display data of all indicators of all chart windows in the journal void PrintWndIndicators(void); //--- Display the properties of all chart windows in the journal void PrintWndParameters(void); }; //+------------------------------------------------------------------+
パラメトリッククラスコンストラクタで、クラスの親オブジェクトにチャートIDを設定し、チャートオブジェクトの3つのメインウィンドウプロパティを指定します(これは メインウィンドウオブジェクトがすべてのグラフウィンドウのリストに配置されているため、事実上不要ですが、オブジェクトにはそのようなプロパティがあるため、正しいデータを入力します。メソッドの最後で、チャートに属するすべてのウィンドウオブジェクトをすべてのチャートウィンドウのリストに追加します。
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CChartObj::CChartObj(const long chart_id) { //--- Set chart ID to the base object CBaseObj::SetChartID(chart_id); //--- Set integer properties this.SetProperty(CHART_PROP_ID,chart_id); // Chart ID this.SetProperty(CHART_PROP_TIMEFRAME,::ChartPeriod(this.ID())); // Chart timeframe this.SetProperty(CHART_PROP_SHOW,::ChartGetInteger(this.ID(),CHART_SHOW)); // Price chart drawing attribute this.SetProperty(CHART_PROP_IS_OBJECT,::ChartGetInteger(this.ID(),CHART_IS_OBJECT)); // Chart object identification attribute this.SetProperty(CHART_PROP_BRING_TO_TOP,false); // Show chart above all others this.SetProperty(CHART_PROP_CONTEXT_MENU,::ChartGetInteger(this.ID(),CHART_CONTEXT_MENU)); // Access to the context menu using the right click this.SetProperty(CHART_PROP_CROSSHAIR_TOOL,::ChartGetInteger(this.ID(),CHART_CROSSHAIR_TOOL)); // Access the Crosshair tool by pressing the middle mouse button this.SetProperty(CHART_PROP_MOUSE_SCROLL,::ChartGetInteger(this.ID(),CHART_MOUSE_SCROLL)); // Scroll the chart horizontally using the left mouse button this.SetProperty(CHART_PROP_EVENT_MOUSE_WHEEL,::ChartGetInteger(this.ID(),CHART_EVENT_MOUSE_WHEEL)); // Send messages about mouse wheel events to all MQL5 programs on a chart this.SetProperty(CHART_PROP_EVENT_MOUSE_MOVE,::ChartGetInteger(this.ID(),CHART_EVENT_MOUSE_MOVE)); // Send messages about mouse button click and movement events to all MQL5 programs on a chart this.SetProperty(CHART_PROP_EVENT_OBJECT_CREATE,::ChartGetInteger(this.ID(),CHART_EVENT_OBJECT_CREATE)); // Send messages about the graphical object creation event to all MQL5 programs on a chart this.SetProperty(CHART_PROP_EVENT_OBJECT_DELETE,::ChartGetInteger(this.ID(),CHART_EVENT_OBJECT_DELETE)); // Send messages about the graphical object destruction event to all MQL5 programs on a chart this.SetProperty(CHART_PROP_MODE,::ChartGetInteger(this.ID(),CHART_MODE)); // Type of the chart (candlesticks, bars or line) this.SetProperty(CHART_PROP_FOREGROUND,::ChartGetInteger(this.ID(),CHART_FOREGROUND)); // Price chart in the foreground this.SetProperty(CHART_PROP_SHIFT,::ChartGetInteger(this.ID(),CHART_SHIFT)); // Mode of shift of the price chart from the right border this.SetProperty(CHART_PROP_AUTOSCROLL,::ChartGetInteger(this.ID(),CHART_AUTOSCROLL)); // The mode of automatic shift to the right border of the chart this.SetProperty(CHART_PROP_KEYBOARD_CONTROL,::ChartGetInteger(this.ID(),CHART_KEYBOARD_CONTROL)); // Allow managing the chart using a keyboard this.SetProperty(CHART_PROP_QUICK_NAVIGATION,::ChartGetInteger(this.ID(),CHART_QUICK_NAVIGATION)); // Allow the chart to intercept Space and Enter key strokes to activate the quick navigation bar this.SetProperty(CHART_PROP_SCALE,::ChartGetInteger(this.ID(),CHART_SCALE)); // Scale this.SetProperty(CHART_PROP_SCALEFIX,::ChartGetInteger(this.ID(),CHART_SCALEFIX)); // Fixed scale mode this.SetProperty(CHART_PROP_SCALEFIX_11,::ChartGetInteger(this.ID(),CHART_SCALEFIX_11)); // 1:1 scale mode this.SetProperty(CHART_PROP_SCALE_PT_PER_BAR,::ChartGetInteger(this.ID(),CHART_SCALE_PT_PER_BAR)); // Mode for specifying the scale in points per bar this.SetProperty(CHART_PROP_SHOW_TICKER,::ChartGetInteger(this.ID(),CHART_SHOW_TICKER)); // Display a symbol ticker in the upper left corner this.SetProperty(CHART_PROP_SHOW_OHLC,::ChartGetInteger(this.ID(),CHART_SHOW_OHLC)); // Display OHLC values in the upper left corner this.SetProperty(CHART_PROP_SHOW_BID_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_BID_LINE)); // Display Bid value as a horizontal line on the chart this.SetProperty(CHART_PROP_SHOW_ASK_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_ASK_LINE)); // Display Ask value as a horizontal line on the chart this.SetProperty(CHART_PROP_SHOW_LAST_LINE,::ChartGetInteger(this.ID(),CHART_SHOW_LAST_LINE)); // Display Last value as a horizontal line on the chart this.SetProperty(CHART_PROP_SHOW_PERIOD_SEP,::ChartGetInteger(this.ID(),CHART_SHOW_PERIOD_SEP)); // Display vertical separators between adjacent periods this.SetProperty(CHART_PROP_SHOW_GRID,::ChartGetInteger(this.ID(),CHART_SHOW_GRID)); // Display the chart grid this.SetProperty(CHART_PROP_SHOW_VOLUMES,::ChartGetInteger(this.ID(),CHART_SHOW_VOLUMES)); // Display volumes on the chart this.SetProperty(CHART_PROP_SHOW_OBJECT_DESCR,::ChartGetInteger(this.ID(),CHART_SHOW_OBJECT_DESCR)); // Display text descriptions of the objects this.SetProperty(CHART_PROP_VISIBLE_BARS,::ChartGetInteger(this.ID(),CHART_VISIBLE_BARS)); // Number of bars on a chart that are available for display this.SetProperty(CHART_PROP_WINDOWS_TOTAL,::ChartGetInteger(this.ID(),CHART_WINDOWS_TOTAL)); // The total number of chart windows including indicator subwindows this.SetProperty(CHART_PROP_WINDOW_IS_VISIBLE,::ChartGetInteger(this.ID(),CHART_WINDOW_IS_VISIBLE,0));// Window visibility this.SetProperty(CHART_PROP_WINDOW_HANDLE,::ChartGetInteger(this.ID(),CHART_WINDOW_HANDLE)); // Chart window handle this.SetProperty(CHART_PROP_WINDOW_YDISTANCE,::ChartGetInteger(this.ID(),CHART_WINDOW_YDISTANCE,0)); // Distance in Y axis pixels between the upper frame of the indicator subwindow and the upper frame of the chart main window this.SetProperty(CHART_PROP_FIRST_VISIBLE_BAR,::ChartGetInteger(this.ID(),CHART_FIRST_VISIBLE_BAR)); // Number of the first visible bar on the chart this.SetProperty(CHART_PROP_WIDTH_IN_BARS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_BARS)); // Chart width in bars this.SetProperty(CHART_PROP_WIDTH_IN_PIXELS,::ChartGetInteger(this.ID(),CHART_WIDTH_IN_PIXELS)); // Chart width in pixels this.SetProperty(CHART_PROP_HEIGHT_IN_PIXELS,::ChartGetInteger(this.ID(),CHART_HEIGHT_IN_PIXELS,0)); // Chart height in pixels this.SetProperty(CHART_PROP_COLOR_BACKGROUND,::ChartGetInteger(this.ID(),CHART_COLOR_BACKGROUND)); // Chart background color this.SetProperty(CHART_PROP_COLOR_FOREGROUND,::ChartGetInteger(this.ID(),CHART_COLOR_FOREGROUND)); // Color of axes, scale and OHLC line this.SetProperty(CHART_PROP_COLOR_GRID,::ChartGetInteger(this.ID(),CHART_COLOR_GRID)); // Grid color this.SetProperty(CHART_PROP_COLOR_VOLUME,::ChartGetInteger(this.ID(),CHART_COLOR_VOLUME)); // Color of volumes and position opening levels this.SetProperty(CHART_PROP_COLOR_CHART_UP,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_UP)); // Color for the up bar, shadows and body borders of bullish candlesticks this.SetProperty(CHART_PROP_COLOR_CHART_DOWN,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_DOWN)); // Color for the down bar, shadows and body borders of bearish candlesticks this.SetProperty(CHART_PROP_COLOR_CHART_LINE,::ChartGetInteger(this.ID(),CHART_COLOR_CHART_LINE)); // Color of the chart line and the Doji candlesticks this.SetProperty(CHART_PROP_COLOR_CANDLE_BULL,::ChartGetInteger(this.ID(),CHART_COLOR_CANDLE_BULL)); // Color of the bullish candle body this.SetProperty(CHART_PROP_COLOR_CANDLE_BEAR,::ChartGetInteger(this.ID(),CHART_COLOR_CANDLE_BEAR)); // Color of the bearish candle body this.SetProperty(CHART_PROP_COLOR_BID,::ChartGetInteger(this.ID(),CHART_COLOR_BID)); // Bid price line color this.SetProperty(CHART_PROP_COLOR_ASK,::ChartGetInteger(this.ID(),CHART_COLOR_ASK)); // Ask price line color this.SetProperty(CHART_PROP_COLOR_LAST,::ChartGetInteger(this.ID(),CHART_COLOR_LAST)); // Color of the last performed deal's price line (Last) this.SetProperty(CHART_PROP_COLOR_STOP_LEVEL,::ChartGetInteger(this.ID(),CHART_COLOR_STOP_LEVEL)); // Color of stop order levels (Stop Loss and Take Profit) this.SetProperty(CHART_PROP_SHOW_TRADE_LEVELS,::ChartGetInteger(this.ID(),CHART_SHOW_TRADE_LEVELS)); // Display trade levels on the chart (levels of open positions, Stop Loss, Take Profit and pending orders) this.SetProperty(CHART_PROP_DRAG_TRADE_LEVELS,::ChartGetInteger(this.ID(),CHART_DRAG_TRADE_LEVELS)); // Enable the ability to drag trading levels on a chart using mouse this.SetProperty(CHART_PROP_SHOW_DATE_SCALE,::ChartGetInteger(this.ID(),CHART_SHOW_DATE_SCALE)); // Display the time scale on the chart this.SetProperty(CHART_PROP_SHOW_PRICE_SCALE,::ChartGetInteger(this.ID(),CHART_SHOW_PRICE_SCALE)); // Display the price scale on the chart this.SetProperty(CHART_PROP_SHOW_ONE_CLICK,::ChartGetInteger(this.ID(),CHART_SHOW_ONE_CLICK)); // Display the quick trading panel on the chart this.SetProperty(CHART_PROP_IS_MAXIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MAXIMIZED)); // Chart window maximized this.SetProperty(CHART_PROP_IS_MINIMIZED,::ChartGetInteger(this.ID(),CHART_IS_MINIMIZED)); // Chart window minimized this.SetProperty(CHART_PROP_IS_DOCKED,::ChartGetInteger(this.ID(),CHART_IS_DOCKED)); // Chart window docked this.SetProperty(CHART_PROP_FLOAT_LEFT,::ChartGetInteger(this.ID(),CHART_FLOAT_LEFT)); // Left coordinate of the undocked chart window relative to the virtual screen this.SetProperty(CHART_PROP_FLOAT_TOP,::ChartGetInteger(this.ID(),CHART_FLOAT_TOP)); // Upper coordinate of the undocked chart window relative to the virtual screen this.SetProperty(CHART_PROP_FLOAT_RIGHT,::ChartGetInteger(this.ID(),CHART_FLOAT_RIGHT)); // Right coordinate of the undocked chart window relative to the virtual screen this.SetProperty(CHART_PROP_FLOAT_BOTTOM,::ChartGetInteger(this.ID(),CHART_FLOAT_BOTTOM)); // Bottom coordinate of the undocked chart window relative to the virtual screen //--- Set real properties this.SetProperty(CHART_PROP_SHIFT_SIZE,::ChartGetDouble(this.ID(),CHART_SHIFT_SIZE)); // Shift size of the zero bar from the right border in % this.SetProperty(CHART_PROP_FIXED_POSITION,::ChartGetDouble(this.ID(),CHART_FIXED_POSITION)); // Chart fixed position from the left border in % this.SetProperty(CHART_PROP_FIXED_MAX,::ChartGetDouble(this.ID(),CHART_FIXED_MAX)); // Fixed chart maximum this.SetProperty(CHART_PROP_FIXED_MIN,::ChartGetDouble(this.ID(),CHART_FIXED_MIN)); // Fixed chart minimum this.SetProperty(CHART_PROP_POINTS_PER_BAR,::ChartGetDouble(this.ID(),CHART_POINTS_PER_BAR)); // Scale in points per bar this.SetProperty(CHART_PROP_PRICE_MIN,::ChartGetDouble(this.ID(),CHART_PRICE_MIN)); // Chart minimum this.SetProperty(CHART_PROP_PRICE_MAX,::ChartGetDouble(this.ID(),CHART_PRICE_MAX)); // Chart maximum //--- Set string properties this.SetProperty(CHART_PROP_COMMENT,::ChartGetString(this.ID(),CHART_COMMENT)); // Comment text on the chart this.SetProperty(CHART_PROP_EXPERT_NAME,::ChartGetString(this.ID(),CHART_EXPERT_NAME)); // name of an EA launched on the chart this.SetProperty(CHART_PROP_SCRIPT_NAME,::ChartGetString(this.ID(),CHART_SCRIPT_NAME)); // name of a script launched on the chart this.SetProperty(CHART_PROP_SYMBOL,::ChartSymbol(this.ID())); // Chart symbol this.m_digits=(int)::SymbolInfoInteger(this.Symbol(),SYMBOL_DIGITS); int total=this.WindowsTotal(); for(int i=0;i<total;i++) { CChartWnd *wnd=new CChartWnd(m_chart_id,i); if(wnd==NULL) continue; m_list_wnd.Sort(); if(!m_list_wnd.Add(wnd)) delete wnd; } } //+------------------------------------------------------------------+
チャートウィンドウリストを作成するには、すべてのチャートウィンドウの総数を取得します。すべてのウィンドウによるループで、新しいチャートウィンドウオブジェクトを作成し、リストに追加します。
前の記事で開発された2つのチャートオブジェクトを比較するメソッドに論理的な誤りがありました。各チャートには一意のチャートIDとウィンドウハンドルがあるため、これら2つのプロパティで比較すると、常にfalseが返されます。ただし、このメソッドの目的は、チャートが一致することを確認することですが、IDとハンドルを比較すると、常に同一ではないことが示されます。
比較中にこれら2つのプロパティをスキップして、これを修正しましょう。
//+------------------------------------------------------------------+ //| Compare the CChartObj objects by all properties | //+------------------------------------------------------------------+ bool CChartObj::IsEqual(CChartObj *compared_obj) const { int beg=0, end=CHART_PROP_INTEGER_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_INTEGER prop=(ENUM_CHART_PROP_INTEGER)i; if(prop==CHART_PROP_ID || prop==CHART_PROP_WINDOW_HANDLE) continue; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } beg=end; end+=CHART_PROP_DOUBLE_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_DOUBLE prop=(ENUM_CHART_PROP_DOUBLE)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } beg=end; end+=CHART_PROP_STRING_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_STRING prop=(ENUM_CHART_PROP_STRING)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } return true; } //+------------------------------------------------------------------+
整数オブジェクトプロパティの説明を返すメソッドで、追加された3つのプロパティの説明を返すようにします。
//+------------------------------------------------------------------+ //| Return description of object's integer property | //+------------------------------------------------------------------+ string CChartObj::GetPropertyDescription(ENUM_CHART_PROP_INTEGER property) { return ( property==CHART_PROP_ID ? CMessage::Text(MSG_CHART_OBJ_ID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_TIMEFRAME ? CMessage::Text(MSG_LIB_TEXT_BAR_PERIOD)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+TimeframeDescription((ENUM_TIMEFRAMES)this.GetProperty(property)) ) : property==CHART_PROP_SHOW ? CMessage::Text(MSG_CHART_OBJ_SHOW)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_OBJECT ? CMessage::Text(MSG_CHART_OBJ_IS_OBJECT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_BRING_TO_TOP ? CMessage::Text(MSG_CHART_OBJ_BRING_TO_TOP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_CONTEXT_MENU ? CMessage::Text(MSG_CHART_OBJ_CONTEXT_MENU)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_CROSSHAIR_TOOL ? CMessage::Text(MSG_CHART_OBJ_CROSSHAIR_TOOL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_MOUSE_SCROLL ? CMessage::Text(MSG_CHART_OBJ_MOUSE_SCROLL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_MOUSE_WHEEL ? CMessage::Text(MSG_CHART_OBJ_EVENT_MOUSE_WHEEL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_MOUSE_MOVE ? CMessage::Text(MSG_CHART_OBJ_EVENT_MOUSE_MOVE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_OBJECT_CREATE ? CMessage::Text(MSG_CHART_OBJ_EVENT_OBJECT_CREATE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_EVENT_OBJECT_DELETE ? CMessage::Text(MSG_CHART_OBJ_EVENT_OBJECT_DELETE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_MODE ? CMessage::Text(MSG_CHART_OBJ_MODE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ChartModeDescription((ENUM_CHART_MODE)this.GetProperty(property)) ) : property==CHART_PROP_FOREGROUND ? CMessage::Text(MSG_CHART_OBJ_FOREGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHIFT ? CMessage::Text(MSG_CHART_OBJ_SHIFT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_AUTOSCROLL ? CMessage::Text(MSG_CHART_OBJ_AUTOSCROLL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_KEYBOARD_CONTROL ? CMessage::Text(MSG_CHART_OBJ_KEYBOARD_CONTROL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_QUICK_NAVIGATION ? CMessage::Text(MSG_CHART_OBJ_QUICK_NAVIGATION)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALE ? CMessage::Text(MSG_CHART_OBJ_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_SCALEFIX ? CMessage::Text(MSG_CHART_OBJ_SCALEFIX)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALEFIX_11 ? CMessage::Text(MSG_CHART_OBJ_SCALEFIX_11)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SCALE_PT_PER_BAR ? CMessage::Text(MSG_CHART_OBJ_SCALE_PT_PER_BAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_TICKER ? CMessage::Text(MSG_CHART_OBJ_SHOW_TICKER)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_OHLC ? CMessage::Text(MSG_CHART_OBJ_SHOW_OHLC)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_BID_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_BID_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_ASK_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_ASK_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_LAST_LINE ? CMessage::Text(MSG_CHART_OBJ_SHOW_LAST_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_PERIOD_SEP ? CMessage::Text(MSG_CHART_OBJ_SHOW_PERIOD_SEP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_GRID ? CMessage::Text(MSG_CHART_OBJ_SHOW_GRID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_VOLUMES ? CMessage::Text(MSG_CHART_OBJ_SHOW_VOLUMES)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ChartModeVolumeDescription((ENUM_CHART_VOLUME_MODE)this.GetProperty(property)) ) : property==CHART_PROP_SHOW_OBJECT_DESCR ? CMessage::Text(MSG_CHART_OBJ_SHOW_OBJECT_DESCR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_VISIBLE_BARS ? CMessage::Text(MSG_CHART_OBJ_VISIBLE_BARS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WINDOWS_TOTAL ? CMessage::Text(MSG_CHART_OBJ_WINDOWS_TOTAL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WINDOW_IS_VISIBLE ? CMessage::Text(MSG_CHART_OBJ_WINDOW_IS_VISIBLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_WINDOW_HANDLE ? CMessage::Text(MSG_CHART_OBJ_WINDOW_HANDLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WINDOW_YDISTANCE ? CMessage::Text(MSG_CHART_OBJ_WINDOW_YDISTANCE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FIRST_VISIBLE_BAR ? CMessage::Text(MSG_CHART_OBJ_FIRST_VISIBLE_BAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WIDTH_IN_BARS ? CMessage::Text(MSG_CHART_OBJ_WIDTH_IN_BARS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_WIDTH_IN_PIXELS ? CMessage::Text(MSG_CHART_OBJ_WIDTH_IN_PIXELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_HEIGHT_IN_PIXELS ? CMessage::Text(MSG_CHART_OBJ_HEIGHT_IN_PIXELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_COLOR_BACKGROUND ? CMessage::Text(MSG_CHART_OBJ_COLOR_BACKGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_FOREGROUND ? CMessage::Text(MSG_CHART_OBJ_COLOR_FOREGROUND)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_GRID ? CMessage::Text(MSG_CHART_OBJ_COLOR_GRID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_VOLUME ? CMessage::Text(MSG_CHART_OBJ_COLOR_VOLUME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_UP ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_UP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_DOWN ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_DOWN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CHART_LINE ? CMessage::Text(MSG_CHART_OBJ_COLOR_CHART_LINE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CANDLE_BULL ? CMessage::Text(MSG_CHART_OBJ_COLOR_CANDLE_BULL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_CANDLE_BEAR ? CMessage::Text(MSG_CHART_OBJ_COLOR_CANDLE_BEAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_BID ? CMessage::Text(MSG_CHART_OBJ_COLOR_BID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_ASK ? CMessage::Text(MSG_CHART_OBJ_COLOR_ASK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_LAST ? CMessage::Text(MSG_CHART_OBJ_COLOR_LAST)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_COLOR_STOP_LEVEL ? CMessage::Text(MSG_CHART_OBJ_COLOR_STOP_LEVEL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CHART_PROP_SHOW_TRADE_LEVELS ? CMessage::Text(MSG_CHART_OBJ_SHOW_TRADE_LEVELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_DRAG_TRADE_LEVELS ? CMessage::Text(MSG_CHART_OBJ_DRAG_TRADE_LEVELS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_DATE_SCALE ? CMessage::Text(MSG_CHART_OBJ_SHOW_DATE_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_PRICE_SCALE ? CMessage::Text(MSG_CHART_OBJ_SHOW_PRICE_SCALE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_SHOW_ONE_CLICK ? CMessage::Text(MSG_CHART_OBJ_SHOW_ONE_CLICK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_MAXIMIZED ? CMessage::Text(MSG_CHART_OBJ_IS_MAXIMIZED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_MINIMIZED ? CMessage::Text(MSG_CHART_OBJ_IS_MINIMIZED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_IS_DOCKED ? CMessage::Text(MSG_CHART_OBJ_IS_DOCKED)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property) ? CMessage::Text(MSG_LIB_TEXT_YES) : CMessage::Text(MSG_LIB_TEXT_NO)) ) : property==CHART_PROP_FLOAT_LEFT ? CMessage::Text(MSG_CHART_OBJ_FLOAT_LEFT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_TOP ? CMessage::Text(MSG_CHART_OBJ_FLOAT_TOP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_RIGHT ? CMessage::Text(MSG_CHART_OBJ_FLOAT_RIGHT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CHART_PROP_FLOAT_BOTTOM ? CMessage::Text(MSG_CHART_OBJ_FLOAT_BOTTOM)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+
追加されたコードのブロックは他のすべてのブロックと同じです。メソッドに渡されたプロパティに応じて、説明と値を含む文字列が作成されて返されます。
操作ログにすべてのオブジェクトプロパティを表示するメソッドを改善しましょう。
//+------------------------------------------------------------------+ //| Display object properties in the journal | //+------------------------------------------------------------------+ void CChartObj::Print(const bool full_prop=false) { ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") ============="); int beg=0, end=CHART_PROP_INTEGER_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_INTEGER prop=(ENUM_CHART_PROP_INTEGER)i; if(!full_prop && !this.SupportProperty(prop)) continue; if(prop==CHART_PROP_WINDOW_IND_HANDLE || prop==CHART_PROP_WINDOW_IND_INDEX) continue; if(prop==CHART_PROP_HEIGHT_IN_PIXELS) { this.PrintWndParameters(); continue; } ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); beg=end; end+=CHART_PROP_DOUBLE_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_DOUBLE prop=(ENUM_CHART_PROP_DOUBLE)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); beg=end; end+=CHART_PROP_STRING_TOTAL; for(int i=beg; i<end; i++) { ENUM_CHART_PROP_STRING prop=(ENUM_CHART_PROP_STRING)i; if(!full_prop && !this.SupportProperty(prop)) continue; if(prop==CHART_PROP_INDICATOR_NAME) { this.PrintWndIndicators(); continue; } ::Print(this.GetPropertyDescription(prop)); } ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n"); } //+------------------------------------------------------------------+
ループにある「指標ハンドル」と「ウィンドウ内の指標インデックス」プロパティはスキップされます。それらはチャートオブジェクトとは関係ありません。
「チャートの高さ(ピクセル単位)」プロパティの場合、すべてのチャートウィンドウのプロパティの説明を表示するメソッドが呼び出されます。
「ウィンドウ内の指標名」プロパティの場合、すべてのチャートウィンドウに接続されているすべての指標の説明を表示するメソッドが呼び出されます。これらのメソッドについては後で検討します。
オブジェクトの短い説明を表示するメソッドも改善されました。
チャートウィンドウのサブウィンドウが存在する場合はその数を表示し、存在しない場合は存在ないことを通知します。
//+------------------------------------------------------------------+ //| Display a short description of the object in the journal | //+------------------------------------------------------------------+ void CChartObj::PrintShort(const bool dash=false) { ::Print ( (dash ? "- " : ""),this.Header()," ID: ",(string)this.ID(),", HWND: ",(string)this.Handle(), ", ",CMessage::Text(MSG_CHART_OBJ_CHART_SUBWINDOWS_NUM),": ",(this.WindowsTotal()>1 ? string(this.WindowsTotal()-1) : CMessage::Text(MSG_LIB_TEXT_NO)) ); } //+------------------------------------------------------------------+
以下は、操作ログにすべてのチャートウィンドウのすべての指標のデータを表示するメソッドです。
//+-------------------------------------------------------------------+ //| Display data of all indicators of all chart windows in the journal| //+-------------------------------------------------------------------+ void CChartObj::PrintWndIndicators(void) { for(int i=0;i<this.WindowsTotal();i++) { CChartWnd *wnd=m_list_wnd.At(i); if(wnd==NULL) continue; wnd.PrintIndicators(true); } } //+------------------------------------------------------------------+
ここで、すべてのチャートウィンドウオブジェクトによるループで、次のチャートウィンドウオブジェクトを取得し、操作ログのウィンドウに接続されているすべての指標の説明を表示します。メソッドはtrueを受け取るため、指標の説明の前にハイフンが表示されます。
以下は、操作ログですべてのチャートウィンドウのプロパティを表示するメソッドです。
//+------------------------------------------------------------------+ //| Display the properties of all chart windows in the journal | //+------------------------------------------------------------------+ void CChartObj::PrintWndParameters(void) { for(int i=0;i<this.WindowsTotal();i++) { CChartWnd *wnd=m_list_wnd.At(i); if(wnd==NULL) continue; wnd.PrintParameters(true); } } //+------------------------------------------------------------------+
ここで、すべてのチャートウィンドウオブジェクトによるループで、次のチャートウィンドウオブジェクトを取得し、操作ログでパラメータの説明を表示します。メソッドはtrueを受け取るため、ウィンドウの説明の前にハイフンが表示されます。
以下は、サブウィンドウインデックスによってウィンドウオブジェクトを返すメソッドです。
//+------------------------------------------------------------------+ //| Return the window object by its subwindow index | //+------------------------------------------------------------------+ CChartWnd *CChartObj::GetWindowByNum(const int win_num) const { int total=m_list_wnd.Total(); for(int i=0;i<total;i++) { CChartWnd *wnd=m_list_wnd.At(i); if(wnd==NULL) continue; if(wnd.WindowNum()==win_num) return wnd; } return NULL; } //+------------------------------------------------------------------+
ここで、チャートウィンドウオブジェクトの総数によるループで、次のウィンドウオブジェクトを取得します。そのインデックスがメソッドに渡されたものと一致する場合は、リストにあるオブジェクトへのポインタを返します。ループが完了すると、NULLLを返します(オブジェクトが見つかりません)。
以下は、「サブウィンドウの可視性」プロパティをチャートオブジェクトに設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the "Subwindow visibility" property | //+------------------------------------------------------------------+ void CChartObj::SetVisible(void) { this.SetProperty(CHART_PROP_WINDOW_IS_VISIBLE,::ChartGetInteger(this.ID(),CHART_WINDOW_IS_VISIBLE,0)); } //+------------------------------------------------------------------+
ここでは、メインのチャートウィンドウの適切な読み取り専用プロパティを追加するだけです。
以下は、指標サブウィンドウの上部フレームとメインウィンドウの上部フレームの間の距離をY軸ピクセルで返すメソッドです。
//+-----------------------------------------------------------------------------------+ //| Return the distance in pixels by Y axis between | //| the upper frame of the indicator subwindow and the upper frame of the main window | //+-----------------------------------------------------------------------------------+ int CChartObj::WindowYDistance(const int sub_window) const { CChartWnd *wnd=GetWindowByNum(sub_window); return(wnd!=NULL ? wnd.YDistance() : WRONG_VALUE); } //+------------------------------------------------------------------+
ここで、サブウィンドウインデックスによってチャートウィンドウオブジェクトを受け取り、取得したオブジェクトからプロパティ値を返します。
オブジェクトが受信されない場合は-1を返します
。
以下は、指定されたチャートの高さをピクセル単位で返すメソッドです。
//+------------------------------------------------------------------+ //| Return the height of the specified chart in pixels | //+------------------------------------------------------------------+ int CChartObj::WindowHeightInPixels(const int sub_window) const { CChartWnd *wnd=GetWindowByNum(sub_window); return(wnd!=NULL ? wnd.HeightInPixels() : WRONG_VALUE); } //+------------------------------------------------------------------+
ここで、サブウィンドウインデックスによってチャートウィンドウオブジェクトを受け取り、取得したオブジェクトからプロパティ値を返します。
オブジェクトが受信されない場合は-1を返します。
以下は、指定したチャートの高さをピクセル単位で設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the height of the specified chart in pixels | //+------------------------------------------------------------------+ bool CChartObj::SetWindowHeightInPixels(const int height,const int sub_window,const bool redraw=false) { CChartWnd *wnd=GetWindowByNum(sub_window); return(wnd!=NULL ? wnd.SetHeightInPixels(height,redraw) : false); } //+------------------------------------------------------------------+
ここで、サブウィンドウインデックスによってチャートウィンドウオブジェクトを受け取り、取得したオブジェクトに適切なプロパティ値を設定した結果を返します。
オブジェクトが受信されなかった場合は、 falseを返します。
前の記事で追加した古いメソッドを削除します。
//+------------------------------------------------------------------+
//| Set the height of the specified chart in pixels |
//+------------------------------------------------------------------+
bool CChartObj::SetWindowHeightInPixels(const int height,const int sub_window,const bool redraw=false)
{
::ResetLastError();
if(!::ChartSetInteger(this.ID(),CHART_HEIGHT_IN_PIXELS,sub_window,height))
{
CMessage::ToLog(DFUN,::GetLastError(),true);
return false;
}
if(redraw)
::ChartRedraw(this.ID());
return true;
}
//+------------------------------------------------------------------+
これで、チャートオブジェクトクラスの改善は完了です。
検証
作成されたオブジェクトのパフォーマンスを確認するには、3つのチャートを開くだけです。EAを使用してチャートにフラクタル指標を追加して、指標ウィンドウを追加します。たとえば、DeMarkerデータに基づくAMAなどの別の指標を含むDeMarkerです。
2番目のチャートでは、ストキャスティクスウィンドウを配置し、3番目のウィンドウはドッキング解除されます(Alt + D)。
操作ログで、3つのチャートオブジェクトすべての簡単な説明とEAがある現在のチャートの完全な説明を表示します。
テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part68\で TestDoEasyPart68.mq5として保存します。
EAはほとんど変更されていません。必要なのは、OnTick()ハンドラにロジックを追加することです。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Handle the NewTick event in the library engine.OnTick(rates_data); //--- If working in the tester if(MQLInfoInteger(MQL_TESTER)) { engine.OnTimer(rates_data); // Working in the timer PressButtonsControl(); // Button pressing control engine.EventsHandling(); // Working with events } //--- If the trailing flag is set if(trailing_on) { TrailingPositions(); // Trailing positions TrailingOrders(); // Trailing pending orders } //--- If it is the first launch static bool done=false; if(!done) { //--- Create the list object for storing chart objects CArrayObj *list=new CArrayObj(); if(list==NULL) return; //--- Declare the variables and get the first chart ID long currChart,prevChart=ChartFirst(); int i=0; //--- Create the chart object and add it to the list CChartObj *chart_first=new CChartObj(prevChart); list.Add(chart_first); //--- In the loop by the total number of terminal charts (not more than 100) while(i<CHARTS_MAX) { //--- based on the previous one, get the new chart currChart=ChartNext(prevChart); //--- When reaching the end of the chart list, complete the loop if(currChart<0) break; //--- Create the chart object based on the current chart ID in the loop and add it to the list CChartObj *chart=new CChartObj(currChart); list.Add(chart); //--- remember the current chart ID for ChartNext() and increase the loop counter prevChart=currChart; i++; } Print(""); //--- From the filled list in the loop, receive the next chart object and display its short description int total=list.Total(); for(int j=0;j<total;j++) { CChartObj *chart_obj=list.At(j); if(chart_obj!=NULL) chart_obj.PrintShort(); } Print(""); //--- Display the full description of the current chart: in the loop by all objects of the created list for(int j=0;j<total;j++) { //--- get the next chart object and CChartObj *chart_obj=list.At(j); //--- if its symbol matches the current chart symbol, display its full description in the journal if(chart_obj!=NULL && chart_obj.Symbol()==Symbol()) chart_obj.Print(); } //--- Destroy the list of chart objects delete list; done=true; } //--- } //+------------------------------------------------------------------+
セクションの冒頭で説明した必要なターミナル環境を事前に作成しながら、EAをコンパイルしてチャート上で起動します。
操作ログには、開いている3つのチャートすべての簡単な説明が表示されます。
Main chart window EURUSD H4 ID: 131733844391938630, HWND: 5179646, Subwindows: 1 Main chart window AUDUSD H4 ID: 131733844391938634, HWND: 3672036, Subwindows: 1 Main chart window GBPUSD H4 ID: 131733844391938633, HWND: 3473910, Subwindows: No
and the full description of the current one. 本稿で開発されたクラスの結果は、ウィンドウオブジェクトプロパティの順序付けられた文字列として操作ログおよびそれらに接続された指標に表示されます。
============= The beginning of the parameter list (Main chart window EURUSD H4) ============= Chart ID: 131733844391938630 Timeframe: H4 Drawing attributes of a price chart: Yes Object "Chart": No Chart on top of other charts: No Accessing the context menu by pressing the right mouse button: Yes Accessing the "Crosshair tool" by pressing the middle mouse button: Yes Scrolling the chart horizontally using the left mouse button: Yes Sending messages about mouse wheel events to all mql5 programs on a chart: No Send notifications of mouse move and mouse click events to all mql5 programs on a chart: No Send a notification of an event of new object creation to all mql5-programs on a chart: No Send a notification of an event of object deletion to all mql5-programs on a chart: No Chart type: Display as Japanese candlesticks Price chart in the foreground: No Price chart indent from the right border: Yes Automatic moving to the right border of the chart: Yes Managing the chart using a keyboard: Yes Allowed to intercept Space and Enter key presses on the chart to activate the quick navigation bar: Yes Scale: 2 Fixed scale mode: No Scale 1:1 mode: No Scale to be specified in points per bar: No Display a symbol ticker in the upper left corner: Yes Display OHLC values in the upper left corner: Yes Display Bid values as a horizontal line in a chart: Yes Display Ask values as a horizontal line in a chart: Yes Display Last values as a horizontal line in a chart: No Display vertical separators between adjacent periods: No Display grid in the chart: No Display volume in the chart: Trade volumes Display textual descriptions of objects: Yes The number of bars on the chart that can be displayed: 137 The total number of chart windows, including indicator subwindows: 2 Visibility of subwindow: Yes Chart window handle: 5179646 Number of the first visible bar in the chart: 136 Chart width in bars: 168 Chart width in pixels: 670 Main chart window: - Chart height in pixels: 301 Chart subwindow 1: - The distance between the upper frame of the indicator subwindow and the upper frame of the main chart window: 303 - Chart height in pixels: 13 Chart background color: clrWhite Color of axes, scales and OHLC line: clrBlack Grid color: clrSilver Color of volumes and position opening levels: clrGreen Color for the up bar, shadows and body borders of bull candlesticks: clrBlack Color for the down bar, shadows and body borders of bear candlesticks: clrBlack Line chart color and color of "Doji" Japanese candlesticks: clrBlack Body color of a bull candlestick: clrWhite Body color of a bear candlestick: clrBlack Bid price level color: clrLightSkyBlue Ask price level color: clrCoral Line color of the last executed deal price (Last): clrSilver Color of stop order levels (Stop Loss and Take Profit): clrOrangeRed Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders): Yes Permission to drag trading levels on a chart with a mouse: Yes Showing the time scale on a chart: Yes Showing the price scale on a chart: Yes Showing the "One click trading" panel on a chart: No Chart window is maximized: Yes Chart window is minimized: No The chart window is docked: Yes The left coordinate of the undocked chart window relative to the virtual screen: 0 The top coordinate of the undocked chart window relative to the virtual screen: 0 The right coordinate of the undocked chart window relative to the virtual screen: 0 The bottom coordinate of the undocked chart window relative to the virtual screen: 0 ------ The size of the zero bar indent from the right border in percents: 18.93 Chart fixed position from the left border in percent value: 0.00 Fixed chart maximum: 1.22620 Fixed chart minimum : 1.17940 Scale in points per bar: 1.00 Chart minimum: 1.17940 Chart maximum: 1.22620 ------ Text of a comment in a chart: "" The name of the Expert Advisor running on the chart: "TestDoEasyPart68" The name of the script running on the chart: "" Indicators in the main chart window: - Indicator Fractals Indicators in the chart window 1: - Indicator DeM(14) - Indicator AMA(14,2,30) Symbol: "EURUSD" ============= End of the parameter list (Main chart window EURUSD H4) =============
次の段階
次の記事では、チャートオブジェクトコレクションクラスの開発を開始します。
ライブラリの現在のバージョンのすべてのファイルは、テストおよびダウンロードできるように、MQL5のテストEAファイルと一緒に以下に添付されています。
チャートオブジェクトはさらに変更されるため、現在の状態で作業に使用することはお勧めしません。
質問や提案はコメント欄にお願いします。
*連載のこれまでの記事:
DoEasyライブラリでの価格(第62部): ティックシリーズをリアルタイムで更新して板情報で作業するための準備
DoEasyライブラリでの価格(第63部): 板情報とその抽象リクエストクラス
DoEasyライブラリでの価格(第64部): 板情報、DOMスナップショットのクラスおよびスナップショットシリーズオブジェクト
DoEasyライブラリでの価格(第65部): 板情報コレクションとMQL5.comシグナル操作クラス
DoEasyライブラリでのその他のクラス(第66部): MQL5.comシグナルコレクションクラス
DoEasyライブラリでのその他のクラス(第67部): チャットオブジェクトクラス
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/9236





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
お金を返して下さい!
和解の提案があれば、提示して下さい!
1. 何の話をしているのか全く分からない。
2. MetaQuotes とトラブっているのならサービスデスクに言え。
3. 掲示板に書いても誰も見てはいない。これ以上無駄な投稿はするな。