DoEasy. Dienstfunktionen (Teil 2): Das Muster der „Inside-Bar“
Inhalt
- Konzept
- Verbesserung der Bibliotheksklassen
- Klasse der Bitmap-Grafikelemente
- Die Klasse des Musters „Inside-Bar“
- Test
- Was kommt als Nächstes?
Konzept
Wir entwickeln weiterhin Muster, die auf Zeitreihendaten basieren. Im ersten Artikel der Musterserie haben wir ein Toolkit für die Suche und Anzeige verschiedener Muster erstellt und eine Funktionalität für die Suche nach dem Muster „Pin-Bar“ aus den Price Action-Formationen entwickelt. In diesem Artikel werden wir die Funktionalität für die Suche nach verschiedenen Mustern in Preischarts weiterentwickeln und verfeinern und die Suche nach den Mustern „Inside-Bar“ der Price Action erstellen.
Wenn das „Pin-Bar“-Muster eine Formation aus einem Balken ist und nach den Proportionen eines Balkens gesucht wird, dann ist die „Inside-Bar“ eine Formation aus zwei Balken, die aus zwei Balken besteht - dem Mutter-Balken (dem Balken links) und dem definierenden Balken (Balken rechts):
Bei der Suche nach solchen Formationen reicht es nicht aus, nur die Proportionen eines Balkens zu vergleichen. Hier müssen wir zwei benachbarte Balken vergleichen. Außerdem können solche Formationen in einer Reihe laufen, und dann wird der Mutterbalken für alle ineinander verschachtelten Formationen einer sein, und zwar der ganz linke, während es viele definierende Balken geben wird - jeder rechte Balken jeder verschachtelten Formation. Der Balken ganz rechts ist der letzte der bestimmenden Balken der gesamten verschachtelten Formation. Um nach solchen Strukturen zu suchen, werden wir eine universelle Funktionalität implementieren und eine weitere Eigenschaft zu den Mustereigenschaften hinzufügen - die Öffnungszeit des Mutterbalkens. Anhand der Differenz zwischen den Eröffnungszeiten der Mutter- und der Definitionsbalken lässt sich die Anzahl der Balken bestimmen, die in der gesamten verschachtelten Formation enthalten sind. Dies ist nützlich, um Beschreibung des Musters auf dem Chart zu zeichnen. Mit anderen Worten, zusätzlich zu der Tatsache, dass jedes Muster mit einem einfachen Punkt auf dem Chart markiert werden kann, werden wir es ermöglichen, das Muster visuell anzuzeigen, indem wir einen Rahmen um die in der Formation enthaltenen Balken zeichnen. Dementsprechend werden wir die Möglichkeit schaffen, zwischen verschiedenen Methoden zur Darstellung von Mustern im Chart zu wählen.
Außerdem werden uns die heute geschaffenen Funktionen bei der Erstellung anderer Mustertypen helfen.
Verbesserung der Bibliotheksklassen
Bevor wir mit der Implementierung von Codes für das nächste Muster beginnen, sollten wir die vorgefertigten Dateien und Bibliotheksklassen fertigstellen.
Wir fügen in \MQL5\Include\DoEasy\Defines.mqh den Objekttyp „Bitmap“ zur Liste der Bibliotheksobjekttypen hinzu:
//+------------------------------------------------------------------+ //| List of library object types | //+------------------------------------------------------------------+ enum ENUM_OBJECT_DE_TYPE { //--- Graphics OBJECT_DE_TYPE_GBASE = COLLECTION_ID_LIST_END+1, // "Base object of all library graphical objects" object type OBJECT_DE_TYPE_GELEMENT, // "Graphical element" object type OBJECT_DE_TYPE_GFORM, // Form object type OBJECT_DE_TYPE_GFORM_CONTROL, // "Form for managing pivot points of graphical object" object type OBJECT_DE_TYPE_GSHADOW, // Shadow object type OBJECT_DE_TYPE_GGLARE, // Glare object type OBJECT_DE_TYPE_GBITMAP, // Bitmap object type //--- WinForms OBJECT_DE_TYPE_GWF_BASE, // WinForms Base object type (base abstract WinForms object) OBJECT_DE_TYPE_GWF_CONTAINER, // WinForms container object type OBJECT_DE_TYPE_GWF_COMMON, // WinForms standard control object type OBJECT_DE_TYPE_GWF_HELPER, // WinForms auxiliary control object type //--- Animation //--- ... //---...
Objekte vom Typ OBJ_BITMAP ermöglichen es, eine bmp-Ressource anzuhängen und verschiedene Primitive darauf zu zeichnen. Ein solches Objekt ist an die Balkenzeit und den Preis gebunden. Wir werden sie verwenden, um die Balken des Musters mit einem Rahmen zu umreißen.
Zusätzlich zu der Tatsache, dass Musterobjekte die Zeiten der Balken speichern, auf denen sie gebildet werden, werden wir auch die Arten von Mustern, die darauf gefunden wurden, dem Bibliotheksbalkenobjekt hinzufügen. Da es sich bei den Mustertypen um Bitflags handelt, können viele verschiedene Arten von Mustern in einer Variablen gespeichert werden. Aus dem Wert dieser Variablen können wir dann immer den Typ und dementsprechend den Namen aller auf dem Balken gefundenen Muster extrahieren.
Das ist praktisch, wenn man nach einem Muster sucht, mit dem man von einem Nutzerprogramm aus arbeiten will: Man holt sich ein Balkenobjekt, prüft die Arten von Mustern, die darauf gefunden werden, und arbeitet mit denen, deren Flags in die Variable geschrieben werden.
Wir fügen eine weitere Eigenschaft zu den Ganzzahl-Eigenschaften des Balkenobjekts hinzu und erhöhen die Anzahl der Ganzzahl-Eigenschaften des Balkenobjekts von 13 auf 14:
//+------------------------------------------------------------------+ //| Bar integer properties | //+------------------------------------------------------------------+ enum ENUM_BAR_PROP_INTEGER { BAR_PROP_TIME = 0, // Bar period start time BAR_PROP_TYPE, // Bar type (from the ENUM_BAR_BODY_TYPE enumeration) BAR_PROP_PERIOD, // Bar period (timeframe) BAR_PROP_SPREAD, // Bar spread BAR_PROP_VOLUME_TICK, // Bar tick volume BAR_PROP_VOLUME_REAL, // Bar exchange volume BAR_PROP_TIME_DAY_OF_YEAR, // Bar day serial number in a year BAR_PROP_TIME_YEAR, // A year the bar belongs to BAR_PROP_TIME_MONTH, // A month the bar belongs to BAR_PROP_TIME_DAY_OF_WEEK, // Bar week day BAR_PROP_TIME_DAY, // Bar day of month (number) BAR_PROP_TIME_HOUR, // Bar hour BAR_PROP_TIME_MINUTE, // Bar minute BAR_PROP_PATTERNS_TYPE, // Pattern types on the bar (pattern flags from the ENUM_PATTERN_TYPE enumeration) }; #define BAR_PROP_INTEGER_TOTAL (14) // Total number of integer bar properties
Wenn wir mit Listen von Zeitreihen nach Mustern suchen und ein Muster in einem Balken finden, fügen wir den Typ des gefundenen Musters zu eben dieser Variablen im Balkenobjekt hinzu. Basierend auf den Ergebnissen der Suche nach verschiedenen Arten von Mustern können in dieser Variablen in einem Balken die Flags der verschiedenen gefundenen Mustertypen aufgezeichnet werden.
Füge wir das Sortieren nach Mustertyp der Balken zur Liste der möglichen Sortierkriterien für Balkenobjekte:
//+------------------------------------------------------------------+ //| Possible bar sorting criteria | //+------------------------------------------------------------------+ #define FIRST_BAR_DBL_PROP (BAR_PROP_INTEGER_TOTAL-BAR_PROP_INTEGER_SKIP) #define FIRST_BAR_STR_PROP (BAR_PROP_INTEGER_TOTAL-BAR_PROP_INTEGER_SKIP+BAR_PROP_DOUBLE_TOTAL-BAR_PROP_DOUBLE_SKIP) enum ENUM_SORT_BAR_MODE { //--- Sort by integer properties SORT_BY_BAR_TIME = 0, // Sort by bar period start time SORT_BY_BAR_TYPE, // Sort by bar type (from the ENUM_BAR_BODY_TYPE enumeration) SORT_BY_BAR_PERIOD, // Sort by bar period (timeframe) SORT_BY_BAR_SPREAD, // Sort by bar spread SORT_BY_BAR_VOLUME_TICK, // Sort by bar tick volume SORT_BY_BAR_VOLUME_REAL, // Sort by bar exchange volume SORT_BY_BAR_TIME_DAY_OF_YEAR, // Sort by bar day number in a year SORT_BY_BAR_TIME_YEAR, // Sort by a year the bar belongs to SORT_BY_BAR_TIME_MONTH, // Sort by a month the bar belongs to SORT_BY_BAR_TIME_DAY_OF_WEEK, // Sort by a bar week day SORT_BY_BAR_TIME_DAY, // Sort by a bar day SORT_BY_BAR_TIME_HOUR, // Sort by a bar hour SORT_BY_BAR_TIME_MINUTE, // Sort by a bar minute SORT_BY_BAR_PATTERN_TYPE, // Sort by pattern types on the bar (pattern flags from the ENUM_PATTERN_TYPE enumeration) //--- Sort by real properties SORT_BY_BAR_OPEN = FIRST_BAR_DBL_PROP, // Sort by bar open price SORT_BY_BAR_HIGH, // Sort by the highest price for the bar period SORT_BY_BAR_LOW, // Sort by the lowest price for the bar period SORT_BY_BAR_CLOSE, // Sort by a bar close price SORT_BY_BAR_CANDLE_SIZE, // Sort by a candle price SORT_BY_BAR_CANDLE_SIZE_BODY, // Sort by a candle body size SORT_BY_BAR_CANDLE_BODY_TOP, // Sort by a candle body top SORT_BY_BAR_CANDLE_BODY_BOTTOM, // Sort by a candle body bottom SORT_BY_BAR_CANDLE_SIZE_SHADOW_UP, // Sort by candle upper wick size SORT_BY_BAR_CANDLE_SIZE_SHADOW_DOWN, // Sort by candle lower wick size //--- Sort by string properties SORT_BY_BAR_SYMBOL = FIRST_BAR_STR_PROP, // Sort by a bar symbol };
Zuvor war für das Harami-Muster in der Liste der Mustertypen der Wert 0 angegeben. Das ist nicht ganz richtig. Es ist besser, wenn Null das Fehlen von Mustern auf dem Balken anzeigt.
Wir sollten dies beheben und eine Makrosubstitution hinzufügen, die die Gesamtzahl der in der Bibliothek verfügbaren Suchmuster angibt:
//+------------------------------------------------------------------+ //| Pattern type | //+------------------------------------------------------------------+ enum ENUM_PATTERN_TYPE { //--- Candle formations PATTERN_TYPE_NONE = 0x0, // None PATTERN_TYPE_HARAMI = 0x1, // Harami PATTERN_TYPE_HARAMI_CROSS = 0x2, // Harami Cross PATTERN_TYPE_TWEEZER = 0x4, // Tweezer PATTERN_TYPE_PIERCING_LINE = 0x8, // Piercing Line PATTERN_TYPE_DARK_CLOUD_COVER = 0x10, // Dark Cloud Cover PATTERN_TYPE_THREE_WHITE_SOLDIERS= 0x20, // Three White Soldiers PATTERN_TYPE_THREE_BLACK_CROWS = 0x40, // Three Black Crows PATTERN_TYPE_SHOOTING_STAR = 0x80, // Shooting Star PATTERN_TYPE_HAMMER = 0x100, // Hammer PATTERN_TYPE_INVERTED_HAMMER = 0x200, // Inverted Hammer PATTERN_TYPE_HANGING_MAN = 0x400, // Hanging Man PATTERN_TYPE_DOJI = 0x800, // Doji PATTERN_TYPE_DRAGONFLY_DOJI = 0x1000, // Dragonfly Doji PATTERN_TYPE_GRAVESTONE_DOJI = 0x2000, // Gravestone Doji PATTERN_TYPE_MORNING_STAR = 0x4000, // Morning Star PATTERN_TYPE_MORNING_DOJI_STAR = 0x8000, // Morning Doji Star PATTERN_TYPE_EVENING_STAR = 0x10000, // Evening Star PATTERN_TYPE_EVENING_DOJI_STAR = 0x20000, // Evening Doji Star PATTERN_TYPE_THREE_STARS = 0x40000, // Three Stars PATTERN_TYPE_ABANDONED_BABY = 0x80000, // Abandoned Baby //--- Price Action PATTERN_TYPE_PIVOT_POINT_REVERSAL= 0x100000, // Price Action Reversal Pattern PATTERN_TYPE_OUTSIDE_BAR = 0x200000, // Price Action Outside Bar PATTERN_TYPE_INSIDE_BAR = 0x400000, // Price Action Inside Bar PATTERN_TYPE_PIN_BAR = 0x800000, // Price Action Pin Bar PATTERN_TYPE_RAILS = 0x1000000, // Price Action Rails }; #define PATTERNS_TOTAL (26) // Total number of patterns (including the missing one)
Fügen wir der Liste der ganzzahligen Mustereigenschaften eine neue Eigenschaft hinzu, die die Zeit des Mutterbalkens speichert, und erhöhen Sie die Anzahl der ganzzahligen Mustereigenschaften von 9 auf 10:
//+------------------------------------------------------------------+ //| Pattern integer properties | //+------------------------------------------------------------------+ enum ENUM_PATTERN_PROP_INTEGER { PATTERN_PROP_CODE = 0, // Unique pattern code (time + type + status + direction + timeframe + symbol) PATTERN_PROP_CTRL_OBJ_ID, // Pattern control object ID PATTERN_PROP_ID, // Pattern ID PATTERN_PROP_TIME, // Pattern defining bar time PATTERN_PROP_MOTHERBAR_TIME, // Pattern mother bar time PATTERN_PROP_STATUS, // Pattern status (from the ENUM_PATTERN_STATUS enumeration) PATTERN_PROP_TYPE, // Pattern type (from the ENUM_PATTERN_TYPE enumeration) PATTERN_PROP_DIRECTION, // Pattern type by direction (from the ENUM_PATTERN_TYPE_DIRECTION enumeration) PATTERN_PROP_PERIOD, // Pattern period (timeframe) PATTERN_PROP_CANDLES, // Number of candles that make up the pattern }; #define PATTERN_PROP_INTEGER_TOTAL (10) // Total number of integer pattern properties
Hinzufügen der Sortierung nach einer neuen Eigenschaft zur Liste der möglichen Mustersortierkriterien:
//+------------------------------------------------------------------+ //| Possible pattern sorting criteria | //+------------------------------------------------------------------+ #define FIRST_PATTERN_DBL_PROP (PATTERN_PROP_INTEGER_TOTAL-PATTERN_PROP_INTEGER_SKIP) #define FIRST_PATTERN_STR_PROP (PATTERN_PROP_INTEGER_TOTAL-PATTERN_PROP_INTEGER_SKIP+PATTERN_PROP_DOUBLE_TOTAL-PATTERN_PROP_DOUBLE_SKIP) enum ENUM_SORT_PATTERN_MODE { //--- Sort by integer properties SORT_BY_PATTERN_CODE = 0, // Sort by unique pattern code (time + type + status + direction + timeframe) SORT_BY_PATTERN_CTRL_OBJ_ID, // Sort by pattern control object ID SORT_BY_PATTERN_ID, // Sort by pattern ID SORT_BY_PATTERN_TIME, // Sort by pattern defining bar time SORT_BY_PATTERN_MOTHERBAR_TIME, // Sort by pattern mother bar time SORT_BY_PATTERN_STATUS, // Sort by pattern status (from the ENUM_PATTERN_STATUS enumeration) SORT_BY_PATTERN_TYPE, // Sort by pattern type (from the ENUM_PATTERN_TYPE enumeration) SORT_BY_PATTERN_DIRECTION, // Sort by pattern type based on direction (from the ENUM_PATTERN_TYPE_DIRECTION enumeration) SORT_BY_PATTERN_PERIOD, // Sort by pattern period (timeframe) SORT_BY_PATTERN_CANDLES, // Sort by the number of candles that make up the pattern //--- Sort by real properties SORT_BY_PATTERN_BAR_PRICE_OPEN = FIRST_PATTERN_DBL_PROP, // Sort by pattern defining bar Open price SORT_BY_PATTERN_BAR_PRICE_HIGH, // Sort by pattern defining bar High price SORT_BY_PATTERN_BAR_PRICE_LOW, // Sort by pattern defining bar Low price SORT_BY_PATTERN_BAR_PRICE_CLOSE, // Sort by pattern defining bar Close price SORT_BY_PATTERN_RATIO_BODY_TO_CANDLE_SIZE, // Sort by percentage ratio of the candle body to the full size of the candle SORT_BY_PATTERN_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE, // Sort by percentage ratio of the upper shadow size to the candle size SORT_BY_PATTERN_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE, // Sort by percentage ratio of the lower shadow size to the candle size SORT_BY_PATTERN_RATIO_BODY_TO_CANDLE_SIZE_CRITERION, // Sort by defined criterion of the ratio of the candle body to the full candle size in % SORT_BY_PATTERN_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION, // Sort by defined criterion of the ratio of the maximum shadow to the candle size in % SORT_BY_PATTERN_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION, // Sort by defined criterion of the ratio of the minimum shadow to the candle size in % //--- Sort by string properties SORT_BY_PATTERN_SYMBOL = FIRST_BAR_STR_PROP, // Sort by a pattern symbol SORT_BY_PATTERN_NAME, // Sort by pattern name };
Hinzufügen eines neuen Typs (Bitmap-Objekt) zur Liste der grafischen Elementtypen:
//+------------------------------------------------------------------+ //| The list of graphical element types | //+------------------------------------------------------------------+ enum ENUM_GRAPH_ELEMENT_TYPE { GRAPH_ELEMENT_TYPE_STANDARD, // Standard graphical object GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED, // Extended standard graphical object GRAPH_ELEMENT_TYPE_SHADOW_OBJ, // Shadow object GRAPH_ELEMENT_TYPE_ELEMENT, // Element GRAPH_ELEMENT_TYPE_BITMAP, // Bitmap GRAPH_ELEMENT_TYPE_FORM, // Form GRAPH_ELEMENT_TYPE_WINDOW, // Window //--- WinForms GRAPH_ELEMENT_TYPE_WF_UNDERLAY, // Panel object underlay GRAPH_ELEMENT_TYPE_WF_BASE, // Windows Forms Base //--- 'Container' object types are to be set below GRAPH_ELEMENT_TYPE_WF_CONTAINER, // Windows Forms container base object GRAPH_ELEMENT_TYPE_WF_PANEL, // Windows Forms Panel GRAPH_ELEMENT_TYPE_WF_GROUPBOX, // Windows Forms GroupBox GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL, // Windows Forms TabControl GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER, // Windows Forms SplitContainer //--- 'Standard control' object types are to be set below GRAPH_ELEMENT_TYPE_WF_COMMON_BASE, // Windows Forms base standard control GRAPH_ELEMENT_TYPE_WF_LABEL, // Windows Forms Label GRAPH_ELEMENT_TYPE_WF_BUTTON, // Windows Forms Button GRAPH_ELEMENT_TYPE_WF_CHECKBOX, // Windows Forms CheckBox GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON, // Windows Forms RadioButton GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX, // Base list object of Windows Forms elements GRAPH_ELEMENT_TYPE_WF_LIST_BOX, // Windows Forms ListBox GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX, // Windows Forms CheckedListBox GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX, // Windows Forms ButtonListBox GRAPH_ELEMENT_TYPE_WF_TOOLTIP, // Windows Forms ToolTip GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR, // Windows Forms ProgressBar //--- Auxiliary elements of WinForms objects GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM, // Windows Forms ListBoxItem GRAPH_ELEMENT_TYPE_WF_TAB_HEADER, // Windows Forms TabHeader GRAPH_ELEMENT_TYPE_WF_TAB_FIELD, // Windows Forms TabField GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL, // Windows Forms SplitContainerPanel GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON, // Windows Forms ArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP, // Windows Forms UpArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN, // Windows Forms DownArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT, // Windows Forms LeftArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT, // Windows Forms RightArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX, // Windows Forms UpDownArrowButtonsBox GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX, // Windows Forms LeftRightArrowButtonsBox GRAPH_ELEMENT_TYPE_WF_SPLITTER, // Windows Forms Splitter GRAPH_ELEMENT_TYPE_WF_HINT_BASE, // Windows Forms HintBase GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT, // Windows Forms HintMoveLeft GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT, // Windows Forms HintMoveRight GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP, // Windows Forms HintMoveUp GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN, // Windows Forms HintMoveDown GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR, // Windows Forms BarProgressBar GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ, // Glare object GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_THUMB, // Windows Forms ScrollBarThumb GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR, // Windows Forms ScrollBar GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL, // Windows Forms ScrollBarHorisontal GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL, // Windows Forms ScrollBarVertical };Hierbei handelt es sich um eine neue Art von grafischen Objekten für die Bibliothek, die an Preis/Zeit-Koordinaten gebunden sind und auf denen Sie auf dieselbe Weise zeichnen können wie auf den GUI-Elementen der Bibliothek. Aus diesem Grund wurde sie in diese Liste aufgenommen. Wahrscheinlich werden wir sie neben der Darstellung von Musterbalken im Preischart auch für andere Zwecke der Bibliothek verwenden.
Fügen wir in der Bibliotheksdatei \MQL5\Include\DoEasy\Data.mqh die Indizes für neue Bibliotheksmeldungen hinzu:
//+------------------------------------------------------------------+ //| List of the library's text message indices | //+------------------------------------------------------------------+ enum ENUM_MESSAGES_LIB { MSG_LIB_PARAMS_LIST_BEG=ERR_USER_ERROR_FIRST, // Beginning of the parameter list MSG_LIB_PARAMS_LIST_END, // End of the parameter list MSG_LIB_PROP_NOT_SUPPORTED, // Property not supported MSG_LIB_PROP_NOT_SUPPORTED_MQL4, // Property not supported in MQL4 MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_2155, // Property not supported in MetaTrader 5 versions lower than 2155 MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_3245, // Property not supported in MetaTrader 5 versions lower than 3245 MSG_LIB_PROP_NOT_SUPPORTED_MT5_LESS_3260, // Property not supported in MetaTrader 5 versions lower than 3260 MSG_LIB_PROP_NOT_SUPPORTED_POSITION, // Property not supported for position MSG_LIB_PROP_NOT_SUPPORTED_PENDING, // Property not supported for pending order MSG_LIB_PROP_NOT_SUPPORTED_MARKET, // Property not supported for market order MSG_LIB_PROP_NOT_SUPPORTED_MARKET_HIST, // Property not supported for historical market order MSG_LIB_PROP_NOT_SET, // Value not set MSG_LIB_PROP_EMPTY, // Not set MSG_LIB_PROP_NOT_FOUND, // Not found MSG_LIB_PROP_AUTO, // Generated by the terminal MSG_LIB_PROP_AS_IN_ORDER, // According to the order expiration mode
...
MSG_LIB_TEXT_BAR_RATIO_BODY_TO_CANDLE_SIZE, // Ratio of the candle body to the full size of the candle MSG_LIB_TEXT_BAR_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,// Ratio of the upper shadow size to the candle size MSG_LIB_TEXT_BAR_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,// Ratio of the lower shadow size to the candle size MSG_LIB_TEXT_BAR_PATTERNS_TYPE, // Types of patterns on the bar //--- CTimeSeries
...
//--- CPattern MSG_LIB_TEXT_PATTERN_CODE, // Code MSG_LIB_TEXT_PATTERN_TIME, // Defining bar time MSG_LIB_TEXT_PATTERN_MOTHERBAR_TIME, // "Mother" bar time MSG_LIB_TEXT_PATTERN_ID, // Pattern ID MSG_LIB_TEXT_PATTERN_CTRL_OBJ_ID, // Pattern control object ID
...
MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED, // Extended standard graphical object MSG_GRAPH_ELEMENT_TYPE_ELEMENT, // Element MSG_GRAPH_ELEMENT_TYPE_BITMAP, // Bitmap MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ, // Shadow object MSG_GRAPH_ELEMENT_TYPE_FORM, // Form
...
//--- String properties of graphical elements MSG_CANV_ELEMENT_PROP_NAME_OBJ, // Graphical element object name MSG_CANV_ELEMENT_PROP_NAME_RES, // Graphical resource name MSG_CANV_ELEMENT_PROP_TEXT, // Graphical element text MSG_CANV_ELEMENT_PROP_DESCRIPTION, // Graphical element description MSG_CANV_ELEMENT_PROP_TOOLTIP_TITLE, // Element tooltip title MSG_CANV_ELEMENT_PROP_TOOLTIP_TEXT, // Element tooltip text //--- CGCnvBitmap MSG_ERR_FAILED_SET_BITMAP_OBJ_TIME, // Failed to set the time value to the Bitmap object MSG_ERR_FAILED_SET_BITMAP_OBJ_PRICE, // Failed to set the price value for the Bitmap object };
und die Textnachrichten, die den neu hinzugefügten Indizes entsprechen:
string messages_library[][TOTAL_LANG]= { {"Начало списка параметров","The beginning of the parameter list"}, {"Конец списка параметров","End of parameter list"}, {"Свойство не поддерживается","Property not supported"}, {"Свойство не поддерживается в MQL4","Property not supported in MQL4"}, {"Свойство не поддерживается в MetaTrader5 версии ниже 2155","The property is not supported in MetaTrader5, build lower than 2155"}, {"Свойство не поддерживается в MetaTrader5 версии ниже 3245","The property is not supported in MetaTrader5, build lower than 3245"}, {"Свойство не поддерживается в MetaTrader5 версии ниже 3260","The property is not supported in MetaTrader5, build lower than 3260"}, {"Свойство не поддерживается у позиции","Property not supported for position"}, {"Свойство не поддерживается у отложенного ордера","The property is not supported for a pending order"}, {"Свойство не поддерживается у маркет-ордера","The property is not supported for a market-order"}, {"Свойство не поддерживается у исторического маркет-ордера","The property is not supported for a history market-order"}, {"Значение не задано","Value not set"}, {"Отсутствует","Not set"}, {"Не найдено","Not found"}, {"Формируется терминалом","Formed by the terminal"}, {"В соответствии с режимом истечения ордера","In accordance with the order expiration mode"},
...
{"Отношение тела свечи к полному размеру свечи","Ratio of candle body to full candle size"}, {"Отношение размера верхней тени к размеру свечи","Ratio of the upper shadow size to the candle size"}, {"Отношение размера нижней тени к размеру свечи","Ratio of the lower shadow size to the candle size"}, {"Типы паттернов на баре","Types of patterns on the bar"}, //--- CTimeSeries
...
//--- CPattern {"Код","Code"}, {"Время определяющего бара","Time of the defining bar"}, {"Время \"материнского\" бара","Time open of the mother bar"}, {"Идентификатор паттерна","Pattern ID"}, {"Идентификатор объекта управления паттерном","Pattern Control object ID"},
...
{"Расширенный стандартный графический объект","Extended standard graphic object"}, {"Элемент","Element"}, {"Рисунок","Bitmap"}, {"Объект тени","Shadow object"}, {"Форма","Form"},
...
//--- String properties of graphical elements {"Имя объекта-графического элемента","The name of the graphic element object"}, {"Имя графического ресурса","Image resource name"}, {"Текст графического элемента","Text of the graphic element"}, {"Описание графического элемента","Description of the graphic element"}, {"Заголовок подсказки элемента","Element tooltip header"}, {"Текст подсказки элемента","Element tooltip title"}, //--- CGCnvBitmap {"Не удалось установить значение времени Bitmap-объекту","Failed to set time value to Bitmap object"}, {"Не удалось установить значение цены Bitmap-объекту","Failed to set price value to Bitmap object"}, };
Oft ist es notwendig, die Gültigkeit der an Funktionen und Methoden übergebenen Symbol- und Periodenwerte zu überprüfen. Um Codewiederholungen zu vermeiden, implementieren wir die Funktionen, die den korrekten Symbolnamen und die Chartperiode zurückgeben, in \MQL5\Include\DoEasy\Services\DELib.mqh:
//+------------------------------------------------------------------+ //| Service functions | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Correct and return a symbol name | //+------------------------------------------------------------------+ string CorrectSymbol(const string symbol) { return(symbol==NULL || symbol=="" ? ::Symbol() : symbol); } //+------------------------------------------------------------------+ //| Correct and return a timeframe name | //+------------------------------------------------------------------+ ENUM_TIMEFRAMES CorrectTimeframe(const ENUM_TIMEFRAMES timeframe) { return(timeframe==PERIOD_CURRENT ? ::Period() : timeframe); }
Wenn NULL, ein leerer String, 0 oder PERIOD_CURRENT als Chart-Periode übergeben werden, geben die Funktionen das aktuelle Symbol oder den aktuellen Zeitrahmen zurück. In allen anderen Fällen geben sie die an die Funktion übergebenen Werte zurück. So werden wir nach und nach alle Codes in der Bibliothek, in denen ähnliche Prüfungen auf die Gültigkeit der an die Methoden übergebenen Werte durchgeführt werden, durch diese Funktionen ersetzen.
Wir werden hier auch die Funktionen hinzufügen, die Musterbeschreibungen zurückgeben:
//+------------------------------------------------------------------+ //| Return pattern type description | //+------------------------------------------------------------------+ string PatternTypeDescription(const ENUM_PATTERN_TYPE type) { switch(type) { case PATTERN_TYPE_HARAMI : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_HARAMI); case PATTERN_TYPE_HARAMI_CROSS : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_HARAMI_CROSS); case PATTERN_TYPE_TWEEZER : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_TWEEZER); case PATTERN_TYPE_PIERCING_LINE : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_PIERCING_LINE); case PATTERN_TYPE_DARK_CLOUD_COVER : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_DARK_CLOUD_COVER); case PATTERN_TYPE_THREE_WHITE_SOLDIERS : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_THREE_WHITE_SOLDIERS); case PATTERN_TYPE_THREE_BLACK_CROWS : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_THREE_BLACK_CROWS); case PATTERN_TYPE_SHOOTING_STAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_SHOOTING_STAR); case PATTERN_TYPE_HAMMER : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_HAMMER); case PATTERN_TYPE_INVERTED_HAMMER : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_INVERTED_HAMMER); case PATTERN_TYPE_HANGING_MAN : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_HANGING_MAN); case PATTERN_TYPE_DOJI : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_DOJI); case PATTERN_TYPE_DRAGONFLY_DOJI : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_DRAGONFLY_DOJI); case PATTERN_TYPE_GRAVESTONE_DOJI : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_GRAVESTONE_DOJI); case PATTERN_TYPE_MORNING_STAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_MORNING_STAR); case PATTERN_TYPE_MORNING_DOJI_STAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_MORNING_DOJI_STAR); case PATTERN_TYPE_EVENING_STAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_EVENING_STAR); case PATTERN_TYPE_EVENING_DOJI_STAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_EVENING_DOJI_STAR); case PATTERN_TYPE_THREE_STARS : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_THREE_STARS); case PATTERN_TYPE_ABANDONED_BABY : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_ABANDONED_BABY); case PATTERN_TYPE_PIVOT_POINT_REVERSAL : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_PIVOT_POINT_REVERSAL); case PATTERN_TYPE_OUTSIDE_BAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_OUTSIDE_BAR); case PATTERN_TYPE_INSIDE_BAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_INSIDE_BAR); case PATTERN_TYPE_PIN_BAR : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_PIN_BAR); case PATTERN_TYPE_RAILS : return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_RAILS); default : return CMessage::Text(MSG_LIB_TEXT_FRAME_STYLE_NONE); } }
Je nach dem an die Funktion übergebenen Mustertyp wird die entsprechende Textbeschreibung zurückgegeben.
Die Funktion, die die Anzahl und die Liste der Muster in einer ulong-Variablen zurückgibt:
//+------------------------------------------------------------------+ //| Return the number and list of patterns in the ulong variable | //+------------------------------------------------------------------+ int ListPatternsInVar(const ulong var,ulong &array[]) { int size=0; ulong x=1; //--- In the loop from 1 to the number of patterns PATTERNS_TOTAL-1 for(int i=1;i<PATTERNS_TOTAL;i++) { //--- set the value of the pattern flag to be checked from the ENUM_PATTERN_TYPE enumeration by the loop index x=(i>1 ? x*2 : 1); ENUM_PATTERN_TYPE type=(ENUM_PATTERN_TYPE)x; //--- If the value passed to the function contains the pattern flag with x value, bool res=(var & type)==type; if(res) { //--- increase the size of the pattern array size++; ArrayResize(array,size,PATTERNS_TOTAL-1); //--- write the pattern type to the array array[size-1]=type; } } //--- Return the number of pattern types stored in the variable return size; }
Die Funktion erhält die Variable, die die Musterflags enthält, und ein Array, in das die aus dieser Variable extrahierten Mustertypen geschrieben werden. Da jedes Flag doppelt so groß ist wie das vorherige, ist es einfach, den Wert des Flags in einer Schleife aus dem Wert des Schleifenindexes zu bilden und dann nach dem Vorhandensein eines solchen Flags im Variablenwert zu suchen. Wenn ein solches Flag in eine Variable geschrieben wird, wird der Mustertyp in ein Array geschrieben, das zuvor um 1 erhöht wurde, um einen neuen Mustertyp hineinzuschreiben. Am Ende der Schleife nach Mustertypen werden alle Muster, die in Form von Flags in die Variable geschrieben werden, in das Array eingetragen, das dann im Programm verwendet werden kann.
Die Funktion, die eine Beschreibung der Mustertypen in einer ulong-Variablen an das Journal sendet:
//+------------------------------------------------------------------------+ //| Send a description of pattern types in a ulong variable to the journal | //+------------------------------------------------------------------------+ void PatternsInVarDescriptionPrint(const ulong var,const bool dash=false) { ulong array[]; //--- Get the number of patterns in the value passed to the function int total=ListPatternsInVar(var,array); //--- In the loop by the array of patterns, obtain a description of the next pattern and print it for(int i=0;i<total;i++) Print((dash ? " - " : ""),PatternTypeDescription((ENUM_PATTERN_TYPE)array[i])); }
Die Methodenlogik wird in den Codekommentaren beschrieben.
Die Funktion, die eine Beschreibung der Mustertypen in einer ulong-Variablen zurückgibt:
//+------------------------------------------------------------------+ //| Return a description of pattern types in a ulong variable | //+------------------------------------------------------------------+ string PatternsInVarDescription(const ulong var,const bool dash=false) { ulong array[]; //--- Get the number of patterns in the value passed to the function int total=ListPatternsInVar(var,array); string txt=""; //--- In the loop by the array of patterns, obtain a description of the next pattern and add it to the text variable for(int i=0;i<total;i++) txt+=((dash ? " - " : "")+PatternTypeDescription((ENUM_PATTERN_TYPE)array[i]))+(i<total-1 ? "\n" : ""); //--- Return the obtained text return txt; }
Alle diese Funktionen sind von jeder Stelle des Programms aus zugänglich und ermöglichen dem Nutzer einen einfachen Zugriff auf die Listen der auf einem Balken erkannten Muster. Die Eigenschaft der Balken hat jetzt eine Variable, die die Flags der gefundenen Muster speichert. Anhand des Wertes dieser Eigenschaft und unter Verwendung der Funktionen können wir immer alle Arten von Mustern auf dem Balken extrahieren und im Programm verarbeiten. Genau das werden wir im Test-EA tun.
Die Objektklasse für grafische Elemente in der Datei \MQL5\Include\DoEasy\Objects\Graph\GCnvElement.mqh dient als Grundlage für die Erstellung komplexerer GUI-Elemente, aber es gibt einige Variablen in dieser Klasse, auf die von abgeleiteten Klassen nicht zugegriffen werden kann. Verschieben wir diese Variablen und Methoden aus dem privaten Bereich in den geschützten Bereich:
//+------------------------------------------------------------------+ //| Class of the graphical element object | //+------------------------------------------------------------------+ class CGCnvElement : public CGBaseObj { protected: CGCnvElement *m_element_main; // Pointer to the initial parent element within all the groups of bound objects CGCnvElement *m_element_base; // Pointer to the parent element within related objects of the current group CCanvas m_canvas; // CCanvas class object CPause m_pause; // Pause class object bool m_shadow; // Shadow presence color m_chart_color_bg; // Chart background color uint m_duplicate_res[]; // Array for storing resource data copy color m_array_colors_bg[]; // Array of element background colors color m_array_colors_bg_dwn[]; // Array of control background colors when clicking on the control color m_array_colors_bg_ovr[]; // Array of control background colors when hovering the mouse over the control bool m_gradient_v; // Vertical gradient filling flag bool m_gradient_c; // Cyclic gradient filling flag int m_init_relative_x; // Initial relative X coordinate int m_init_relative_y; // Initial relative Y coordinate color m_array_colors_bg_init[]; // Array of element background colors (initial color) int m_shift_coord_x; // Offset of the X coordinate relative to the base object int m_shift_coord_y; // Offset of the Y coordinate relative to the base object //--- Create (1) the object structure and (2) the object from the structure
...
long m_long_prop[CANV_ELEMENT_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[CANV_ELEMENT_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[CANV_ELEMENT_PROP_STRING_TOTAL]; // String properties ENUM_FRAME_ANCHOR m_text_anchor; // Current text alignment int m_text_x; // Text last X coordinate int m_text_y; // Text last Y coordinate protected: //--- Initialize property values void Initialize(const ENUM_GRAPH_ELEMENT_TYPE element_type, const int element_id,const int element_num, const int x,const int y,const int w,const int h, const string descript,const bool movable,const bool activity); private: //--- Return the index of the array the order's (1) double and (2) string properties are located at
Wir schreiben im Abschnitt der Methoden für die Arbeit mit dem Text zwei Methoden für den Zugriff auf die Einstellung der privaten Klasseneigenschaften:
//+------------------------------------------------------------------+ //| Methods of working with text | //+------------------------------------------------------------------+ //--- Set the last text coordinate (1) X, (2) Y void SetTextLastX(const int x) { this.m_text_x=x; } void SetTextLastY(const int y) { this.m_text_y=y; } //--- Return (1) alignment type (anchor method), the last (2) X and (3) Y text coordinate
Die Methoden sind im Konstruktor von abgeleiteten Klassen nützlich, da die Platzierung dieser Variablen in einem geschützten Bereich der Klasse noch größere Änderungen an anderen Klassen nach sich zieht. Für den Moment werden wir uns mit diesen Methoden begnügen, ohne die Variablen umzubenennen.
Bisher haben wir Objekte verwendet, die auf dem Objekt OBJ_BITMAP_LABEL - „Graphical label“ basieren:
Sie können auch die Verankerungsecke der Bitmap aus der Aufzählung ENUM_BASE_CORNER auswählen.
Diese Objekte haben Bildschirmkoordinaten in Pixeln und eignen sich für die Erstellung grafischer Steuerelemente.
Wenn wir aber ein solches Objekt an Preis/Zeit-Koordinaten binden und gleichzeitig genau die gleichen Möglichkeiten zum Zeichnen innerhalb des Objekts wie auf der Leinwand nutzen wollen, dann kommt das grafische Objekt OBJ_BITMAP zur Hilfe:
Dies ist genau das gleiche grafische Objekt, das entweder eine Rasterbilddatei oder eine dynamisch erstellte Ressource als Bild verwenden kann, in dem das Rendering stattfindet.
Die Methoden der Klasse CCanvas ermöglichen die Erstellung eines Bitmap-Objekts. Daher müssen wir lediglich eine Zeichnungsobjektklasse erstellen, die auf der Klasse der grafischen Elemente basiert und nur geringfügige Änderungen aufweist.
Klasse der Bitmap-Grafikelemente
Wir erstellen im Bibliotheksverzeichnis \MQL5\Include\DoEasy\Objects\Graph\ eine neue Datei GCnvBitmap.mqh der Klasse CGCnvBitmap.
Die Klasse sollte von der grafischen Elementklasse abgeleitet sein, deren Datei in die Datei der erstellten Klasse aufgenommen werden sollte:
//+------------------------------------------------------------------+ //| GCnvBitmap.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "GCnvElement.mqh" //+------------------------------------------------------------------+ //| Class of the graphical element object | //+------------------------------------------------------------------+ class CGCnvBitmap : public CGCnvElement { }
Im Körper der Klasse brauchen wir nur einige private Variablen und Methoden, um mit ihnen zu arbeiten, eine virtuelle Methode, um ein Objekt zu erzeugen, sowie Konstruktoren mit einem Destruktor. Alles andere ist bereits in der übergeordneten Klasse implementiert:
//+------------------------------------------------------------------+ //| Class of the graphical element object | //+------------------------------------------------------------------+ class CGCnvBitmap : public CGCnvElement { private: datetime m_time; // Time coordinate double m_price; // Price ccoordinate protected: //--- Protected constructor CGCnvBitmap(const ENUM_GRAPH_ELEMENT_TYPE element_type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int wnd_num, const string descript, const datetime time, const double price, const int w, const int h); public: //--- Create Bitmap virtual bool Create(const long chart_id, const int wnd_num, const int x, const int y, const int w, const int h, const bool redraw=false); //--- Parametric constructor CGCnvBitmap(const ENUM_GRAPH_ELEMENT_TYPE element_type, CGCnvElement *main_obj,CGCnvElement *base_obj, const int element_id, const int element_num, const long chart_id, const int wnd_num, const string descript, const datetime time, const double price, const int w, const int h, const color colour, const uchar opacity, const bool movable=false, const bool activity=true, const bool redraw=false); //--- Default constructor CGCnvBitmap() { this.m_shadow=false; this.m_chart_color_bg=(color)::ChartGetInteger(::ChartID(),CHART_COLOR_BACKGROUND); this.m_type=OBJECT_DE_TYPE_GBITMAP; this.m_element_main=NULL; this.m_element_base=NULL; this.m_shift_coord_x=0; this.m_shift_coord_y=0; } //--- Destructor ~CGCnvBitmap() { this.m_canvas.Destroy(); } //+------------------------------------------------------------------+ //| Methods of simplified access to object properties | //+------------------------------------------------------------------+ //--- Set the (1) time and (2) price coordinate or (3) both bool SetTime(const datetime time); bool SetPrice(const double price); bool SetTimePrice(const datetime time,const double price); //--- Return (1) time and (2) price coordinate datetime Time(void) const { return this.m_time; } double Price(void) const { return this.m_price; } };
Alle Konstruktoren sind eine Kopie der Konstruktoren der übergeordneten Klasse und verwenden bei der Initialisierung den Standardkonstruktor der übergeordneten Klasse:
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CGCnvBitmap::CGCnvBitmap(const ENUM_GRAPH_ELEMENT_TYPE element_type, CGCnvElement *main_obj,CGCnvElement *base_obj, const int element_id, const int element_num, const long chart_id, const int wnd_num, const string descript, const datetime time, const double price, const int w, const int h, const color colour, const uchar opacity, const bool movable=false, const bool activity=true, const bool redraw=false) { this.SetTypeElement(element_type); this.m_type=OBJECT_DE_TYPE_GBITMAP; this.m_element_main=main_obj; this.m_element_base=base_obj; this.m_chart_color_bg=(color)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_COLOR_BACKGROUND); this.m_name=this.CreateNameGraphElement(element_type); this.m_chart_id=(chart_id==NULL || chart_id==0 ? ::ChartID() : chart_id); this.m_subwindow=wnd_num; this.SetFont(DEF_FONT,DEF_FONT_SIZE); this.SetTextAnchor(0); this.SetTextLastX(0); this.SetTextLastY(0); this.SetBackgroundColor(colour,true); this.SetOpacity(opacity); this.m_shift_coord_x=0; this.m_shift_coord_y=0; if(::ArrayResize(this.m_array_colors_bg,1)==1) this.m_array_colors_bg[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_dwn,1)==1) this.m_array_colors_bg_dwn[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_ovr,1)==1) this.m_array_colors_bg_ovr[0]=this.BackgroundColor(); if(this.Create(chart_id,wnd_num,0,0,w,h,redraw)) { this.Initialize(element_type,element_id,element_num,0,0,w,h,descript,movable,activity); this.SetVisibleFlag(false,false); this.SetTimePrice(time,price); } else { ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),"\"",this.TypeElementDescription(element_type),"\" ",this.NameObj()); } } //+------------------------------------------------------------------+ //| Protected constructor | //+------------------------------------------------------------------+ CGCnvBitmap::CGCnvBitmap(const ENUM_GRAPH_ELEMENT_TYPE element_type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int wnd_num, const string descript, const datetime time, const double price, const int w, const int h) { this.m_type=OBJECT_DE_TYPE_GBITMAP; this.m_element_main=main_obj; this.m_element_base=base_obj; this.m_chart_color_bg=(color)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_COLOR_BACKGROUND); this.m_name=this.CreateNameGraphElement(element_type); this.m_chart_id=(chart_id==NULL || chart_id==0 ? ::ChartID() : chart_id); this.m_subwindow=wnd_num; this.m_type_element=element_type; this.SetFont(DEF_FONT,DEF_FONT_SIZE); this.SetTextAnchor(0); this.SetTextLastX(0); this.SetTextLastY(0); this.SetBackgroundColor(CLR_CANV_NULL,true); this.SetOpacity(0); this.m_shift_coord_x=0; this.m_shift_coord_y=0; this.m_shadow=false; if(::ArrayResize(this.m_array_colors_bg,1)==1) this.m_array_colors_bg[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_dwn,1)==1) this.m_array_colors_bg_dwn[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_ovr,1)==1) this.m_array_colors_bg_ovr[0]=this.BackgroundColor(); if(this.Create(chart_id,wnd_num,0,0,w,h,false)) { this.Initialize(element_type,0,0,0,0,w,h,descript,false,false); this.SetVisibleFlag(false,false); this.SetTimePrice(time,price); } else { ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),"\"",this.TypeElementDescription(element_type),"\" ",this.NameObj()); } }
Hier verwenden wir den Standardkonstruktor der übergeordneten Klasse, da in ihm alle Objektparameter gesetzt werden und das Objekt erstellt wird. Um die Parameter in diesem Konstruktor nicht neu zu definieren und um ein Objekt eines neuen Typs nicht zu löschen und neu zu erstellen, machen wir das alles gleich hier, in diesen Konstruktoren, unter Verwendung des Standardkonstruktors des übergeordneten Objekts.
Die virtuelle Methode zur Erstellung eines grafischen Bitmap-Objekts:
//+------------------------------------------------------------------+ //| Create the graphical bitmap object | //+------------------------------------------------------------------+ bool CGCnvBitmap::Create(const long chart_id, // Chart ID const int wnd_num, // Chart subwindow const int x, // X coordinate const int y, // Y coordinate const int w, // Width const int h, // Height const bool redraw=false) // Flag indicating the need to redraw { ::ResetLastError(); if(this.m_canvas.CreateBitmap((chart_id==NULL ? ::ChartID() : chart_id),wnd_num,this.m_name,x,y,w,h,COLOR_FORMAT_ARGB_NORMALIZE)) { this.Erase(CLR_CANV_NULL); this.m_canvas.Update(redraw); this.m_shift_y=(int)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_WINDOW_YDISTANCE,wnd_num); return true; } int err=::GetLastError(); int code=(err==0 ? (w<1 ? MSG_CANV_ELEMENT_ERR_FAILED_SET_WIDTH : h<1 ? MSG_CANV_ELEMENT_ERR_FAILED_SET_HEIGHT : ERR_OBJECT_ERROR) : err); string subj=(w<1 ? "Width="+(string)w+". " : h<1 ? "Height="+(string)h+". " : ""); CMessage::ToLog(DFUN_ERR_LINE+subj,code,true); return false; }
Im Gegensatz zur gleichen Methode der Elternklasse wird hier die Methode verwendet, um die Methode CreateBitmap() der Klasse CCanvas anstelle der Methode CreateBitmapLabel() zu erstellen. Dies ist der einzige Unterschied zwischen dieser Methode und der Methode der übergeordneten Klasse.
Die Methoden zum Festlegen von Preis- und Zeitkoordinaten für ein Bitmap-Objekt:
//+------------------------------------------------------------------+ //| Set the time coordinate | //+------------------------------------------------------------------+ bool CGCnvBitmap::SetTime(const datetime time) { string name=this.NameObj(); if(name==NULL || name=="") return false; ::ResetLastError(); if(!::ObjectSetInteger(this.ChartID(),name,OBJPROP_TIME,time)) { ::PrintFormat("%s%s. %s %s",DFUN,CMessage::Text(MSG_ERR_FAILED_SET_BITMAP_OBJ_TIME),CMessage::Text(MSG_LIB_SYS_ERROR),::GetLastError()); return false; } this.m_time=time; return true; } //+------------------------------------------------------------------+ //| Set the price coordinate | //+------------------------------------------------------------------+ bool CGCnvBitmap::SetPrice(const double price) { string name=this.NameObj(); if(name==NULL || name=="") return false; ::ResetLastError(); if(!::ObjectSetDouble(this.ChartID(),name,OBJPROP_PRICE,price)) { ::PrintFormat("%s%s. %s %s",DFUN,CMessage::Text(MSG_ERR_FAILED_SET_BITMAP_OBJ_PRICE),CMessage::Text(MSG_LIB_SYS_ERROR),::GetLastError()); return false; } this.m_price=price; return true; } //+------------------------------------------------------------------+ //| Set both coordinates | //+------------------------------------------------------------------+ bool CGCnvBitmap::SetTimePrice(const datetime time,const double price) { if(!this.SetTime(time)) return false; return this.SetPrice(price); } //+------------------------------------------------------------------+Kurz gesagt: Wenn es nicht möglich war, eine Eigenschaft in einem grafischen Objekt zu setzen, zeigen wir eine entsprechende Meldung im Journal an und geben false zurück.
Wenn eine Eigenschaft erfolgreich auf ein Objekt gesetzt wird, wird ein neuer Wert in die Klassenvariable geschrieben und true zurückgegeben.
Wir deklarieren in der Verwaltungsklasse für grafische Elemente in der Datei \MQL5\Include\DoEasy\Objects\Graph\GraphElmControl.mqh die Methode zur Erstellung eines Bitmap-Objekts:
//+------------------------------------------------------------------+ //| Class for managing graphical elements | //+------------------------------------------------------------------+ class CGraphElmControl : public CObject { private: int m_type; // Object type int m_type_node; // Type of the object the graphics is constructed for //--- Set general parameters for standard graphical objects void SetCommonParamsStdGraphObj(const long chart_id,const string name); public: //--- Return itself CGraphElmControl *GetObject(void) { return &this; } //--- Set a type of the object the graphics is constructed for void SetTypeNode(const int type_node) { this.m_type_node=type_node; } //--- Create a form object CForm *CreateForm(const int form_id,const long chart_id,const int wnd,const string name,const int x,const int y,const int w,const int h); CForm *CreateForm(const int form_id,const int wnd,const string name,const int x,const int y,const int w,const int h); CForm *CreateForm(const int form_id,const string name,const int x,const int y,const int w,const int h); //--- Create Bitmap object CGCnvBitmap *CreateBitmap(const int obj_id,const long chart_id,const int wnd,const string name,const datetime time,const double price,const int w,const int h,const color clr); //--- Creates the trend line standard graphical object
Nun schreiben wir die Implementierung außerhalb des Hauptteils der Klasse:
//+------------------------------------------------------------------+ //| Create Bitmap object | //+------------------------------------------------------------------+ CGCnvBitmap *CGraphElmControl::CreateBitmap(const int obj_id,const long chart_id,const int wnd,const string name,const datetime time,const double price,const int w,const int h,const color clr) { CGCnvBitmap *obj=new CGCnvBitmap(GRAPH_ELEMENT_TYPE_BITMAP,NULL,NULL,obj_id,0,chart_id,wnd,name,time,price,w,h,clr,200); return obj; }
Die Methode erstellt ein neues Objekt der Klasse CDCnvBitmap mit den übergebenen Parametern und einer Deckkraft von 200 und gibt den Zeiger auf das erstellte Objekt zurück.
Wir schreiben nun in die Basisobjektklasse der CBaseObj-Bibliothek, d. h. in die Datei \MQL5\Include\DoEasy\Objects\BaseObj.mqh, die Methoden zur Erstellung eines Bitmap-Objekts:
//+------------------------------------------------------------------+ //| Methods for handling graphical elements | //+------------------------------------------------------------------+ //--- Create a form object on a specified chart in a specified subwindow CForm *CreateForm(const int form_id,const long chart_id,const int wnd,const string name,const int x,const int y,const int w,const int h) { return this.m_graph_elm.CreateForm(form_id,chart_id,wnd,name,x,y,w,h); } //--- Create a form object on the current chart in a specified subwindow CForm *CreateForm(const int form_id,const int wnd,const string name,const int x,const int y,const int w,const int h) { return this.m_graph_elm.CreateForm(form_id,wnd,name,x,y,w,h); } //--- Create the form object on the current chart in the main window CForm *CreateForm(const int form_id,const string name,const int x,const int y,const int w,const int h) { return this.m_graph_elm.CreateForm(form_id,name,x,y,w,h); } //--- Create a bitmap object on a specified chart in a specified subwindow CGCnvBitmap *CreateBitmap(const int obj_id,const long chart_id,const int wnd,const string name,const datetime time,const double price,const int w,const int h,const color clr) { return this.m_graph_elm.CreateBitmap(obj_id,chart_id,wnd,name,time,price,w,h,clr); } //--- Create a bitmap object on the current chart in a specified subwindow CGCnvBitmap *CreateBitmap(const int obj_id,const int wnd,const string name,const datetime time,const double price,const int w,const int h,const color clr) { return this.m_graph_elm.CreateBitmap(obj_id,::ChartID(),wnd,name,time,price,w,h,clr);} //--- Create the bitmap object on the current chart in the main window CGCnvBitmap *CreateBitmap(const int obj_id,const string name,const datetime time,const double price,const int w,const int h,const color clr) { return this.m_graph_elm.CreateBitmap(obj_id,::ChartID(),0,name,time,price,w,h,clr); } //--- Create a standard graphical trend line object in the specified subwindow of the specified chart
Drei Methoden zum Erstellen eines Zeichnungsobjekts (1) auf dem angegebenen Chart im angegebenen Unterfenster, (2) auf dem aktuellen Chart im angegebenen Unterfenster und (3) auf dem aktuellen Chart im Hauptfenster. Die Methoden geben einfach das Ergebnis des Aufrufs der Methode zur Erstellung eines Bitmap-Objekts der Klasse CGraphElmControl mit den oben angegebenen Parametern zurück.
Jetzt können wir ein Zeichenobjekt aus einem beliebigen Bibliotheksobjekt erstellen, um etwas visuell zu gestalten. Übrigens konnten wir früher schon einige grafische Primitive und GUI-Elemente aus beliebigen Bibliotheksobjekten erstellen. Jetzt wurde der Liste ein Bitmap-Objekt hinzugefügt.
Die Klasse des grafischen Formularobjekts wird von der Klasse des grafischen Elements geerbt. Dementsprechend ist die grafische Elementdatei mit der Formularobjektklassendatei verbunden. Da wir nun eine weitere Klasse haben, die von dem grafischen Element geerbt wurde - die Bitmap-Objektklasse -, werden wir, um alle diese Klassen optimal miteinander zu verbinden, die Bitmap-Objektklassendatei mit der Formularobjektklassendatei verbinden. Da diese Klasse von dem grafischen Element abgeleitet ist, sind beide Klassen in der Formularobjektklasse verfügbar.
Die Formularobjektklassendatei \MQL5\Include\DoEasy\Objects\Graph\Form.mqh erhält die Bitmap-Objektklassendatei anstelle der grafischen Elementdatei:
//+------------------------------------------------------------------+ //| Form.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "GCnvBitmap.mqh" #include "ShadowObj.mqh" #include "Animations\Animations.mqh" #include "..\..\Services\MouseState.mqh" //+------------------------------------------------------------------+ //| Form object class | //+------------------------------------------------------------------+ class CForm : public CGCnvElement {
Jetzt sind sowohl das Elementobjekt als auch das Bitmap-Objekt im Formularobjekt verfügbar. Dementsprechend werden in anderen Dateien, in denen das Element-Objekt benötigt wird, beide Objekte verfügbar sein.
Tragen wir die gefundenen Objekte in das Balkenobjekt ein.
Dazu schreiben wir in den öffentlichen Abschnitt der Datei der Balken-Objektklasse \MQL5\Include\DoEasy\Objects\Series\Bar.mqh die Methode, die einen neuen Mustertyp zur Balken-Eigenschaft hinzufügt:
//--- Return itself CBar *GetObject(void) { return &this;} //--- Set (1) bar symbol, timeframe and time, (2) bar object parameters void SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES timeframe,const datetime time); void SetProperties(const MqlRates &rates); //--- Add the pattern type on bar void AddPattern(const ENUM_PATTERN_TYPE pattern_type) { this.m_long_prop[BAR_PROP_PATTERNS_TYPE] |=pattern_type; } //--- Compare CBar objects by all possible properties (for sorting the lists by a specified bar object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CBar objects by all properties (to search for equal bar objects) bool IsEqual(CBar* compared_bar) const; //--- Constructors CBar(){ this.m_type=OBJECT_DE_TYPE_SERIES_BAR; } CBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const datetime time,const string source); CBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const MqlRates &rates);
Die Methode empfängt den Mustertyp, und sein Wert (Bitmaske) wird zum Wert der Eigenschaft BAR_PROP_PATTERNS_TYPE hinzugefügt. Mit dem logischen Operator „oder“ können wir einer Variablen verschiedene Typen hinzufügen, ohne den Variablenwert zu überschreiben. So können mehrere verschiedene Arten von Mustern in einer Variablen gespeichert werden.
Im Abschnitt Beschreibungen der Balken-Eigenschaften, deklarieren wir die Methode, die eine Liste von Mustern im übergebenen Array zurückgibt und die Methode, die eine Liste von Mustern auf einem Balken an das Journal ausgibt:
//+------------------------------------------------------------------+ //| Descriptions of bar object properties | //+------------------------------------------------------------------+ //--- Get description of a bar's (1) integer, (2) real and (3) string properties string GetPropertyDescription(ENUM_BAR_PROP_INTEGER property); string GetPropertyDescription(ENUM_BAR_PROP_DOUBLE property); string GetPropertyDescription(ENUM_BAR_PROP_STRING property); //--- Return the bar type description string BodyTypeDescription(void) const; //--- Display the description of the object properties in the journal (full_prop=true - all properties, false - supported ones only - implemented in descendant classes) virtual void Print(const bool full_prop=false,const bool dash=false); //--- Display a short description of the object in the journal virtual void PrintShort(const bool dash=false,const bool symbol=false); //--- Return the (1) short name, (2) description of bar object parameters and (3) a list of patterns in the passed array virtual string Header(void); string ParameterDescription(void); int GetPatternsList(ulong &array[]); //--- Display a list of patterns on the bar in the journal void PatternTypeDescriptionPrint(const bool dash=false); //--- };
Wir setzen in der Methode, die die Parameter des Balkenobjekts festlegt, den Mustertyp des Balkens als nicht vorhanden fest (der Variablenwert ist Null):
//+------------------------------------------------------------------+ //| Set bar object parameters | //+------------------------------------------------------------------+ void CBar::SetProperties(const MqlRates &rates) { this.SetProperty(BAR_PROP_SPREAD,rates.spread); this.SetProperty(BAR_PROP_VOLUME_TICK,rates.tick_volume); this.SetProperty(BAR_PROP_VOLUME_REAL,rates.real_volume); this.SetProperty(BAR_PROP_TIME,rates.time); this.SetProperty(BAR_PROP_TIME_YEAR,this.TimeYear()); this.SetProperty(BAR_PROP_TIME_MONTH,this.TimeMonth()); this.SetProperty(BAR_PROP_TIME_DAY_OF_YEAR,this.TimeDayOfYear()); this.SetProperty(BAR_PROP_TIME_DAY_OF_WEEK,this.TimeDayOfWeek()); this.SetProperty(BAR_PROP_TIME_DAY,this.TimeDay()); this.SetProperty(BAR_PROP_TIME_HOUR,this.TimeHour()); this.SetProperty(BAR_PROP_TIME_MINUTE,this.TimeMinute()); //--- this.SetProperty(BAR_PROP_OPEN,rates.open); this.SetProperty(BAR_PROP_HIGH,rates.high); this.SetProperty(BAR_PROP_LOW,rates.low); this.SetProperty(BAR_PROP_CLOSE,rates.close); this.SetProperty(BAR_PROP_CANDLE_SIZE,this.CandleSize()); this.SetProperty(BAR_PROP_CANDLE_SIZE_BODY,this.BodySize()); this.SetProperty(BAR_PROP_CANDLE_BODY_TOP,this.BodyHigh()); this.SetProperty(BAR_PROP_CANDLE_BODY_BOTTOM,this.BodyLow()); this.SetProperty(BAR_PROP_CANDLE_SIZE_SHADOW_UP,this.ShadowUpSize()); this.SetProperty(BAR_PROP_CANDLE_SIZE_SHADOW_DOWN,this.ShadowDownSize()); //--- this.SetProperty(BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE,this.CandleRatioBodyToCandleSize()); this.SetProperty(BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,this.CandleRatioUpperShadowToCandleSize()); this.SetProperty(BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,this.CandleRatioLowerShadowToCandleSize()); this.SetProperty(BAR_PROP_PATTERNS_TYPE,0); this.SetProperty(BAR_PROP_TYPE,this.BodyType()); //--- Set the object type to the object of the graphical object management class this.m_graph_elm.SetTypeNode(this.m_type); }
Außerhalb des Klassenkörpers schreiben wir die Methode, die eine Liste der Muster im übergebenen Array zurückgibt:
//+------------------------------------------------------------------+ //| Return the list of patterns in the passed array | //+------------------------------------------------------------------+ int CBar::GetPatternsList(ulong &array[]) { return ListPatternsInVar(this.GetProperty(BAR_PROP_PATTERNS_TYPE),array); }
Das Array wird an die Methode übergeben und das Ergebnis der Ausführung der oben implementierten Funktion ListPatternsInVar() wird zurückgegeben. In diesem Fall wird die Liste aller Muster auf dem Balken in das Array gestellt, das durch den Link an die Methode übergeben wird.
Die Methode zur Anzeige die Beschreibung der Muster eines Balkens im Journal:
//+------------------------------------------------------------------+ //| Display the description of patterns on the bar in the journal | //+------------------------------------------------------------------+ void CBar::PatternTypeDescriptionPrint(const bool dash=false) { ulong patt=this.GetProperty(BAR_PROP_PATTERNS_TYPE); ::Print(CMessage::Text(MSG_LIB_TEXT_BAR_PATTERNS_TYPE),": ",(patt>0 ? "" : CMessage::Text(MSG_LIB_PROP_EMPTY))); if(patt>0) ::Print(PatternsInVarDescription(patt,dash)); }
Zuvor haben wir die Funktion PatternsInVarDescription() geschrieben, die eine Zeichenkette mit Beschreibungen aller Muster zurückgibt, deren Flags in der Variablen enthalten sind. Hier senden wir den Wert der Variablen, die die Balken-Eigenschaft BAR_PROP_PATTERNS_TYPE speichert, an diese Funktion und drucken die von der Funktion erhaltene Zeichenkette in das Journal.
Wir fügen in der Methode, die die Beschreibung der Eigenschaft Balken integer zurückgibt, die Rückgabe der Beschreibung des Eigenschaftswerts BAR_PROP_PATTERNS_TYPE hinzu:
//+------------------------------------------------------------------+ //| Return the description of the bar integer property | //+------------------------------------------------------------------+ string CBar::GetPropertyDescription(ENUM_BAR_PROP_INTEGER property) { return ( property==BAR_PROP_TIME ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES|TIME_SECONDS) ) : property==BAR_PROP_TYPE ? CMessage::Text(MSG_ORD_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.BodyTypeDescription() ) : property==BAR_PROP_PERIOD ? CMessage::Text(MSG_LIB_TEXT_BAR_PERIOD)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.m_period_description ) : property==BAR_PROP_SPREAD ? CMessage::Text(MSG_LIB_TEXT_BAR_SPREAD)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==BAR_PROP_VOLUME_TICK ? CMessage::Text(MSG_LIB_TEXT_BAR_VOLUME_TICK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==BAR_PROP_VOLUME_REAL ? CMessage::Text(MSG_LIB_TEXT_BAR_VOLUME_REAL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==BAR_PROP_TIME_YEAR ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_YEAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.Year() ) : property==BAR_PROP_TIME_MONTH ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_MONTH)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+MonthDescription((int)this.Month()) ) : property==BAR_PROP_TIME_DAY_OF_YEAR ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_DAY_OF_YEAR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::IntegerToString(this.DayOfYear(),3,'0') ) : property==BAR_PROP_TIME_DAY_OF_WEEK ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_DAY_OF_WEEK)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+DayOfWeekDescription((ENUM_DAY_OF_WEEK)this.DayOfWeek()) ) : property==BAR_PROP_TIME_DAY ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_DAY)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::IntegerToString(this.Day(),2,'0') ) : property==BAR_PROP_TIME_HOUR ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_HOUR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::IntegerToString(this.Hour(),2,'0') ) : property==BAR_PROP_TIME_MINUTE ? CMessage::Text(MSG_LIB_TEXT_BAR_TIME_MINUTE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::IntegerToString(this.Minute(),2,'0') ) : property==BAR_PROP_PATTERNS_TYPE ? CMessage::Text(MSG_LIB_TEXT_BAR_PATTERNS_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(this.GetProperty(property)==0 ? CMessage::Text(MSG_LIB_PROP_NOT_FOUND) : "\n"+PatternsInVarDescription(this.GetProperty(property),true)) ) : "" ); }
Lassen Sie uns Verbesserungen an der Datei \MQL5\Include\DoEasy\Objects\Series\Patterns\Pattern.mqh vornehmen.
Da wir den Zeiger auf das Balkenobjekt, auf dem das Muster gefunden wurde, auf das Musterobjekt setzen werden, müssen wir die Klassendatei des Balkenobjekts in die Klassendatei des Musterobjekts aufnehmen. Das Muster hat eine Basis und einen „Mutterbalken“. Für den Basisbalken verwenden wir den Zeiger auf das Balkenobjekt (den Balken, auf dem das Muster gefunden wurde). Im Falle des „Mutter“-Balkens erstellen wir die MqlRates-Struktur, in der die Balkendaten gespeichert werden sollen. Auf diese Weise haben wir immer alle Daten über die Balken, die von dem Muster „abgedeckt“ werden. Wenn es sich übrigens um ein Muster aus einem Balken handelt, sind der Mutter- und der Basisbalken derselbe Balken. Wir werden das Muster mit Hilfe des Bitmap-Objekts „umreißen“, dessen Klasse hier erstellt wurde. Wir deklarieren den Zeiger auf das Klassenobjekt im geschützten Abschnitt der abstrakten Musterobjektklasse. Um die erforderliche Größe des Musters für die Balken des Musters berechnen zu können, müssen wir die Abmessungen und Parameter des Charts kennen. Wir deklarieren die Variablen zum Speichern der Chartparameter, die zur Berechnung der Größe des Bitmap-Objekts erforderlich sind.
//+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\..\BaseObj.mqh" #include "..\Bar.mqh" //+------------------------------------------------------------------+ //| Abstract pattern class | //+------------------------------------------------------------------+ class CPattern : public CBaseObj { private: CBar *m_bar_pattern; // Pointer to the bar the pattern is formed on MqlRates m_mother_bar_prop; // "Mother" bar parameters long m_long_prop[PATTERN_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[PATTERN_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[PATTERN_PROP_STRING_TOTAL]; // String properties //--- Return the index of the array the pattern (1) double and (2) string properties are located at int IndexProp(ENUM_PATTERN_PROP_DOUBLE property) const { return(int)property-PATTERN_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_PATTERN_PROP_STRING property) const { return(int)property-PATTERN_PROP_INTEGER_TOTAL-PATTERN_PROP_DOUBLE_TOTAL;} protected: CForm *m_form; // Pointer to form object CGCnvBitmap *m_bitmap; // Pointer to the bitmap object int m_digits; // Symbol's digits value ulong m_symbol_code; // Symbol as a number (sum of name symbol codes) string m_name_graph_obj; // Name of the graphical object displaying the pattern double m_price; // Price level the graphical object is placed at color m_color_bullish; // Color of a graphical object set to the bullish pattern icon color m_color_bearish; // Color of a graphical object set to the bearish pattern icon color m_color_bidirect; // Color of a graphical object set to the bidirectional pattern icon color m_color; // Graphical object color color m_color_panel_bullish; // Bullish pattern panel color color m_color_panel_bearish; // Bearish pattern panel color color m_color_panel_bidirect; // Bidirectional pattern panel color int m_bars_formation; // Number of bars in the formation (nested pattern) bool m_draw_dots; // Draw on the chart with dots int m_chart_scale; // Chart scale int m_chart_height_px; // Height of the chart in pixels double m_chart_price_max; // Chart maximum double m_chart_price_min; // Chart minimum public:
Wir fügen im öffentlichen Abschnitt der Klasse die Methoden zum Setzen und Zurückgeben neuer Eigenschaften und Zeiger hinzu:
public: //--- Set pattern (1) integer, (2) real and (3) string properties void SetProperty(ENUM_PATTERN_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_PATTERN_PROP_DOUBLE property,double value){ this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_PATTERN_PROP_STRING property,string value){ this.m_string_prop[this.IndexProp(property)]=value; } //--- Return (1) integer, (2) real and (3) string pattern properties from the property array long GetProperty(ENUM_PATTERN_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_PATTERN_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_PATTERN_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Return the flag of the pattern supporting the specified property virtual bool SupportProperty(ENUM_PATTERN_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_PATTERN_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_PATTERN_PROP_STRING property) { return true; } //--- Return itself CPattern *GetObject(void) { return &this; } CForm *GetForm(void) { return this.m_form;} //--- Compare CPattern objects by all possible properties (for sorting the lists by a specified pattern object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CPattern objects with each other by all properties (to search equal pattern objects) bool IsEqual(CPattern* compared_obj) const; //--- Constructors CPattern(){ this.m_type=OBJECT_DE_TYPE_SERIES_PATTERN; } protected: //--- Protected parametric constructor CPattern(const ENUM_PATTERN_STATUS status, const ENUM_PATTERN_TYPE type, const uint id, const ENUM_PATTERN_DIRECTION direction, const string symbol, const ENUM_TIMEFRAMES timeframe,MqlRates &rates); public: //--- Destructor ~CPattern(void); //+------------------------------------------------------------------+ //| Methods of a simplified access to the pattern object properties | //+------------------------------------------------------------------+ //--- Return (1) type, (2) direction, (3) period, (4) status, //--- (5) code, (6) pattern defining bar time, //--- (7) number of candles forming the pattern ENUM_PATTERN_TYPE TypePattern(void) const { return (ENUM_PATTERN_TYPE)this.GetProperty(PATTERN_PROP_TYPE); } ENUM_PATTERN_DIRECTION Direction(void) const { return (ENUM_PATTERN_DIRECTION)this.GetProperty(PATTERN_PROP_DIRECTION); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(PATTERN_PROP_PERIOD); } ENUM_PATTERN_STATUS Status(void) const { return (ENUM_PATTERN_STATUS)this.GetProperty(PATTERN_PROP_STATUS); } ulong Code(void) const { return this.GetProperty(PATTERN_PROP_CODE); } uint ID(void) const { return (uint)this.GetProperty(PATTERN_PROP_ID); } ulong ControlObjectID(void) const { return this.GetProperty(PATTERN_PROP_CTRL_OBJ_ID); } datetime Time(void) const { return (datetime)this.GetProperty(PATTERN_PROP_TIME); } uint Candles(void) const { return (uint)this.GetProperty(PATTERN_PROP_CANDLES); } //--- Return pattern defining bar prices double BarPriceOpen(void) const { return this.GetProperty(PATTERN_PROP_BAR_PRICE_OPEN); } double BarPriceHigh(void) const { return this.GetProperty(PATTERN_PROP_BAR_PRICE_HIGH); } double BarPriceLow(void) const { return this.GetProperty(PATTERN_PROP_BAR_PRICE_LOW); } double BarPriceClose(void) const { return this.GetProperty(PATTERN_PROP_BAR_PRICE_CLOSE); } //--- Return pattern (1) symbol and (2) name string Symbol(void) const { return this.GetProperty(PATTERN_PROP_SYMBOL); } string Name(void) const { return this.GetProperty(PATTERN_PROP_NAME); } //--- Set the pointer to the (1) pattern bar, (2) "mother" bar data void SetPatternBar(CBar *bar) { this.m_bar_pattern=bar; } void SetMotherBarData(MqlRates &data); //--- Set the (1) "mother" bar OHLC and (2) the number of bars in nested formations void SetMotherBarOpen(const double open) { this.m_mother_bar_prop.open=open; } void SetMotherBarHigh(const double high) { this.m_mother_bar_prop.high=high; } void SetMotherBarLow(const double low) { this.m_mother_bar_prop.low=low; } void SetMotherBarClose(const double close) { this.m_mother_bar_prop.close=close; } void SetBarsInNestedFormations(const int bars) { this.m_bars_formation=bars; } //--- Return the pointer to the (1) pattern bar, (2) time, (3 - 6) "mother" bar OHLC and (7) the number of bars in nested formations CBar *PatternBar(void) const { return this.m_bar_pattern; } datetime MotherBarTime(void) const { return (datetime)this.GetProperty(PATTERN_PROP_MOTHERBAR_TIME); } double MotherBarOpen(void) const { return this.m_mother_bar_prop.open; } double MotherBarHigh(void) const { return this.m_mother_bar_prop.high; } double MotherBarLow(void) const { return this.m_mother_bar_prop.low; } double MotherBarClose(void) const { return this.m_mother_bar_prop.close; } int BarsInNestedFormations(void) const { return this.m_bars_formation; } //+------------------------------------------------------------------+ //| Descriptions of pattern object properties | //+------------------------------------------------------------------+ //--- Get description of pattern (1) integer, (2) real and (3) string property string GetPropertyDescription(ENUM_PATTERN_PROP_INTEGER property); string GetPropertyDescription(ENUM_PATTERN_PROP_DOUBLE property); string GetPropertyDescription(ENUM_PATTERN_PROP_STRING property); //--- Return description of the pattern (1) status, (2) type and (3) direction virtual string StatusDescription(void) const { return NULL; } virtual string TypeDescription(void) const { return NULL; } string DirectDescription(void) const; //--- Display the description of the object properties in the journal (full_prop=true - all properties, false - supported ones only - implemented in descendant classes) virtual void Print(const bool full_prop=false,const bool dash=false); //--- Display a short description of the object in the journal virtual void PrintShort(const bool dash=false,const bool symbol=false); //--- Return a short name of a pattern object virtual string Header(void); //+------------------------------------------------------------------+ //| Handle graphical display | //+------------------------------------------------------------------+ protected: //--- Set graphical object display colors for the (1) bullish, (2) bearish and (3) bidirectional pattern void SetColorBullish(const color clr) { this.m_color_bullish=clr; } void SetColorBearish(const color clr) { this.m_color_bearish=clr; } void SetColorBiDirect(const color clr) { this.m_color_bidirect=clr; } //--- Create the (1) info panel and (2) Bitmap object bool CreateInfoPanel(void); virtual bool CreateBitmap(void); //--- Create the info panel appearance virtual void CreateInfoPanelView(void){} //--- Calculate the bitmap object (1) width and (2) height int GetBitmapWidth(void); int GetBitmapHeight(void); public: //--- Remove a graphical object bool DeleteGraphObj(bool redraw=false); //--- Set graphical object display colors and pattern display color void SetColors(const color color_bullish,const color color_bearish,const color color_bidirect,const bool redraw=false); //--- Set the flag for drawing pattern labels as dots void SetDrawAsDots(const bool flag) { this.m_draw_dots=flag; } //--- Set the background color for the (1) bullish, (2) bearish and (3) bidirectional pattern panel void SetColorPanelBullish(const color clr) { this.m_color_panel_bullish=clr; } void SetColorPanelBearish(const color clr) { this.m_color_panel_bearish=clr; } void SetColorPanelBiDirect(const color clr) { this.m_color_panel_bidirect=clr; } //--- Set the background color for the (1) bullish, (2) bearish and (3) bidirectional pattern panel by setting the values of the RGB color components void SetColorPanelBullish(const uchar R,const uchar G,const uchar B); void SetColorPanelBearish(const uchar R,const uchar G,const uchar B); void SetColorPanelBiDirect(const uchar R,const uchar G,const uchar B); //--- Draw the pattern icon on the chart virtual void Draw(const bool redraw); //--- (1) Display, (2) hide the pattern icon on the chart void Show(const bool redraw=false); void Hide(const bool redraw=false); //--- (1) Display and (2) hide the info panel on the chart void ShowInfoPanel(const int x,const int y,const bool redraw=true); void HideInfoPanel(void); //--- Change the bitmap object (1) width, (2) height and (3) size bool BitmapSetWidth(const int width); bool BitmapSetHeight(const int height); bool BitmapResize(const int w,const int h); //--- Set the (1) chart scale, (2) chart height in pixels, (3) chart maximum and (3) minimum void SetChartScale(const int scale) { this.m_chart_scale=scale; } void SetChartHeightInPixels(const int height) { this.m_chart_height_px=height; } void SetChartPriceMax(const double price) { this.m_chart_price_max=price; } void SetChartPriceMin(const double price) { this.m_chart_price_min=price; } //--- Return the (1) chart scale, (2) chart height in pixels, (3) chart maximum and (3) minimum int ChartScale(void) const { return this.m_chart_scale; } int ChartHeightInPixels(void) const { return this.m_chart_height_px; } double ChartPriceMax(void) const { return this.m_chart_price_max; } double ChartPriceMin(void) const { return this.m_chart_price_min; } };
Im Konstruktor der abstrakten Musterklasse ersetzen wir die Farbe der bidirektionalen Musterbeschriftung und setzen die Standardwerte für den Zeiger auf das Bildobjekt (NULL), für das Flag zum Zeichnen mit Punkten (true) und für die Anzahl der verschachtelten Formationen gleich 1 (keine verschachtelten Muster):
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPattern::CPattern(const ENUM_PATTERN_STATUS status,const ENUM_PATTERN_TYPE type,const uint id,const ENUM_PATTERN_DIRECTION direction,const string symbol,const ENUM_TIMEFRAMES timeframe,MqlRates &rates) { //--- Set pattern object properties this.m_digits=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS); this.m_type=OBJECT_DE_TYPE_SERIES_PATTERN; this.SetProperty(PATTERN_PROP_STATUS,status); this.SetProperty(PATTERN_PROP_TYPE,type); this.SetProperty(PATTERN_PROP_ID,id); this.SetProperty(PATTERN_PROP_DIRECTION,direction); this.SetProperty(PATTERN_PROP_PERIOD,timeframe); this.SetProperty(PATTERN_PROP_TIME,rates.time); this.SetProperty(PATTERN_PROP_BAR_PRICE_OPEN,rates.open); this.SetProperty(PATTERN_PROP_BAR_PRICE_HIGH,rates.high); this.SetProperty(PATTERN_PROP_BAR_PRICE_LOW,rates.low); this.SetProperty(PATTERN_PROP_BAR_PRICE_CLOSE,rates.close); this.SetProperty(PATTERN_PROP_SYMBOL,symbol); //--- Create symbol code this.m_symbol_code=0; for(int i=0;i<(int)symbol.Length();i++) this.m_symbol_code+=symbol.GetChar(i); //--- Pattern code = defining bar time + type + status + pattern direction + timeframe + symbol code ulong code=(ulong)rates.time+type+status+direction+timeframe+this.m_symbol_code; this.SetProperty(PATTERN_PROP_CODE,code); //--- Set pattern graphical objects parameters (chart labels) this.m_name_graph_obj=::StringFormat("%s_p%lu",this.m_name_program,code); this.m_color_bullish=clrBlue; this.m_color_bearish=clrRed; this.m_color_bidirect=clrMediumSeaGreen; if(this.Direction()==PATTERN_DIRECTION_BULLISH) { this.m_color=this.m_color_bullish; this.m_price=rates.low; } else if(this.Direction()==PATTERN_DIRECTION_BEARISH) { this.m_color=this.m_color_bearish; this.m_price=rates.high; } else { this.m_color=this.m_color_bidirect; this.m_price=(rates.open+rates.close)/2; } //--- Set base colors of the pattern information panels this.m_color_panel_bullish=clrLightGray; this.m_color_panel_bearish=clrLightGray; this.m_color_panel_bidirect=clrLightGray; this.m_form=NULL; this.m_bitmap=NULL; this.m_draw_dots=true; this.m_bars_formation=1; }
Im Destruktor der Klasse entfernen wir das Bitmap-Objekt:
//+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CPattern::~CPattern(void) { //--- Delete the form object and pattern label on the chart if(this.m_form!=NULL) delete this.m_form; if(this.m_bitmap!=NULL) delete this.m_bitmap; this.DeleteGraphObj(); }
Wir fügen in der Methode, die eine Beschreibung der Integer-Muster-Eigenschaft zurückgibt, die Anzeige der Öffnungszeit des Mutterbalkens hinzu:
//+------------------------------------------------------------------+ //| Return the description of the pattern integer property | //+------------------------------------------------------------------+ string CPattern::GetPropertyDescription(ENUM_PATTERN_PROP_INTEGER property) { return ( property==PATTERN_PROP_CODE ? CMessage::Text(MSG_LIB_TEXT_PATTERN_CODE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==PATTERN_PROP_TIME ? CMessage::Text(MSG_LIB_TEXT_PATTERN_TIME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES) ) : property==PATTERN_PROP_MOTHERBAR_TIME ? CMessage::Text(MSG_LIB_TEXT_PATTERN_MOTHERBAR_TIME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES) ) : property==PATTERN_PROP_STATUS ? CMessage::Text(MSG_ORD_STATUS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.StatusDescription() ) : property==PATTERN_PROP_TYPE ? CMessage::Text(MSG_ORD_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.TypeDescription() ) : property==PATTERN_PROP_ID ? CMessage::Text(MSG_LIB_TEXT_PATTERN_ID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==PATTERN_PROP_CTRL_OBJ_ID ? CMessage::Text(MSG_LIB_TEXT_PATTERN_CTRL_OBJ_ID)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==PATTERN_PROP_DIRECTION ? CMessage::Text(MSG_LIB_TEXT_PATTERN_DIRECTION)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.DirectDescription() ) : property==PATTERN_PROP_PERIOD ? CMessage::Text(MSG_LIB_TEXT_BAR_PERIOD)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+TimeframeDescription((ENUM_TIMEFRAMES)this.GetProperty(property)) ) : property==PATTERN_PROP_CANDLES ? CMessage::Text(MSG_LIB_TEXT_PATTERN_CANDLES)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); }
Implementierung der Methode, die die Daten des „Mutter“-Balkens festlegt:
//+------------------------------------------------------------------+ //| Set the "mother" bar data | //+------------------------------------------------------------------+ void CPattern::SetMotherBarData(MqlRates &data) { this.m_mother_bar_prop.open=data.open; this.m_mother_bar_prop.high=data.high; this.m_mother_bar_prop.low=data.low; this.m_mother_bar_prop.close=data.close; this.m_mother_bar_prop.time=data.time; this.SetProperty(PATTERN_PROP_MOTHERBAR_TIME,data.time); }
Die Methode empfängt die Balkenstruktur, und die erforderlichen Strukturfelder werden auf die entsprechenden Strukturfelder der Struktur der Mitgliedsvariablen der Klasse m_mother_bar_prop gesetzt. Zusätzlich wird die Zeit aus der übergebenen Balkenstruktur in die Zeit-Eigenschaft des Mutterbalkens geschrieben - dieser Wert ist in den Objekteigenschaften vorhanden und sollte korrekt ausgefüllt werden.
Die Methode, die das Info-Panel auf dem Chart anzeigt , erhält die Eingabe, ohne dass das Chart neu gezeichnet werden muss. Das Chart wird neu gezeichnet, wenn der Variablenwert auf true gesetzt wird:
//+------------------------------------------------------------------+ //| Display the info panel on the chart | //+------------------------------------------------------------------+ void CPattern::ShowInfoPanel(const int x,const int y,const bool redraw=true) { //--- If there is no panel object yet, create it if(this.m_form==NULL) if(!this.CreateInfoPanel()) return; //--- Get the chart width and height int chart_w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS); int chart_h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS); //--- Calculate the X and Y coordinates of the panel so that it does not go beyond the chart int cx=(x+this.m_form.Width() >chart_w-1 ? chart_w-1-this.m_form.Width() : x); int cy=(y+this.m_form.Height()>chart_h-1 ? chart_h-1-this.m_form.Height() : y); //--- Set the calculated coordinates and display the panel if(this.m_form.SetCoordX(cx) && this.m_form.SetCoordY(cy)) this.m_form.Show(); if(redraw) ::ChartRedraw(this.m_chart_id); }
Dies wurde so gemacht, dass das Panel mit der Beschreibung des Musters ohne Verzögerung erscheint, nachdem der Mauszeiger über den Balken mit dem Muster bewegt wurde. Wenn es mehrere Muster auf diesem Balken gibt, sollte der Wert dieser Variable für alle Infotafeln, wenn sie auf dem Chart angezeigt werden, auf false gesetzt werden, außer für die letzte, die auf true gesetzt wird. In diesem Fall wird das Chart erst dann neu gezeichnet, wenn das letzte Feld (und nicht jedes einzelne) angezeigt wird.
Da Muster auf zwei Arten im Chart angezeigt werden können - als Punkte und als Bitmap-Objekte - sollten wir die Methode zur Anzeige des Mustersymbols im Chart fertigstellen:
//+------------------------------------------------------------------+ //| Display the pattern icon on the chart | //+------------------------------------------------------------------+ void CPattern::Show(const bool redraw=false) { if(this.m_draw_dots) { ::ObjectSetInteger(this.m_chart_id,this.m_name_graph_obj,OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS); return; } if(this.m_bitmap!=NULL) this.m_bitmap.Show(); if(redraw) ::ChartRedraw(this.m_chart_id); }
Wenn wir Punkte verwenden, schalten wir die Sichtbarkeit des grafischen Objekts wie zuvor ein. Wenn wir das Bitmap-Objekt verwenden, rufen wir dessen Methode Show() auf, falls vorhanden. Wir aktualisieren daher das Chart, wenn das Redraw-Flag gesetzt ist.
Auch verfeinern wir die Methode zum Ausblenden des Mustersymbols im Chart:
//+------------------------------------------------------------------+ //| Hide the pattern icon on the chart | //+------------------------------------------------------------------+ void CPattern::Hide(const bool redraw=false) { if(this.m_draw_dots) { ::ObjectSetInteger(this.m_chart_id,this.m_name_graph_obj,OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS); return; } if(this.m_bitmap!=NULL) this.m_bitmap.Hide(); if(redraw) ::ChartRedraw(this.m_chart_id); }
Die Methode, mit der die Breite des Bitmap-Objekts berechnet wird:
//+------------------------------------------------------------------+ //| Calculate the bitmap object width | //+------------------------------------------------------------------+ int CPattern::GetBitmapWidth(void) { //--- Calculate the width of the chart candles in pixels int px=int(1<<this.m_chart_scale); //--- Calculate the number of bars that make up the pattern int num_bars=::Bars(this.Symbol(),this.Timeframe(),this.MotherBarTime(),this.Time()); if(num_bars==0) num_bars=(int)this.Candles(); //--- Calculate and return the width of the bitmap object return (px*num_bars*2)-px+1; }
Je nach Maßstab des Charts berechnen wir die Breite der Kerzen in Pixeln. Dann wird die Breite des Musters in Balken ermittelt, und aus diesen beiden Werten wird die erforderliche Breite des Musterobjekts berechnet und zurückgegeben.
Die Methode zur Berechnung der Höhe des Zeichnungsobjekts:
//+------------------------------------------------------------------+ //| Calculate the bitmap object height | //+------------------------------------------------------------------+ int CPattern::GetBitmapHeight(void) { //--- Calculate the chart price range and pattern price range double chart_price_range=this.m_chart_price_max-this.m_chart_price_min; double patt_price_range=this.MotherBarHigh()-this.MotherBarLow(); //--- Using the calculated price ranges, calculate and return the height of the bitmap object return (int)ceil(patt_price_range*this.m_chart_height_px/chart_price_range)+8; }
Hier erhalten wir die Kursspanne des Charts vom Höchst- bis zum Tiefstkurs auf dem Chart und die Kursspanne von Hoch und Tief des Mutterbalkens des Musters. Dann berechnen wir das Verhältnis eines Bereichs zu einem anderen in Pixeln und geben die resultierende Höhe des Bitmap-Objekts zurück, indem Sie 8 Pixel dazu addieren - vier oben und vier unten.
Im Konstruktor des Musters „Pin-Bar“ legen wir die Anzahl der verschachtelten Muster gleich dem Wert der Musterbalken (1) fest:
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPatternPinBar::CPatternPinBar(const uint id,const string symbol,const ENUM_TIMEFRAMES timeframe,MqlRates &rates,const ENUM_PATTERN_DIRECTION direct) : CPattern(PATTERN_STATUS_PA,PATTERN_TYPE_PIN_BAR,id,direct,symbol,timeframe,rates) { this.SetProperty(PATTERN_PROP_NAME,"Pin Bar"); this.SetProperty(PATTERN_PROP_CANDLES,1); this.m_bars_formation=(int)this.GetProperty(PATTERN_PROP_CANDLES); }
Erstellen wir nun die Klasse für das neue Preisaktionsmuster „Inside-Bar“.
Die Klasse des Musters „Inside-Bar“
De neue Musterklasse „Inside-Bar“ erstellen wir in derselben Datei, in der auch die Klassen des abstrakten Musters und des Musters „Pin-Bar“ gespeichert sind. Im Wesentlichen müssen wir nur einige virtuelle Methoden und Eigenschaftswerte des Musters schreiben (überschreiben). Die Klasse sollte von der abstrakten Musterobjektklasse abgeleitet sein:
//+------------------------------------------------------------------+ //| "Inside Bar" pattern class | //+------------------------------------------------------------------+ class CPatternInsideBar : public CPattern { protected: //--- Create the (1) image object, the appearance of the (2) info panel and (3) the bitmap object virtual bool CreateBitmap(void); virtual void CreateInfoPanelView(void); void CreateBitmapView(void); public: //--- Return the flag of the pattern supporting the specified property virtual bool SupportProperty(ENUM_PATTERN_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_PATTERN_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_PATTERN_PROP_STRING property) { return true; } //--- Return description of the pattern (1) status and (2) type virtual string StatusDescription(void) const { return CMessage::Text(MSG_LIB_TEXT_PATTERN_STATUS_PA); } virtual string TypeDescription(void) const { return CMessage::Text(MSG_LIB_TEXT_PATTERN_TYPE_INSIDE_BAR); } //--- Draw the pattern icon on the chart virtual void Draw(const bool redraw); //--- Constructor CPatternInsideBar(const uint id,const string symbol,const ENUM_TIMEFRAMES timeframe,MqlRates &rates,const ENUM_PATTERN_DIRECTION direct); };
Im Klassenkonstruktor legen wir den Musternamen, die Anzahl der Musterbalken gleich zwei sowie die Anzahl der Balken der verschachtelten Formationen gleich 2 fest - keine verschachtelten Formationen:
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPatternInsideBar::CPatternInsideBar(const uint id,const string symbol,const ENUM_TIMEFRAMES timeframe,MqlRates &rates,const ENUM_PATTERN_DIRECTION direct) : CPattern(PATTERN_STATUS_PA,PATTERN_TYPE_INSIDE_BAR,id,direct,symbol,timeframe,rates) { this.SetProperty(PATTERN_PROP_NAME,"Inside Bar"); this.SetProperty(PATTERN_PROP_CANDLES,2); this.m_bars_formation=(int)this.GetProperty(PATTERN_PROP_CANDLES); }
Die virtuelle Methode, die das Aussehen der Infotafel bestimmt:
//+------------------------------------------------------------------+ //| Create the info panel appearance | //+------------------------------------------------------------------+ void CPatternInsideBar::CreateInfoPanelView(void) { //--- If the form object is not created, leave if(this.m_form==NULL) return; //--- Declare the array for the initial and final colors of the gradient fill color clr[2]={this.m_form.ChangeColorLightness(this.m_color_panel_bidirect,-5),this.m_form.ChangeColorLightness(this.m_color_panel_bidirect,15)}; //--- Set the background and form frame colors this.m_form.SetBackgroundColor(this.m_color_panel_bidirect,true); this.m_form.SetBorderColor(clrGray,true); //--- Create strings to describe the pattern, its parameters and search criteria string name=::StringFormat("Inside Bar (%lu bars)",int(this.Time()-this.MotherBarTime())/::PeriodSeconds(this.Timeframe())+1); string param=this.DirectDescription();//::StringFormat("%s (%.2f/%.2f/%.2f)",this.DirectDescription(),this.GetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION),this.GetProperty(PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION),this.GetProperty(PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION)); //--- Set the coordinates of the panel and calculate its width and height depending on the size of the texts placed on the panel int x=3; int y=20; int w=4+(::fmax(20+this.m_form.TextWidth(name),::fmax(x+this.m_form.TextWidth(param),x+this.m_form.TextWidth(::TimeToString(this.Time()))))); int h=2+(20+this.m_form.TextHeight(this.DirectDescription())+this.m_form.TextHeight(::TimeToString(this.Time()))); //--- Set the width and height of the panel according to the calculated values this.m_form.SetWidth(w); this.m_form.SetHeight(h); //--- Depending on the chart size and coordinates, we calculate the coordinates of the panel so that it does not go beyond the chart int chart_w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS); int chart_h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS); int cx=(this.m_form.RightEdge() >chart_w-1 ? chart_w-1-this.m_form.Width() : this.m_form.CoordX()); int cy=(this.m_form.BottomEdge()>chart_h-1 ? chart_h-1-this.m_form.Height() : this.m_form.CoordY()); this.m_form.SetCoordX(cx); this.m_form.SetCoordY(cy); //--- Fill the background with a gradient color this.m_form.Erase(clr,200,true,false); //--- Draw the panel frame, an icon with (i), draw the header text with the proportions of a candle and separate the header with a horizontal line this.m_form.DrawFrameSimple(0,0,this.m_form.Width(),this.m_form.Height(),1,1,1,1,this.m_form.BorderColor(),200); this.m_form.DrawIconInfo(1,1,200); this.m_form.Text(20,3,name,clrBlack,200); this.m_form.DrawLine(1,18,this.m_form.Width()-1,18,clrDarkGray,250); //--- Under the horizontal line, enter the pattern description with its search criteria and the date of the pattern-defining bar y=20; this.m_form.Text(x,y,param,clrBlack,200); y+=this.m_form.TextHeight(::TimeToString(this.Time())); this.m_form.Text(x,y,::TimeToString(this.Time()),clrBlack,200); //--- Update the panel while redrawing the chart this.m_form.Update(true); }
Für jeden Mustertyp werden wir eigene virtuelle Methoden erstellen, um das Erscheinungsbild des Info-Panels zu gestalten, denn jedes Muster hat seine eigenen wichtigen Parameter, die auf dem Panel angezeigt werden können, um das Muster visuell zu beschreiben.
Die Methode, die das Mustersymbol auf dem Chart zeichnet:
//+------------------------------------------------------------------+ //| Draw the pattern icon on the chart | //+------------------------------------------------------------------+ void CPatternInsideBar::Draw(const bool redraw) { //--- If the flag for drawing with dots is set, call the parent class method and leave if(this.m_draw_dots) { CPattern::Draw(redraw); return; } //--- If the bitmap object has not yet been created, create it if(this.m_bitmap==NULL) { if(!this.CreateBitmap()) return; } //--- display this.Show(redraw); }
Die Logik der Methode ist in den Kommentaren beschrieben. Die Methode der übergeordneten Klasse erstellt und zeichnet Musterbeschriftungen (Punkte) auf dem Chart. Wenn also das Flag zum Zeichnen von Punkten gesetzt ist, werden sie mit der Methode der Elternklasse gezeichnet.
Andernfalls wird das Bitmap-Objekt erstellt und im Chart angezeigt.
Die Methode, die das Bitmap-Objekt erstellt:
//+------------------------------------------------------------------+ //| Create the bitmap object | //+------------------------------------------------------------------+ bool CPatternInsideBar::CreateBitmap(void) { //--- If the bitmap object has already been created earlier, return 'true' if(this.m_bitmap!=NULL) return true; //--- Calculate the object coordinates and dimensions datetime time=this.MotherBarTime(); double price=(this.MotherBarHigh()+this.MotherBarLow())/2; int w=this.GetBitmapWidth(); int h=this.GetBitmapHeight(); //--- Create the Bitmap object this.m_bitmap=this.CreateBitmap(this.ID(),this.GetChartID(),0,this.Name(),time,price,w,h,this.m_color_bidirect); if(this.m_bitmap==NULL) return false; //--- Set the object origin to its center and remove the tooltip ::ObjectSetInteger(this.GetChartID(),this.m_bitmap.NameObj(),OBJPROP_ANCHOR,ANCHOR_CENTER); ::ObjectSetString(this.GetChartID(),this.m_bitmap.NameObj(),OBJPROP_TOOLTIP,"\n"); //--- Draw the bitmap object appearance this.CreateBitmapView(); return true; }
Die Methode zur Erstellung das Aussehen des Bitmap-Objekts:
//+------------------------------------------------------------------+ //| Create the bitmap object appearance | //+------------------------------------------------------------------+ void CPatternInsideBar::CreateBitmapView(void) { this.m_bitmap.Erase(CLR_CANV_NULL,0); int x=this.m_bitmap.Width()/2-int(1<<this.m_chart_scale)/2; this.m_bitmap.DrawRectangleFill(x,0,this.m_bitmap.Width()-1,this.m_bitmap.Height()-1,this.m_color_bidirect,80); this.m_bitmap.DrawRectangle(x,0,this.m_bitmap.Width()-1,this.m_bitmap.Height()-1,clrGray); this.m_bitmap.Update(false); }
Hier füllen wir den Hintergrund (canvas) mit einer transparenten Farbe und berechnen die anfängliche X-Koordinate des Rechtecks, das die Musterbalken umgibt. Dann füllen wir den rechteckigen Bereich, beginnend an der berechneten X-Koordinate, mit der für das bidirektionale Muster eingestellten Farbe und einer Deckkraft von 80, und umranden den gefüllten Bereich mit dem grauen Rechteck. Anschließend aktualisieren wir die Ressource, ohne das Chart neu zu zeichnen.
Jedes gesuchte Muster mit seinen Parametern wird durch das Objekt der Musterverwaltungsklasse kontrolliert und behandelt. Ein solches Objekt wird einmal erstellt, wenn die Erlaubnis erteilt wird, nach einem Muster mit dem angegebenen Typ und den angegebenen Mustersuchparametern zu suchen. In derselben Klasse müssen wir die Eigenschaften des Chartfensters auslesen - damit wir sie nur einmal beim Erstellen eines Steuerobjekts auslesen und dann die ausgelesenen Chartparameter in die erstellten Musterobjekte schreiben können. Charteigenschaften werden benötigt, um sicherzustellen, dass die Informationsfelder jedes einzelnen Musters nicht über den Rand des Charts hinausragen, wenn sie angezeigt werden. Wenn wir die Chartparameter jedes Mal auslesen, wenn wir ein neues Musterobjekt erstellen, wird das sehr ressourcenaufwändig - schließlich gibt es viele Muster in einer Zeitreihe. Außerdem, warum jedes Mal die gleichen Parameter lesen, wenn sie einmal gelesen und dann in jedem erstellten Muster verwendet werden können? Wir benötigen auch Chartparameter, wenn wir Bitmap-Objekte erstellen, die die Musterbalken umreißen. Auch hier ist es nicht optimal, jedes Mal dieselbe Größe in der Tabelle abzulesen. Daher werden wir sie nur lesen, wenn wir ein Mustersteuerungsobjekt erstellen. Allerdings gibt es hier eine Nuance: Wenn die Größe der Chart geändert wird, bleiben alle zuvor gelesenen Daten gleich, wie sie bereits empfangen wurden. Sie müssen erneut aus der Tabelle abgefragt und in den Eigenschaften der einzelnen Muster erfasst werden. Wir werden dies in den folgenden Artikeln tun.
Die Objektklasse der Mustersteuerung befindet sich in \MQL5\Include\DoEasy\Objects\Series\SeriesDE.mqh. Wir werden die notwendigen Änderungen daran vornehmen:
//+------------------------------------------------------------------+ //| Abstract pattern control class | //+------------------------------------------------------------------+ class CPatternControl : public CBaseObjExt { private: ENUM_TIMEFRAMES m_timeframe; // Pattern timeseries chart period string m_symbol; // Pattern timeseries symbol double m_point; // Symbol Point bool m_used; // Pattern use flag bool m_drawing; // Flag for drawing the pattern icon on the chart bool m_draw_dots; // Flag for drawing the pattern icon on the chart with dots //--- Handled pattern ENUM_PATTERN_TYPE m_type_pattern; // Pattern type protected: //--- Candle proportions double m_ratio_body_to_candle_size; // Percentage ratio of the candle body to the full size of the candle double m_ratio_larger_shadow_to_candle_size; // Percentage ratio of the size of the larger shadow to the size of the candle double m_ratio_smaller_shadow_to_candle_size; // Percentage ratio of the size of the smaller shadow to the size of the candle ulong m_object_id; // Unique object code based on pattern search criteria //--- List views CArrayObj *m_list_series; // Pointer to the timeseries list CArrayObj *m_list_all_patterns; // Pointer to the list of all patterns CPattern m_pattern_instance; // Pattern object for searching by property ulong m_symbol_code; // Chart symbol name as a number int m_chart_scale; // Chart scale int m_chart_height_px; // Height of the chart in pixels double m_chart_price_max; // Chart maximum double m_chart_price_min; // Chart minimum //--- (1) Search for a pattern, return direction (or -1 if no pattern is found), //--- (2) create a pattern with a specified direction, //--- (3) create and return a unique pattern code, //--- (4) return the list of patterns managed by the object virtual ENUM_PATTERN_DIRECTION FindPattern(const datetime series_bar_time,const uint min_body_size,MqlRates &mother_bar_data) const { return WRONG_VALUE; } virtual CPattern *CreatePattern(const ENUM_PATTERN_DIRECTION direction,const uint id,CBar *bar){ return NULL; } virtual ulong GetPatternCode(const ENUM_PATTERN_DIRECTION direction,const datetime time) const { return 0; } virtual CArrayObj*GetListPatterns(void) { return NULL; } //--- Create object ID based on pattern search criteria virtual ulong CreateObjectID(void) { return 0; } //--- Write bar data to the structure void SetBarData(CBar *bar,MqlRates &rates) const { if(bar==NULL) return; rates.open=bar.Open(); rates.high=bar.High(); rates.low=bar.Low(); rates.close=bar.Close(); rates.time=bar.Time(); } public: //--- Returns (1) itself, (2) pattern usage flag CPatternControl *GetObject(void) { return &this; } //--- (1) Set and (2) return the pattern usage flag void SetUsed(const bool flag) { this.m_used=flag; } bool IsUsed(void) const { return this.m_used; } //--- (1) Set and (2) return the pattern drawing flag void SetDrawing(const bool flag) { this.m_drawing=flag; } bool IsDrawing(void) const { return this.m_drawing; } //--- (1) Set and (2) return the flag for drawing pattern icons as dots void SetDrawingAsDots(const bool flag,const bool redraw); bool IsDrawingAsDots(void) const { return this.m_draw_dots; } //--- Set the necessary percentage ratio of the candle body to the full size of the candle, //--- size of the (2) upper and (3) lower shadow to the candle size void SetRatioBodyToCandleSizeValue(const double value) { this.m_ratio_body_to_candle_size=value; } void SetRatioLargerShadowToCandleSizeValue(const double value) { this.m_ratio_larger_shadow_to_candle_size=value; } void SetRatioSmallerShadowToCandleSizeValue(const double value) { this.m_ratio_smaller_shadow_to_candle_size=value; } //--- Return the percentage ratio (1) of the candle body to the full size of the candle, //--- size of the (2) upper and (3) lower shadow to the candle size double RatioBodyToCandleSizeValue(void) const { return this.m_ratio_body_to_candle_size; } double RatioLargerShadowToCandleSizeValue(void) const { return this.m_ratio_larger_shadow_to_candle_size; } double RatioSmallerShadowToCandleSizeValue(void) const { return this.m_ratio_smaller_shadow_to_candle_size; } //--- Return object ID based on pattern search criteria virtual ulong ObjectID(void) const { return this.m_object_id; } //--- Return pattern (1) type, (2) timeframe, (3) symbol, (4) symbol Point, (5) symbol code ENUM_PATTERN_TYPE TypePattern(void) const { return this.m_type_pattern; } ENUM_TIMEFRAMES Timeframe(void) const { return this.m_timeframe; } string Symbol(void) const { return this.m_symbol; } double Point(void) const { return this.m_point; } ulong SymbolCode(void) const { return this.m_symbol_code; } //--- Set the (1) chart scale, (2) chart height in pixels, (3) chart maximum and (3) minimum void SetChartScale(const int scale) { this.m_chart_scale=scale; } void SetChartHeightInPixels(const int height) { this.m_chart_height_px=height; } void SetChartPriceMax(const double price) { this.m_chart_price_max=price; } void SetChartPriceMin(const double price) { this.m_chart_price_min=price; } //--- Return the (1) chart scale, (2) chart height in pixels, (3) chart maximum and (3) minimum int ChartScale(void) const { return this.m_chart_scale; } int ChartHeightInPixels(void) const { return this.m_chart_height_px; } double ChartPriceMax(void) const { return this.m_chart_price_max; } double ChartPriceMin(void) const { return this.m_chart_price_min; } //--- Compare CPatternControl objects by all possible properties virtual int Compare(const CObject *node,const int mode=0) const; //--- Search for patterns and add found ones to the list of all patterns virtual int CreateAndRefreshPatternList(const uint min_body_size); //--- Display patterns on the chart void DrawPatterns(const bool redraw=false); //--- Protected parametric constructor protected: CPatternControl(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_PATTERN_STATUS status,const ENUM_PATTERN_TYPE type,CArrayObj *list_series,CArrayObj *list_patterns); };
Die meisten Methoden müssen nicht vorgestellt werden - ihr Zweck ist in den Kommentaren beschrieben, und die Methoden setzen oder geben nur die entsprechenden Parameter des Klassenobjekts zurück. Wir übergeben nun der Mustersuchmethode eine Verknüpfung zur MqlRates-Struktur, in die wir die Daten des Mutterbalkens einfügen werden. Um diese Daten zu setzen, wird die Methode SetBarData() geschrieben, die den Zeiger auf ein Balkenobjekt und eine Verknüpfung zu einer Variablen vom Typ MqlRates erhält. Die variablen Felder enthalten die entsprechenden Eigenschaften des Balkenobjekts. Die Methode CreateAndRefreshPatternList() erhält die Mindestgröße des Kerzenkörpers. Anschließend werde ich die Einstellung dieses Wertes in das Mustersteuerungsobjekt aufnehmen. Der Wert wird an die Mustersuch- und Aktualisierungsmethode übergeben. Es geht darum, bei der Suche nach Mustern die Balken zu überspringen, deren Größe kleiner als dieser Wert ist. Für den Moment werden wir dort eine Null eingeben, wodurch dieser Filter deaktiviert wird.
Im Klassenkonstruktor berechnen wir die Chartdaten und schreiben sie in die neuen Klassenvariablen:
//+------------------------------------------------------------------+ //| CPatternControl::Protected parametric constructor | //+------------------------------------------------------------------+ CPatternControl::CPatternControl(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_PATTERN_STATUS status,const ENUM_PATTERN_TYPE type,CArrayObj *list_series,CArrayObj *list_patterns) : m_ratio_body_to_candle_size(30),m_ratio_larger_shadow_to_candle_size(60),m_ratio_smaller_shadow_to_candle_size(30),m_used(true),m_drawing(true) { this.m_type=OBJECT_DE_TYPE_SERIES_PATTERN_CONTROL; this.m_type_pattern=type; this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol); this.m_timeframe=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe); this.m_point=::SymbolInfoDouble(this.m_symbol,SYMBOL_POINT); this.m_object_id=0; this.m_list_series=list_series; this.m_list_all_patterns=list_patterns; for(int i=0;i<(int)this.m_symbol.Length();i++) this.m_symbol_code+=this.m_symbol.GetChar(i); this.m_chart_scale=(int)::ChartGetInteger(this.m_chart_id,CHART_SCALE); this.m_chart_height_px=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS); this.m_chart_price_max=::ChartGetDouble(this.m_chart_id,CHART_PRICE_MAX); this.m_chart_price_min=::ChartGetDouble(this.m_chart_id,CHART_PRICE_MIN); }
Die notwendigen Verbesserungen nehmen wir an der Methode vor, die nach Mustern sucht und die gefundenen Muster zur Liste aller Muster hinzufügt:
//+------------------------------------------------------------------+ //| CPatternControl::Search for patterns and add | //| found ones to the list of all patterns | //+------------------------------------------------------------------+ int CPatternControl::CreateAndRefreshPatternList(const uint min_body_size) { //--- If not used, leave if(!this.m_used) return 0; //--- Reset the timeseries event flag and clear the list of all timeseries pattern events this.m_is_event=false; this.m_list_events.Clear(); //--- Get the opening date of the last (current) bar datetime time_open=0; if(!::SeriesInfoInteger(this.Symbol(),this.Timeframe(),SERIES_LASTBAR_DATE,time_open)) return 0; //--- Get a list of all bars in the timeseries except the current one CArrayObj *list=CSelect::ByBarProperty(this.m_list_series,BAR_PROP_TIME,time_open,LESS); if(list==NULL || list.Total()==0) return 0; //--- "Mother" bar data structure MqlRates pattern_mother_bar_data={}; //--- Sort the resulting list by bar opening time list.Sort(SORT_BY_BAR_TIME); //--- In a loop from the latest bar, for(int i=list.Total()-1;i>=0;i--) { //--- get the next bar object from the list CBar *bar=list.At(i); if(bar==NULL) continue; //--- look for a pattern relative to the received bar ENUM_PATTERN_DIRECTION direction=this.FindPattern(bar.Time(),min_body_size,pattern_mother_bar_data); //--- If there is no pattern, go to the next bar if(direction==WRONG_VALUE) continue; //--- Pattern found on the current bar of the loop //--- unique pattern code = candle opening time + type + status + pattern direction + timeframe + timeseries symbol ulong code=this.GetPatternCode(direction,bar.Time()); //--- Set the pattern code to the sample this.m_pattern_instance.SetProperty(PATTERN_PROP_CODE,code); //--- Sort the list of all patterns by the unique pattern code this.m_list_all_patterns.Sort(SORT_BY_PATTERN_CODE); //--- search for a pattern in the list using a unique code int index=this.m_list_all_patterns.Search(&this.m_pattern_instance); //--- If there is no pattern equal to the sample in the list of all patterns if(index==WRONG_VALUE) { //--- Create the pattern object CPattern *pattern=this.CreatePattern(direction,this.m_list_all_patterns.Total(),bar); if(pattern==NULL) continue; //--- Sort the list of all patterns by time and insert the pattern into the list by its time this.m_list_all_patterns.Sort(SORT_BY_PATTERN_TIME); if(!this.m_list_all_patterns.InsertSort(pattern)) { delete pattern; continue; } //--- Add the pattern to the list of bar object patterns bar.AddPattern(pattern.TypePattern()); //--- Add the pointer to the bar the pattern object is found on, together with the mother bar data pattern.SetPatternBar(bar); pattern.SetMotherBarData(pattern_mother_bar_data); //--- set the chart data to the pattern object pattern.SetChartHeightInPixels(this.m_chart_height_px); pattern.SetChartScale(this.m_chart_scale); pattern.SetChartPriceMax(this.m_chart_price_max); pattern.SetChartPriceMin(this.m_chart_price_min); //--- If the drawing flag is set, draw the pattern label on the chart if(this.m_drawing) pattern.Draw(false); } } //--- Sort the list of all patterns by time and return the total number of patterns in the list this.m_list_all_patterns.Sort(SORT_BY_PATTERN_TIME); return m_list_all_patterns.Total(); }
Nun erhält die Methode die Mindestgröße des Balkenkörpers des gewünschten Musters. Wir übergeben der Mustersuchmethode die Größe und den Verweis auf die Struktur des Hauptbalkens, der die Balkenparameter enthalten soll. Wenn das Muster gefunden wird, wird der Typ des gefundenen Musters in das Balkenobjekt geschrieben, in dem das Muster gefunden wurde. Gleichzeitig erhält das auf dem Balken befindliche Musterobjekt den Zeiger auf den Balken, die Daten des Mutterbalkens und die Daten des Charts.
Die Methode, die das Flag für das Zeichnen von Mustersymbolen als Punkte setzt:
//+------------------------------------------------------------------+ //| Set the flag for drawing pattern icons as dots | //+------------------------------------------------------------------+ void CPatternControl::SetDrawingAsDots(const bool flag,const bool redraw) { this.m_draw_dots=flag; //--- Get a list of patterns controlled by the control object CArrayObj *list=this.GetListPatterns(); if(list==NULL || list.Total()==0) return; //--- In a loop by the list of patterns, for(int i=list.Total()-1;i>=0;i--) { //--- get the next pattern object CPattern *obj=list.At(i); if(obj==NULL) continue; //--- Set the flag value. If 'false', remove the pattern dot object obj.SetDrawAsDots(flag); if(!flag) obj.DeleteGraphObj(); //--- Display the pattern label on the chart if the flag is 'true' else obj.Draw(false); } //--- At the end of the cycle, redraw the chart if the flag is set if(redraw) ::ChartRedraw(this.m_chart_id); }
Die Methodenlogik wurde in den Codekommentaren ausführlich beschrieben. Hier erhalten wir die Liste der Muster, die von diesem Kontrollobjekt verwaltet werden. In jedem Musterobjekt geben wir das Flag für das Zeichnen mit Punkten an. Wenn das Flag zurückgesetzt ist, müssen wir den zuvor gezeichneten Punkt löschen, und wenn das Flag gesetzt ist, sollten wir ihn zeichnen. Am Ende der Bearbeitung der Schleife aller Muster in der Liste und wenn ein Redrawing-Flag an die Methode übergeben wird, wird das Chart neu gezeichnet.
Als Nächstes müssen wir die Klasse des Musters „Pin-Bar“ ändern. Wir integrieren die Variable MqlRates in die Mustersuchmethode, um die Daten für den Mutterbalken festzulegen:
//+------------------------------------------------------------------+ //| Pin Bar pattern control class | //+------------------------------------------------------------------+ class CPatternControlPinBar : public CPatternControl { protected: //--- (1) Search for a pattern, return direction (or -1), //--- (2) create a pattern with a specified direction, //--- (3) create and return a unique pattern code //--- (4) return the list of patterns managed by the object virtual ENUM_PATTERN_DIRECTION FindPattern(const datetime series_bar_time,const uint min_body_size,MqlRates &mother_bar_data) const; virtual CPattern *CreatePattern(const ENUM_PATTERN_DIRECTION direction,const uint id,CBar *bar); virtual ulong GetPatternCode(const ENUM_PATTERN_DIRECTION direction,const datetime time) const { //--- unique pattern code = candle opening time + type + status + pattern direction + timeframe + timeseries symbol return(time+PATTERN_TYPE_PIN_BAR+PATTERN_STATUS_PA+direction+this.Timeframe()+this.m_symbol_code); } virtual CArrayObj*GetListPatterns(void); //--- Create object ID based on pattern search criteria virtual ulong CreateObjectID(void); public: //--- Parametric constructor CPatternControlPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, CArrayObj *list_series,CArrayObj *list_patterns, const double ratio_body_to_candle_size, const double ratio_larger_shadow_to_candle_size, const double ratio_smaller_shadow_to_candle_size) : CPatternControl(symbol,timeframe,PATTERN_STATUS_PA,PATTERN_TYPE_PIN_BAR,list_series,list_patterns) { this.m_ratio_body_to_candle_size=ratio_body_to_candle_size; this.m_ratio_larger_shadow_to_candle_size=ratio_larger_shadow_to_candle_size; this.m_ratio_smaller_shadow_to_candle_size=ratio_smaller_shadow_to_candle_size; this.m_object_id=this.CreateObjectID(); } };
In der Methode, die das Muster mit der angegebenen Richtung erstellt, fügen wir der Variablen MqlRates schreibende Balkendaten hinzu:
//+---------------------------------------------------------------------+ //| CPatternControlPinBar::Create a pattern with a specified direction | //+---------------------------------------------------------------------+ CPattern *CPatternControlPinBar::CreatePattern(const ENUM_PATTERN_DIRECTION direction,const uint id,CBar *bar) { //--- If invalid indicator is passed to the bar object, return NULL if(bar==NULL) return NULL; //--- Fill the MqlRates structure with bar data MqlRates rates={0}; this.SetBarData(bar,rates); //--- Create a new Pin Bar pattern CPatternPinBar *obj=new CPatternPinBar(id,this.Symbol(),this.Timeframe(),rates,direction); if(obj==NULL) return NULL; //--- set the proportions of the candle the pattern was found on to the properties of the created pattern object obj.SetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE,bar.RatioBodyToCandleSize()); obj.SetProperty(PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,bar.RatioLowerShadowToCandleSize()); obj.SetProperty(PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,bar.RatioUpperShadowToCandleSize()); //--- set the search criteria of the candle the pattern was found on to the properties of the created pattern object obj.SetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION,this.RatioBodyToCandleSizeValue()); obj.SetProperty(PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION,this.RatioLargerShadowToCandleSizeValue()); obj.SetProperty(PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION,this.RatioSmallerShadowToCandleSizeValue()); //--- Set the control object ID to the pattern object obj.SetProperty(PATTERN_PROP_CTRL_OBJ_ID,this.ObjectID()); //--- Return the pointer to a created object return obj; }
Zuvor haben wir hier die Daten Element für Element eingegeben. Jetzt wird diese elementweise Eingabe in der Methode SetBarData() durchgeführt, die die gleiche ist, aber der Methodencode ist kürzer.
In der Methode, die nach dem Muster sucht, fügen wir die Eingabedaten zu dem Balkendaten-Mutterbalken hinzu, in dem das Muster gefunden wurde:
//+------------------------------------------------------------------+ //| CPatternControlPinBar::Search for the pattern | //+------------------------------------------------------------------+ ENUM_PATTERN_DIRECTION CPatternControlPinBar::FindPattern(const datetime series_bar_time,const uint min_body_size,MqlRates &mother_bar_data) const { //--- Get data for one bar by time CArrayObj *list=CSelect::ByBarProperty(this.m_list_series,BAR_PROP_TIME,series_bar_time,EQUAL); //--- If the list is empty, return -1 if(list==NULL || list.Total()==0) return WRONG_VALUE; //--- he size of the candle body should be less than or equal to RatioBodyToCandleSizeValue() (default 30%) of the entire candle size, //--- in this case, the body size should not be less than min_body_size list=CSelect::ByBarProperty(list,BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE,this.RatioBodyToCandleSizeValue(),EQUAL_OR_LESS); list=CSelect::ByBarProperty(list,BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE,min_body_size,EQUAL_OR_MORE); //--- If the list is empty - there are no patterns, return -1 if(list==NULL || list.Total()==0) return WRONG_VALUE; //--- Define the bullish pattern //--- The lower shadow should be equal to or greater than RatioLargerShadowToCandleSizeValue() (default 60%) of the entire candle size CArrayObj *list_bullish=CSelect::ByBarProperty(list,BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,this.RatioLargerShadowToCandleSizeValue(),EQUAL_OR_MORE); //--- The upper shadow should be less than or equal to RatioSmallerShadowToCandleSizeValue() (default 30%) of the entire candle size list_bullish=CSelect::ByBarProperty(list_bullish,BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,this.RatioSmallerShadowToCandleSizeValue(),EQUAL_OR_LESS); //--- If a pattern is found on the bar if(list_bullish!=NULL && list_bullish.Total()>0) { CBar *bar=list.At(list_bullish.Total()-1); if(bar!=NULL) { this.SetBarData(bar,mother_bar_data); return PATTERN_DIRECTION_BULLISH; } } //--- Define the bearish pattern //--- The upper shadow should be equal to or greater than RatioLargerShadowToCandleSizeValue() (default 60%) of the entire candle size CArrayObj *list_bearish=CSelect::ByBarProperty(list,BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,this.RatioLargerShadowToCandleSizeValue(),EQUAL_OR_MORE); //--- The lower shadow should be less than or equal to RatioSmallerShadowToCandleSizeValue() (default 30%) of the entire candle size list_bearish=CSelect::ByBarProperty(list_bearish,BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,this.RatioSmallerShadowToCandleSizeValue(),EQUAL_OR_LESS); //--- If a pattern is found on the bar if(list_bearish!=NULL && list_bearish.Total()>0) { CBar *bar=list.At(list_bearish.Total()-1); if(bar!=NULL) { this.SetBarData(bar,mother_bar_data); return PATTERN_DIRECTION_BEARISH; } } //--- No patterns found - return -1 return WRONG_VALUE; }
Da es sich beim „Pin-Bar“ um eine Formation aus einem Balken handelt, ist der Mutterbalken auch der Basisbalken, auf dem das Muster gefunden wurde.
Erstellen wir die Klasse zur Verwaltung des Musters „Inside-Bar“. Die Struktur dieses Musters ist streng definiert und hat keine weiteren Parameter, außer dass sich der Basisbalken (rechts) vollständig innerhalb des Mutterbalkens (links) befinden muss. Es gibt keine weiteren Parameter. Daher ist jedes „Inside-Bar“-Muster das einzige Muster in einer Zeitreihe, im Gegensatz zum „Pin-Bar“-Muster, bei dem wir die Parameter für die Suche festlegen können, und es kann mehrere „Pin-Bar“-Muster mit unterschiedlichen Parametern in einer Zeitreihe geben. Für jedes dieser Muster wird ein eigenes Kontrollobjekt erstellt. In Anbetracht der obigen Ausführungen wird für das Muster „Inside-Bar“ immer nur ein Kontrollobjekt für jede Zeitreihe erstellt.
Tragen wir die neue Klasse zur Verwaltung des Musters „Inside-Bar“ in derselben Datei nach der Kontrollklasse für das Muster „Pin-Bar“ ein:
//+------------------------------------------------------------------+ //| Inside Bar pattern control class | //+------------------------------------------------------------------+ class CPatternControlInsideBar : public CPatternControl { private: //--- Check and return the presence of a pattern on two adjacent bars bool CheckInsideBar(const CBar *bar1,const CBar *bar0) const { //--- If empty bar objects are passed, return 'false' if(bar0==NULL || bar1==NULL) return false; //--- Return the fact that the bar on the right is completely within the dimensions of the bar on the left return(bar0.High()<bar1.High() && bar0.Low()>bar1.Low()); } bool FindMotherBar(CArrayObj *list,MqlRates &rates) const { bool res=false; if(list==NULL) return false; //--- In a loop through the list, starting from the bar to the left of the base one for(int i=list.Total()-2;i>0;i--) { //--- Get the pointers to two consecutive bars CBar *bar0=list.At(i); CBar *bar1=list.At(i-1); if(bar0==NULL || bar1==NULL) return false; //--- If the obtained bars represent a pattern if(CheckInsideBar(bar1,bar0)) { //--- set mother bar data to the MqlRates variable and set 'res' to 'true' this.SetBarData(bar1,rates); res=true; } //--- If there is no pattern, interrupt the loop else break; } //--- return the result return res; } protected: //--- (1) Search for a pattern, return direction (or -1), //--- (2) create a pattern with a specified direction, //--- (3) create and return a unique pattern code //--- (4) return the list of patterns managed by the object virtual ENUM_PATTERN_DIRECTION FindPattern(const datetime series_bar_time,const uint min_body_size,MqlRates &mother_bar_data) const; virtual CPattern *CreatePattern(const ENUM_PATTERN_DIRECTION direction,const uint id,CBar *bar); virtual ulong GetPatternCode(const ENUM_PATTERN_DIRECTION direction,const datetime time) const { //--- unique pattern code = candle opening time + type + status + pattern direction + timeframe + timeseries symbol return(time+PATTERN_TYPE_INSIDE_BAR+PATTERN_STATUS_PA+PATTERN_DIRECTION_BOTH+this.Timeframe()+this.m_symbol_code); } virtual CArrayObj*GetListPatterns(void); //--- Create object ID based on pattern search criteria virtual ulong CreateObjectID(void); public: //--- Parametric constructor CPatternControlInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe, CArrayObj *list_series,CArrayObj *list_patterns) : CPatternControl(symbol,timeframe,PATTERN_STATUS_PA,PATTERN_TYPE_INSIDE_BAR,list_series,list_patterns) { this.m_ratio_body_to_candle_size=0; this.m_ratio_larger_shadow_to_candle_size=0; this.m_ratio_smaller_shadow_to_candle_size=0; this.m_object_id=this.CreateObjectID(); } };
Die Klasse ist praktisch eine Kopie der Klasse des Musters „Pin-Bar“, die im vorherigen Artikel über die Bibliotheksmuster beschrieben wurde. Im Klassenkonstruktor setzen wir alle Kriterien für die Mustersuche auf Null, da sie hier nicht verwendet werden. Die Objekt-ID ist immer Null, da dies das einzige Objekt in einer Zeitreihe ist:
//+------------------------------------------------------------------+ //| Create object ID based on pattern search criteria | //+------------------------------------------------------------------+ ulong CPatternControlInsideBar::CreateObjectID(void) { return 0; }
Die wichtigsten Methoden der Mustersuche sind der Vergleich zweier benachbarter Balken auf das Vorhandensein des Musters und die Suche nach dem Mutterbalken:
//--- Check and return the presence of a pattern on two adjacent bars bool CheckInsideBar(const CBar *bar1,const CBar *bar0) const { //--- If empty bar objects are passed, return 'false' if(bar0==NULL || bar1==NULL) return false; //--- Return the fact that the bar on the right is completely within the dimensions of the bar on the left return(bar0.High()<bar1.High() && bar0.Low()>bar1.Low()); } bool FindMotherBar(CArrayObj *list,MqlRates &rates) const { bool res=false; if(list==NULL) return false; //--- In a loop through the list, starting from the bar to the left of the base one for(int i=list.Total()-2;i>0;i--) { //--- Get the pointers to two consecutive bars CBar *bar0=list.At(i); CBar *bar1=list.At(i-1); if(bar0==NULL || bar1==NULL) return false; //--- If the obtained bars represent a pattern if(CheckInsideBar(bar1,bar0)) { //--- set mother bar data to the MqlRates variable and set 'res' to 'true' this.SetBarData(bar1,rates); res=true; } //--- If there is no pattern, interrupt the loop else break; } //--- return the result return res; }
Die Mustersuchmethode vergleicht einfach die Größen zweier benachbarter Balken und gibt das Flag zurück, dass der rechte Balken vollständig innerhalb des linken liegt.
Bei der Suche nach dem Mutterbalken wird in einer Schleife durch die Liste der Balken nach Mustern gesucht, und wenn ein Muster gefunden wird, werden die Balkendaten in die Variable MqlRates geschrieben, und die Suche wird mit dem nächsten Balkenpaar fortgesetzt. Die Suche wird so lange fortgesetzt, bis bei jeder Iteration der Schleife Muster gefunden werden, und die Daten des Mutterbalkens werden in eine Variable aus jedem nachfolgenden Balken geschrieben. Auf diese Weise finden wir alle verschachtelten Muster und erhalten schließlich die Daten des Hauptbalkens aus dem ganz linken Balken der gesamten Sequenz.
Die Methode, die das Muster mit der angegebenen Richtung erstellt:
//+-----------------------------------------------------------------------+ //|CPatternControlInsideBar::Create a pattern with the specified direction| //+-----------------------------------------------------------------------+ CPattern *CPatternControlInsideBar::CreatePattern(const ENUM_PATTERN_DIRECTION direction,const uint id,CBar *bar) { //--- If invalid indicator is passed to the bar object, return NULL if(bar==NULL) return NULL; //--- Fill the MqlRates structure with bar data MqlRates rates={0}; this.SetBarData(bar,rates); //--- Create a new Inside Bar pattern CPatternInsideBar *obj=new CPatternInsideBar(id,this.Symbol(),this.Timeframe(),rates,PATTERN_DIRECTION_BOTH); if(obj==NULL) return NULL; //--- set the proportions of the candle the pattern was found on to the properties of the created pattern object obj.SetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE,bar.RatioBodyToCandleSize()); obj.SetProperty(PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,bar.RatioLowerShadowToCandleSize()); obj.SetProperty(PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,bar.RatioUpperShadowToCandleSize()); //--- set the search criteria of the candle the pattern was found on to the properties of the created pattern object obj.SetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION,this.RatioBodyToCandleSizeValue()); obj.SetProperty(PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION,this.RatioLargerShadowToCandleSizeValue()); obj.SetProperty(PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION,this.RatioSmallerShadowToCandleSizeValue()); //--- Set the control object ID to the pattern object obj.SetProperty(PATTERN_PROP_CTRL_OBJ_ID,this.ObjectID()); //--- Return the pointer to a created object return obj; }
Die Methode erstellt einfach ein neues Objekt der Musterklasse „Inside-Bar“ und gibt das Ergebnis der Erstellung des neuen Objekts zurück. Alles unterhalb der Zeichenketten für die Erstellung eines neuen Objekts sind immer noch nutzlose Zuweisungen von Nullen an Objekteigenschaften, die bereits im Klassenkonstruktor zugewiesen werden. Aber im Moment ist das alles noch übrig. Später kann es notwendig sein, die Verwendung einiger Parameter zur Identifizierung des Musters hinzuzufügen. Wenn nicht, dann werde ich den zusätzlichen Code einfach entfernen.
Die Methode zur Suche nach dem Muster:
//+------------------------------------------------------------------+ //| CPatternControlInsideBar::Search for pattern | //+------------------------------------------------------------------+ ENUM_PATTERN_DIRECTION CPatternControlInsideBar::FindPattern(const datetime series_bar_time,const uint min_body_size,MqlRates &mother_bar_data) const { //--- Get bar data up to and including the specified time CArrayObj *list=CSelect::ByBarProperty(this.m_list_series,BAR_PROP_TIME,series_bar_time,EQUAL_OR_LESS); //--- If the list is empty, return -1 if(list==NULL || list.Total()==0) return WRONG_VALUE; //--- Sort the list by bar opening time list.Sort(SORT_BY_BAR_TIME); //--- Get the latest bar from the list (base bar) CBar *bar_patt=list.At(list.Total()-1); if(bar_patt==NULL) return WRONG_VALUE; //--- In the loop from the next bar (mother), for(int i=list.Total()-2;i>=0;i--) { CBar *bar_prev=list.At(i); if(bar_prev==NULL) return WRONG_VALUE; //--- check that the resulting two bars are a pattern. If not, return -1 if(!this.CheckInsideBar(bar_prev,bar_patt)) return WRONG_VALUE; //--- If the pattern is found at the previous step, look for nested patterns. //--- The leftmost bar will be the mother bar for the entire chain of nested patterns //--- If the found pattern does not have nested ones, then its mother bar will be the current cycle bar (to the left of the base one) if(!this.FindMotherBar(list,mother_bar_data)) SetBarData(bar_prev,mother_bar_data); //--- Return the pattern direction (bidirectional) return PATTERN_DIRECTION_BOTH; } //--- No patterns found - return -1 return WRONG_VALUE; }
Die Logik der Methode ist in den Kommentaren beschrieben. Die Eröffnungszeit des aktuellen Balkens wird an die Methode übergeben. Holt die Liste aller Balken außer dem aktuellen Balken (wir suchen nicht nach Mustern auf dem Null-Balken). In der Schleife, die auf der resultierenden Liste der Balken basiert, werden alle zwei benachbarten Balken daraufhin überprüft, ob sie die Kriterien des Musters erfüllen. Wenn ihre Beziehung ein Muster ist, suchen wir nach verschachtelten Mustern, d. h. wir suchen in einer zusätzlichen Schleife nach benachbarten Mustern, bis sie gefunden werden. Auf diese Weise finden wir die gesamte Kette benachbarter Muster, und das am weitesten links liegende - sein linker Balken - wird der Mutterbalken für die gesamte Kette verschachtelter Muster sein. Dieser Balken, seine Zeit und die Preise werden in die Eigenschaften des gefundenen Musters geschrieben. Diese Daten geben uns die Möglichkeit, die gesamte Kette der verschachtelten Muster vollständig einzurahmen, wenn wir sie auf dem Chart anzeigen, der im Test-EA sichtbar sein wird.
Die Methode gibt eine Liste von Mustern zurück, die von dem Objekt verwaltet werden:
//+------------------------------------------------------------------+ //| Returns the list of patterns managed by the object | //+------------------------------------------------------------------+ CArrayObj *CPatternControlInsideBar::GetListPatterns(void) { CArrayObj *list=CSelect::ByPatternProperty(this.m_list_all_patterns,PATTERN_PROP_PERIOD,this.Timeframe(),EQUAL); list=CSelect::ByPatternProperty(list,PATTERN_PROP_SYMBOL,this.Symbol(),EQUAL); list=CSelect::ByPatternProperty(list,PATTERN_PROP_TYPE,PATTERN_TYPE_INSIDE_BAR,EQUAL); return CSelect::ByPatternProperty(list,PATTERN_PROP_CTRL_OBJ_ID,this.ObjectID(),EQUAL); }
Passen wir in der Klasse des Muster-Managements die Methode an, die das Objekt „Inner Bar“ des der Musterkontrolle zurückgibt:
//--- Return the Inside Bar pattern control object CPatternControl *GetObjControlPatternInsideBar(void) { int total=this.m_list_controls.Total(); for(int i=0;i<total;i++) { CPatternControl *obj=this.m_list_controls.At(i); if(obj==NULL) continue; //--- Check search conditions and return the result if(obj.TypePattern()==PATTERN_TYPE_INSIDE_BAR) return obj; } return NULL; }
Zuvor gab die Methode NULL zurück, da die Klasse des von der Methode zurückgegebenen Objekts noch nicht erstellt worden war.
Passen wir die Methode an, die das Flag für die Verwendung des Musters „Inside-Bar“ setzt und ein Steuerelementobjekt erstellt, wenn es noch nicht vorhanden ist:
//--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const bool flag) { //--- Get the pointer to the Inner Bar pattern control object CPatternControlInsideBar *obj=this.GetObjControlPatternInsideBar(); //--- If the pointer is received (the object exists), set the use flag if(obj!=NULL) obj.SetUsed(flag); //--- f there is no object and the flag is passed as 'true' else if(flag) { //--- Create the new Inside Bar pattern control object obj=new CPatternControlInsideBar(this.Symbol(),this.Timeframe(),this.m_list_series,this.m_list_all_patterns); if(obj==NULL) return; //--- Add pointer to the created object to the list if(!this.m_list_controls.Add(obj)) { delete obj; return; } //--- Set the usage flag and pattern parameters to the control object obj.SetUsed(flag); obj.SetRatioBodyToCandleSizeValue(0); obj.SetRatioLargerShadowToCandleSizeValue(0); obj.SetRatioSmallerShadowToCandleSizeValue(0); obj.CreateAndRefreshPatternList(0); } }
Zuvor war die Methode aus dem oben genannten Grund leer. Die Logik der Methode ist im Code kommentiert und bedarf kaum einer zusätzlichen Erklärung.
Schreiben wir die Methoden zum Setzen des Flags für das Zeichnen des Musters mit Punkten:
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //--- Set the flag for drawing the Harami pattern with dots void SetDrawingAsDotsPatternHarami(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Harami Cross pattern with dots void SetDrawingAsDotsPatternHaramiCross(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Tweezer pattern with dots void SetDrawingAsDotsPatternTweezer(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Piercing Line pattern with dots void SetDrawingAsDotsPatternPiercingLine(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Cloud Cover pattern with dots void SetDrawingAsDotsPatternDarkCloudCover(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Three White Soldiers pattern with dots void SetDrawingAsDotsPatternThreeWhiteSoldiers(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Three Black Crows pattern with dots void SetDrawingAsDotsPatternThreeBlackCrows(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Shooting Star pattern with dots void SetDrawingAsDotsPatternShootingStar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Hammer pattern with dots void SetDrawingAsDotsPatternHammer(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Inverted Hammer pattern with dots void SetDrawingAsDotsPatternInvertedHammer(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Hanging Man pattern with dots void SetDrawingAsDotsPatternHangingMan(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Doji pattern with dots void SetDrawingAsDotsPatternDoji(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Dragonfly Doji pattern with dots void SetDrawingAsDotsPatternDragonflyDoji(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Gravestone Doji pattern with dots void SetDrawingAsDotsPatternGravestoneDoji(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Morning Star pattern with dots void SetDrawingAsDotsPatternMorningStar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Morning Doji Star pattern with dots void SetDrawingAsDotsPatternMorningDojiStar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Evening Star pattern with dots void SetDrawingAsDotsPatternEveningStar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Evening Doji Star pattern with dots void SetDrawingAsDotsPatternEveningDojiStar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Three Stars pattern with dots void SetDrawingAsDotsPatternThreeStars(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Abandoned Baby pattern with dots void SetDrawingAsDotsPatternAbandonedBaby(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Pivot Point Reversal pattern with dots //--- Price Action void SetDrawingAsDotsPatternPivotPointReversal(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Outside Bar pattern with dots void SetDrawingAsDotsPatternOutsideBar(const bool flag,const bool redraw) { } //--- Set the flag for drawing the Inside Bar pattern with dots void SetDrawingAsDotsPatternInsideBar(const bool flag,const bool redraw) { //--- Get the pointer to the Inner Bar pattern control object CPatternControlInsideBar *obj=this.GetObjControlPatternInsideBar(); //--- If the pointer is received (the object exists), set the drawing flag if(obj!=NULL) obj.SetDrawingAsDots(flag,redraw); } //--- Set the flag for drawing the Pin Bar pattern with dots void SetDrawingAsDotsPatternPinBar(const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { //--- Get the pointer to the Pin Bar pattern control object with the specified parameters CPatternControlPinBar *obj=this.GetObjControlPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow); //--- If the pointer is received (the object exists), set the use flag if(obj!=NULL) obj.SetDrawingAsDots(flag,redraw); } //--- Set the flag for drawing the Rails pattern with dots void SetDrawingAsDotsPatternRails(const bool flag,const bool redraw) { }
Die Methoden sind nur für zwei Muster vollständig geschrieben. Für die übrigen Muster gibt es nur Vorlagen, die wir ausfüllen werden, wenn wir neue Klassen von Musterobjekten schreiben.
Wir schreiben Sie die Methoden der Rückgabe des Flags der Zeichnung mit Punkten:
//+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag for drawing the Harami pattern with dots bool IsDrawingAsDotsPatternHarami(void) { CPatternControl *obj=GetObjControlPatternHarami(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Harami Cross pattern with dots bool IsDrawingAsDotsPatternHaramiCross(void) { CPatternControl *obj=GetObjControlPatternHaramiCross(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Tweezer pattern with dots bool IsDrawingAsDotsPatternTweezer(void) { CPatternControl *obj=GetObjControlPatternTweezer(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Piercing Line pattern with dots bool IsDrawingAsDotsPatternPiercingLine(void) { CPatternControl *obj=GetObjControlPatternPiercingLine(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Cloud Cover pattern with dots bool IsDrawingAsDotsPatternDarkCloudCover(void) { CPatternControl *obj=GetObjControlPatternDarkCloudCover(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Three White Soldiers pattern with dots bool IsDrawingAsDotsPatternThreeWhiteSoldiers(void) { CPatternControl *obj=GetObjControlPatternThreeWhiteSoldiers(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Three Black Crows pattern with dots bool IsDrawingAsDotsPatternThreeBlackCrows(void) { CPatternControl *obj=GetObjControlPatternThreeBlackCrows(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Shooting Star pattern with dots bool IsDrawingAsDotsPatternShootingStar(void) { CPatternControl *obj=GetObjControlPatternShootingStar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Hammer pattern with dots bool IsDrawingAsDotsPatternHammer(void) { CPatternControl *obj=GetObjControlPatternHammer(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Inverted Hammer pattern with dots bool IsDrawingAsDotsPatternInvertedHammer(void) { CPatternControl *obj=GetObjControlPatternInvertedHammer(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Hanging Man pattern with dots bool IsDrawingAsDotsPatternHangingMan(void) { CPatternControl *obj=GetObjControlPatternHangingMan(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Doji pattern with dots bool IsDrawingAsDotsPatternDoji(void) { CPatternControl *obj=GetObjControlPatternDoji(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Dragonfly Doji pattern with dots bool IsDrawingAsDotsPatternDragonflyDoji(void) { CPatternControl *obj=GetObjControlPatternDragonflyDoji(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Gravestone Doji pattern with dots bool IsDrawingAsDotsPatternGravestoneDoji(void) { CPatternControl *obj=GetObjControlPatternGravestoneDoji(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Morning Star pattern with dots bool IsDrawingAsDotsPatternMorningStar(void) { CPatternControl *obj=GetObjControlPatternMorningStar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Morning Doji Star pattern with dots bool IsDrawingAsDotsPatternMorningDojiStar(void) { CPatternControl *obj=GetObjControlPatternMorningDojiStar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Evening Star pattern with dots bool IsDrawingAsDotsPatternEveningStar(void) { CPatternControl *obj=GetObjControlPatternEveningStar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Evening Doji Star pattern with dots bool IsDrawingAsDotsPatternEveningDojiStar(void) { CPatternControl *obj=GetObjControlPatternEveningDojiStar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Three Stars pattern with dots bool IsDrawingAsDotsPatternThreeStars(void) { CPatternControl *obj=GetObjControlPatternThreeStars(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Abandoned Baby pattern with dots bool IsDrawingAsDotsPatternAbandonedBaby(void) { CPatternControl *obj=GetObjControlPatternAbandonedBaby(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Price Action //--- Return the flag for drawing the Pivot Point Reversal pattern with dots bool IsDrawingAsDotsPatternPivotPointReversal(void) { CPatternControl *obj=GetObjControlPatternPivotPointReversal(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Outside Bar pattern with dots bool IsDrawingAsDotsPatternOutsideBar(void) { CPatternControl *obj=GetObjControlPatternOutsideBar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Inside Bar pattern with dots bool IsDrawingAsDotsPatternInsideBar(void) { CPatternControl *obj=GetObjControlPatternInsideBar(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Pin Bar pattern with dots bool IsDrawingAsDotsPatternPinBar(const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { //--- Get the pattern control object based on its parameters CPatternControl *obj=this.GetObjControlPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow); //--- Return the pattern use flag, or 'false' if the object is not found return(obj!=NULL ? obj.IsDrawingAsDots() : false); } //--- Return the flag for drawing the Rails pattern with dots bool IsDrawingAsDotsPatternRails(void) { CPatternControl *obj=GetObjControlPatternRails(); return(obj!=NULL ? obj.IsDrawingAsDots() : false); }
Die Eingänge sind für die Methode implementiert, die das „Pin-Bar“-Muster mit Punkten zeichnet, da alle Methoden für die Arbeit mit dem Muster sie haben. Die übrigen Methoden geben derzeit Flags für das Zeichnen mit Punkten ohne Parameter zurück. Wenn einige Muster Parameter erfordern, werden wir sie später in solche Methoden schreiben.
Nun müssen genau die gleichen Methoden für die Klasse der Zeitreihen geschrieben werden, die sich in der gleichen Datei befindet:
//--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const bool flag) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetUsedPatternInsideBar(flag); }
...
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //--- Set the flag for drawing the Harami pattern with dots void SetDrawingAsDotsPatternHarami(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternHarami(flag,redraw); } //--- Set the flag for drawing the Harami Cross pattern with dots void SetDrawingAsDotsPatternHaramiCross(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternHaramiCross(flag,redraw); } //--- Set the flag for drawing the Tweezer pattern with dots void SetDrawingAsDotsPatternTweezer(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternTweezer(flag,redraw); } //--- Set the flag for drawing the Piercing Line pattern with dots void SetDrawingAsDotsPatternPiercingLine(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternPiercingLine(flag,redraw); } //--- Set the flag for drawing the Cloud Cover pattern with dots void SetDrawingAsDotsPatternDarkCloudCover(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternDarkCloudCover(flag,redraw); } //--- Set the flag for drawing the Three White Soldiers pattern with dots void SetDrawingAsDotsPatternThreeWhiteSoldiers(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternThreeWhiteSoldiers(flag,redraw); } //--- Set the flag for drawing the Three Black Crows pattern with dots void SetDrawingAsDotsPatternThreeBlackCrows(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternThreeBlackCrows(flag,redraw); } //--- Set the flag for drawing the Shooting Star pattern with dots void SetDrawingAsDotsPatternShootingStar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternShootingStar(flag,redraw); } //--- Set the flag for drawing the Hammer pattern with dots void SetDrawingAsDotsPatternHammer(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternHammer(flag,redraw); } //--- Set the flag for drawing the Inverted Hammer pattern with dots void SetDrawingAsDotsPatternInvertedHammer(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternInvertedHammer(flag,redraw); } //--- Set the flag for drawing the Hanging Man pattern with dots void SetDrawingAsDotsPatternHangingMan(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternHangingMan(flag,redraw); } //--- Set the flag for drawing the Doji pattern with dots void SetDrawingAsDotsPatternDoji(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternDoji(flag,redraw); } //--- Set the flag for drawing the Dragonfly Doji pattern with dots void SetDrawingAsDotsPatternDragonflyDoji(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternDragonflyDoji(flag,redraw); } //--- Set the flag for drawing the Gravestone Doji pattern with dots void SetDrawingAsDotsPatternGravestoneDoji(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternGravestoneDoji(flag,redraw); } //--- Set the flag for drawing the Morning Star pattern with dots void SetDrawingAsDotsPatternMorningStar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternMorningStar(flag,redraw); } //--- Set the flag for drawing the Morning Doji Star pattern with dots void SetDrawingAsDotsPatternMorningDojiStar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternMorningDojiStar(flag,redraw); } //--- Set the flag for drawing the Evening Star pattern with dots void SetDrawingAsDotsPatternEveningStar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternEveningStar(flag,redraw); } //--- Set the flag for drawing the Evening Doji Star pattern with dots void SetDrawingAsDotsPatternEveningDojiStar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternEveningDojiStar(flag,redraw); } //--- Set the flag for drawing the Three Stars pattern with dots void SetDrawingAsDotsPatternThreeStars(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternThreeStars(flag,redraw); } //--- Set the flag for drawing the Abandoned Baby pattern with dots void SetDrawingAsDotsPatternAbandonedBaby(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternAbandonedBaby(flag,redraw); } //--- Set the flag for drawing the Pivot Point Reversal pattern with dots //--- Price Action void SetDrawingAsDotsPatternPivotPointReversal(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternPivotPointReversal(flag,redraw); } //--- Set the flag for drawing the Outside Bar pattern with dots void SetDrawingAsDotsPatternOutsideBar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternOutsideBar(flag,redraw); } //--- Set the flag for drawing the Inside Bar pattern with dots void SetDrawingAsDotsPatternInsideBar(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternInsideBar(flag,redraw); } //--- Set the flag for drawing the Pin Bar pattern with dots void SetDrawingAsDotsPatternPinBar(const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternPinBar(flag,redraw,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //--- Set the flag for drawing the Rails pattern with dots void SetDrawingAsDotsPatternRails(const bool flag,const bool redraw) { if(this.m_patterns_control==NULL) return; this.m_patterns_control.SetDrawingAsDotsPatternRails(flag,redraw); } //+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag for drawing the Harami pattern with dots bool IsDrawingAsDotsPatternHarami(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternHarami() : false); } //--- Return the flag for drawing the Harami Cross pattern with dots bool IsDrawingAsDotsPatternHaramiCross(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternHaramiCross() : false); } //--- Return the flag for drawing the Tweezer pattern with dots bool IsDrawingAsDotsPatternTweezer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternTweezer() : false); } //--- Return the flag for drawing the Piercing Line pattern with dots bool IsDrawingAsDotsPatternPiercingLine(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternPiercingLine() : false); } //--- Return the flag for drawing the Cloud Cover pattern with dots bool IsDrawingAsDotsPatternDarkCloudCover(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternDarkCloudCover() : false); } //--- Return the flag for drawing the Three White Soldiers pattern with dots bool IsDrawingAsDotsPatternThreeWhiteSoldiers(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternThreeWhiteSoldiers() : false); } //--- Return the flag for drawing the Three Black Crows pattern with dots bool IsDrawingAsDotsPatternThreeBlackCrows(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternThreeBlackCrows() : false); } //--- Return the flag for drawing the Shooting Star pattern with dots bool IsDrawingAsDotsPatternShootingStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternShootingStar() : false); } //--- Return the flag for drawing the Hammer pattern with dots bool IsDrawingAsDotsPatternHammer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternHammer() : false); } //--- Return the flag for drawing the Inverted Hammer pattern with dots bool IsDrawingAsDotsPatternInvertedHammer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternInvertedHammer() : false); } //--- Return the flag for drawing the Hanging Man pattern with dots bool IsDrawingAsDotsPatternHangingMan(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternHangingMan() : false); } //--- Return the flag for drawing the Doji pattern with dots bool IsDrawingAsDotsPatternDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternDoji() : false); } //--- Return the flag for drawing the Dragonfly Doji pattern with dots bool IsDrawingAsDotsPatternDragonflyDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternDragonflyDoji() : false); } //--- Return the flag for drawing the Gravestone Doji pattern with dots bool IsDrawingAsDotsPatternGravestoneDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternGravestoneDoji() : false); } //--- Return the flag for drawing the Morning Star pattern with dots bool IsDrawingAsDotsPatternMorningStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternMorningStar() : false); } //--- Return the flag for drawing the Morning Doji Star pattern with dots bool IsDrawingAsDotsPatternMorningDojiStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternMorningDojiStar() : false); } //--- Return the flag for drawing the Evening Star pattern with dots bool IsDrawingAsDotsPatternEveningStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternEveningStar() : false); } //--- Return the flag for drawing the Evening Doji Star pattern with dots bool IsDrawingAsDotsPatternEveningDojiStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternEveningDojiStar() : false); } //--- Return the flag for drawing the Three Stars pattern with dots bool IsDrawingAsDotsPatternThreeStars(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternThreeStars() : false); } //--- Return the flag for drawing the Abandoned Baby pattern with dots bool IsDrawingAsDotsPatternAbandonedBaby(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternAbandonedBaby() : false); } //--- Price Action //--- Return the flag for drawing the Pivot Point Reversal pattern with dots bool IsDrawingAsDotsPatternPivotPointReversal(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternPivotPointReversal() : false); } //--- Return the flag for drawing the Outside Bar pattern with dots bool IsDrawingAsDotsPatternOutsideBar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternOutsideBar() : false); } //--- Return the flag for drawing the Inside Bar pattern with dots bool IsDrawingAsDotsPatternInsideBar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternInsideBar() : false); } //--- Return the flag for drawing the Pin Bar pattern with dots bool IsDrawingAsDotsPatternPinBar(const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //--- Return the flag for drawing the Rails pattern with dots bool IsDrawingAsDotsPatternRails(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsDrawingAsDotsPatternRails() : false); }
Die gleichen Methoden müssen in die Datei \MQL5\Include\DoEasy\Objects\Series\TimeSeriesDE.mqh der Klasse der Zeitreihen des Symbol geschrieben werden:
Wir deklarieren die folgenden Methoden im öffentlichen Bereich:
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist //--- Price Action void SetDrawingAsDotsPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetDrawingAsDotsPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetDrawingAsDotsPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternPinBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30); // Percentage ratio of the size of the smaller shadow to the size of the candle //--- Set the flag for using the Rails pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternRails(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsDrawingAsDotsPatternHarami(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Harami Cross pattern bool IsDrawingAsDotsPatternHaramiCross(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Tweezer pattern bool IsDrawingAsDotsPatternTweezer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Piercing Line pattern bool IsDrawingAsDotsPatternPiercingLine(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Cloud Cover pattern bool IsDrawingAsDotsPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three White Soldiers pattern bool IsDrawingAsDotsPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Black Crows pattern bool IsDrawingAsDotsPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Shooting Star pattern bool IsDrawingAsDotsPatternShootingStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hammer pattern bool IsDrawingAsDotsPatternHammer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inverted Hammer pattern bool IsDrawingAsDotsPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hanging Man pattern bool IsDrawingAsDotsPatternHangingMan(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Doji pattern bool IsDrawingAsDotsPatternDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Dragonfly Doji pattern bool IsDrawingAsDotsPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Gravestone Doji pattern bool IsDrawingAsDotsPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Star pattern bool IsDrawingAsDotsPatternMorningStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Doji Star pattern bool IsDrawingAsDotsPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Star pattern bool IsDrawingAsDotsPatternEveningStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Doji Star pattern bool IsDrawingAsDotsPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Stars pattern bool IsDrawingAsDotsPatternThreeStars(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Abandoned Baby pattern bool IsDrawingAsDotsPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe); //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsDrawingAsDotsPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pattern Outside bool IsDrawingAsDotsPatternOutsideBar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inside Bar pattern bool IsDrawingAsDotsPatternInsideBar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pin Bar pattern bool IsDrawingAsDotsPatternPinBar(const ENUM_TIMEFRAMES timeframe,double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30); // Percentage ratio of the size of the smaller shadow to the size of the candle //--- Return the flag of using the Rails pattern bool IsDrawingAsDotsPatternRails(const ENUM_TIMEFRAMES timeframe); //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+
Die deklarierten Methoden implementieren wir außerhalb des Hauptteils der Klasse:
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //--- Set the flag for drawing the Harami pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternHarami(flag,redraw); } //--- Set the flag for drawing the Harami Cross pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternHaramiCross(flag,redraw); } //--- Set the flag for drawing the Tweezer pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternTweezer(flag,redraw); } //--- Set the flag for drawing the Piercing Line pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternPiercingLine(flag,redraw); } //--- Set the flag for drawing the Cloud Cover pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternDarkCloudCover(flag,redraw); } //--- Set the flag for drawing the Three White Soldiers pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternThreeWhiteSoldiers(flag,redraw); } //--- Set the flag for drawing the Three Black Crows pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternThreeBlackCrows(flag,redraw); } //--- Set the flag for drawing the Shooting Star pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternShootingStar(flag,redraw); } //--- Set the flag for drawing the Hammer pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternHammer(flag,redraw); } //--- Set the flag for drawing the Inverted Hammer pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternInvertedHammer(flag,redraw); } //--- Set the flag for drawing the Hanging Man pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternHangingMan(flag,redraw); } //--- Set the flag for drawing the Doji pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternDoji(flag,redraw); } //--- Set the flag for drawing the Dragonfly Doji pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternDragonflyDoji(flag,redraw); } //--- Set the flag for drawing the Gravestone Doji pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternGravestoneDoji(flag,redraw); } //--- Set the flag for drawing the Morning Star pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternMorningStar(flag,redraw); } //--- Set the flag for drawing the Morning Doji Star pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternMorningDojiStar(flag,redraw); } //--- Set the flag for drawing the Evening Star pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternEveningStar(flag,redraw); } //--- Set the flag for drawing the Evening Doji Star pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternEveningDojiStar(flag,redraw); } //--- Set the flag for drawing the Three Stars pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternThreeStars(flag,redraw); } //--- Set the flag for drawing the Abandoned Baby pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternAbandonedBaby(flag,redraw); } //--- Set the flag for drawing the Pivot Point Reversal pattern with dots //--- Price Action void CTimeSeriesDE::SetDrawingAsDotsPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternPivotPointReversal(flag,redraw); } //--- Set the flag for drawing the Outside Bar pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternOutsideBar(flag,redraw); } //--- Set the flag for drawing the Inside Bar pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternInsideBar(flag,redraw); } //--- Set the flag for drawing the Pin Bar pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternPinBar(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternPinBar(flag,redraw,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //--- Set the flag for drawing the Rails pattern with dots void CTimeSeriesDE::SetDrawingAsDotsPatternRails(const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetDrawingAsDotsPatternRails(flag,redraw); } //+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag for drawing the Harami pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternHarami(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternHarami() : false); } //--- Return the flag for drawing the Harami Cross pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternHaramiCross(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternHaramiCross() : false); } //--- Return the flag for drawing the Tweezer pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternTweezer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternTweezer() : false); } //--- Return the flag for drawing the Piercing Line pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternPiercingLine(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternPiercingLine() : false); } //--- Return the flag for drawing the Cloud Cover pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternDarkCloudCover() : false); } //--- Return the flag for drawing the Three White Soldiers pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternThreeWhiteSoldiers() : false); } //--- Return the flag for drawing the Three Black Crows pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternThreeBlackCrows() : false); } //--- Return the flag for drawing the Shooting Star pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternShootingStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternShootingStar() : false); } //--- Return the flag for drawing the Hammer pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternHammer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternHammer() : false); } //--- Return the flag for drawing the Inverted Hammer pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternInvertedHammer() : false); } //--- Return the flag for drawing the Hanging Man pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternHangingMan(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternHangingMan() : false); } //--- Return the flag for drawing the Doji pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternDoji() : false); } //--- Return the flag for drawing the Dragonfly Doji pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternDragonflyDoji() : false); } //--- Return the flag for drawing the Gravestone Doji pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternGravestoneDoji() : false); } //--- Return the flag for drawing the Morning Star pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternMorningStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternMorningStar() : false); } //--- Return the flag for drawing the Morning Doji Star pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternMorningDojiStar() : false); } //--- Return the flag for drawing the Evening Star pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternEveningStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternEveningStar() : false); } //--- Return the flag for drawing the Evening Doji Star pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternEveningDojiStar() : false); } //--- Return the flag for drawing the Three Stars pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternThreeStars(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternThreeStars() : false); } //--- Return the flag for drawing the Abandoned Baby pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternAbandonedBaby() : false); } //--- Price Action //--- Return the flag for drawing the Pivot Point Reversal pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternPivotPointReversal() : false); } //--- Return the flag for drawing the Outside Bar pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternOutsideBar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternOutsideBar() : false); } //--- Return the flag for drawing the Inside Bar pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternInsideBar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternInsideBar() : false); } //--- Return the flag for drawing the Pin Bar pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternPinBar(const ENUM_TIMEFRAMES timeframe,const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //--- Return the flag for drawing the Rails pattern with dots bool CTimeSeriesDE::IsDrawingAsDotsPatternRails(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsDrawingAsDotsPatternRails() : false); }
In den folgenden Artikeln werden wir Chartparameter verfolgen, um Charteigenschaften in Zeitreihenobjekten zurückzusetzen, die zum Zeichnen von Mustersymbolen verwendet werden. Alle Eigenschaften aller im Terminal geöffneten Charte sind in der Chartsammlung der Bibliothek enthalten. Damit wir von der Zeitreihensammlung aller Symbole aus Zugriff auf die Daten dieser Sammlung haben, müssen wir den Zeiger auf die Chartsammlung an die Zeitreihensammlung übergeben.
Zu diesem Zweck verbinden wir die Datei der Chartsammlung mit der Datei \MQL5\Include\DoEasy\Collections\TimeSeriesCollection.mqh. Außerdem deklarieren wir den Zeiger auf die Chartsammlung im privaten Abschnitt:
//+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Series\TimeSeriesDE.mqh" #include "..\Objects\Symbols\Symbol.mqh" #include "ChartObjCollection.mqh" //+------------------------------------------------------------------+ //| Symbol timeseries collection | //+------------------------------------------------------------------+ class CTimeSeriesCollection : public CBaseObjExt { private: CListObj m_list; // List of applied symbol timeseries CListObj m_list_all_patterns; // List of all patterns of all used symbol timeseries CChartObjCollection *m_charts; // Pointer to the chart collection //--- Return the timeseries index by symbol name int IndexTimeSeries(const string symbol); public:
Deklarieren wir die neuen Methoden im öffentlichen Teil der Klasse, und zwar in den Methoden zur Behandlung der Zeitreihenmuster:
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist //--- Price Action void SetDrawingAsDotsPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetDrawingAsDotsPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetDrawingAsDotsPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30); // Percentage ratio of the size of the smaller shadow to the size of the candle //--- Set the flag for using the Rails pattern and create a control object if it does not already exist void SetDrawingAsDotsPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw); //+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsDrawingAsDotsPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Harami Cross pattern bool IsDrawingAsDotsPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Tweezer pattern bool IsDrawingAsDotsPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Piercing Line pattern bool IsDrawingAsDotsPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Cloud Cover pattern bool IsDrawingAsDotsPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three White Soldiers pattern bool IsDrawingAsDotsPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Black Crows pattern bool IsDrawingAsDotsPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Shooting Star pattern bool IsDrawingAsDotsPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hammer pattern bool IsDrawingAsDotsPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inverted Hammer pattern bool IsDrawingAsDotsPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hanging Man pattern bool IsDrawingAsDotsPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Doji pattern bool IsDrawingAsDotsPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Dragonfly Doji pattern bool IsDrawingAsDotsPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Gravestone Doji pattern bool IsDrawingAsDotsPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Star pattern bool IsDrawingAsDotsPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Doji Star pattern bool IsDrawingAsDotsPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Star pattern bool IsDrawingAsDotsPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Doji Star pattern bool IsDrawingAsDotsPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Stars pattern bool IsDrawingAsDotsPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Abandoned Baby pattern bool IsDrawingAsDotsPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsDrawingAsDotsPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pattern Outside bool IsDrawingAsDotsPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inside Bar pattern bool IsDrawingAsDotsPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pin Bar pattern bool IsDrawingAsDotsPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe,double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30); // Percentage ratio of the size of the smaller shadow to the size of the candle //--- Return the flag of using the Rails pattern bool IsDrawingAsDotsPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe);
Am Ende des Klassenkörpers implementieren wir die Initialisierungsmethode, in der der Zeiger, der an die Methode übergeben wird, dem Zeiger auf die oben deklarierte Chartsammlung zugewiesen wird:
//--- Draw Rails pattern labels on the chart void DrawPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Initialization void OnInit(CChartObjCollection *charts) { this.m_charts=charts; } //--- Constructor CTimeSeriesCollection(void); };
Wir implementieren deklarierte Methoden außerhalb des Klassenkörpers, um Zeitreihenmuster zu behandeln:
//+------------------------------------------------------------------+ //| Methods for setting the flag of drawing the pattern using dots | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Set the flag for drawing the Harami pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternHarami(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Harami Cross pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternHaramiCross(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Tweezer pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternTweezer(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Piercing Line pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternPiercingLine(timeframe,flag,redraw); } //+----------------------------------------------------------------------+ //|Set the flag for drawing the Cloud Cover pattern with dots | //+----------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternDarkCloudCover(timeframe,flag,redraw); } //+--------------------------------------------------------------------+ //| Set the flag for drawing the Three White Soldiers pattern with dots| //+--------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternThreeWhiteSoldiers(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Three Black Crows pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternThreeBlackCrows(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Shooting Star pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternShootingStar(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Hammer pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternHammer(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Inverted Hammer pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternInvertedHammer(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Hanging Man pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternHangingMan(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Doji pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternDoji(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Dragonfly Doji pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternDragonflyDoji(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Gravestone Doji pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternGravestoneDoji(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Morning Star pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternMorningStar(timeframe,flag,redraw); } //+-------------------------------------------------------------------+ //|Set the flag for drawing the Morning Doji Star pattern with dots | //+-------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternMorningDojiStar(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Evening Star pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternEveningStar(timeframe,flag,redraw); } //+-------------------------------------------------------------------+ //|Set the flag for drawing the Evening Doji Star pattern with dots | //+-------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternEveningDojiStar(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Three Stars pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternThreeStars(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Abandoned Baby pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternAbandonedBaby(timeframe,flag,redraw); } //--- Price Action //+------------------------------------------------------------------+ //|Set the flag for drawing the Pivot Point Reversal pattern with dots| //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternPivotPointReversal(timeframe,flag,redraw); } //+----------------------------------------------------------------------+ //|Set the flag for drawing the Outside Bar pattern with dots | //+----------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternOutsideBar(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Inside Bar pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternInsideBar(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Pin Bar pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const bool flag,const bool redraw, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternPinBar(timeframe,flag,redraw,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //+------------------------------------------------------------------+ //| Set the flag for drawing the Rails pattern with dots | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetDrawingAsDotsPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetDrawingAsDotsPatternRails(timeframe,flag,redraw); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods of returning the flag of drawing with dots | //+------------------------------------------------------------------+ //--- Candle formations //+------------------------------------------------------------------+ //| Return the flag for drawing the Harami pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternHarami(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Harami Cross pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternHaramiCross(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Tweezer pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternTweezer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Piercing Line pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternPiercingLine(timeframe) : false); } //+-------------------------------------------------------------------+ //|Return the flag for drawing the Cloud Cover pattern with dots | //+-------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternDarkCloudCover(timeframe) : false); } //+-----------------------------------------------------------------------+ //| Return the flag for drawing the Three White Soldiers pattern with dots| //+-----------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternThreeWhiteSoldiers(timeframe) : false); } //+--------------------------------------------------------------------+ //| Return the flag for drawing the Three Black Crows pattern with dots| //+--------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternThreeBlackCrows(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Shooting Star pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternShootingStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Hammer pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternHammer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Inverted Hammer pattern with dots| //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternInvertedHammer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Hanging Man pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternHangingMan(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Doji pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Dragonfly Doji pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternDragonflyDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Gravestone Doji pattern with dots| //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternGravestoneDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Morning Star pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternMorningStar(timeframe) : false); } //+---------------------------------------------------------------------+ //| Return the flag for drawing the Morning Doji Star pattern with dots | //+---------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternMorningDojiStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Evening Star pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternEveningStar(timeframe) : false); } //+---------------------------------------------------------------------+ //| Return the flag for drawing the Evening Doji Star pattern with dots | //+---------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternEveningDojiStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Three Stars pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternThreeStars(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Abandoned Baby pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternAbandonedBaby(timeframe) : false); } //--- Price Action //+-------------------------------------------------------------------------+ //| Return the flag for drawing the Pivot Point Reversal pattern with dots | //+-------------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternPivotPointReversal(timeframe) : false); } //+-------------------------------------------------------------------+ //|Return the flag for drawing the Outside Bar pattern with dots | //+-------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternOutsideBar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Inside Bar pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternInsideBar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Pin Bar pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternPinBar(timeframe,ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //+------------------------------------------------------------------+ //| Return the flag for drawing the Rails pattern with dots | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsDrawingAsDotsPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsDrawingAsDotsPatternRails(timeframe) : false); }
Ich habe ähnliche Methoden in einem früheren Artikel entwickelt, wo sie ausführlicher beschrieben wurden. Im Grunde ist alles ganz einfach: Wir holen uns den Zeiger auf das gewünschte Symbol Zeitreihe und geben das Ergebnis der gleichnamigen Methode auf die erhaltene Zeitreihe zurück. Dort wiederum wird der Zeiger auf die gewünschte Zeitreihe des Chartzeitraums auf genau die gleiche Weise erhalten. Die erforderliche Kontrollmethode wird vom Zeitreihenmuster-Kontrollobjekt aufgerufen, dessen Zeiger von der Methode zurückgegeben wird, die wiederum von der erwähnten Zeitreihe aufgerufen wird - die Kette funktioniert, bis das gewünschte Ergebnis erreicht ist. Das Design ist verschachtelt und unpraktisch in Bezug auf die Menge an identischen Codes. Später werde ich versuchen, ihn zu verkürzen, indem ich den Zugriff auf die erforderlichen Objekte anders gestalte.
Das Gleiche muss mit der Hauptklasse der CEngine-Bibliothek in \MT5\MQL5\Include\DoEasy\Engine.mqh gemacht werden.
Wir ersetzen in allen Methoden zur Behandlung von Mustern die gleichen oder ähnliche Zeichenketten von Eingaben
CArrayObj *list=this.GetListPatterns(symbol,timeframe);
mit den folgenden:
CArrayObj *list=this.GetListPatterns(CorrectSymbol(symbol),CorrectTimeframe(timeframe));
Hier haben wir die in den Methodenparametern übergebenen Werte für das Symbol und die Chartperiode durch die zu Beginn des Artikels implementierten Funktionen zur Anpassung dieser Parameter ersetzt.
Implementieren wir in dem Abschnitt, der sich mit den Methoden zur Behandlung von Mustern befasst, neue Methoden zur Behandlung von Musterzeichnungsflags als Punkt:
//--- Set the flag for using the Rails pattern and create a control object if it does not already exist void SeriesSetUsedPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternRails(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag); } //--- Set the flag for drawing the Harami pattern with dots void SeriesSetDrawingAsDotsPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternHarami(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Harami Cross pattern with dots void SeriesSetDrawingAsDotsPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternHaramiCross(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Tweezer pattern with dots void SeriesSetDrawingAsDotsPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternTweezer(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Piercing Line pattern with dots void SeriesSetDrawingAsDotsPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternPiercingLine(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Cloud Cover pattern with dots void SeriesSetDrawingAsDotsPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternDarkCloudCover(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Three White Soldiers pattern with dots void SeriesSetDrawingAsDotsPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternThreeWhiteSoldiers(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Three Black Crows pattern with dots void SeriesSetDrawingAsDotsPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternThreeBlackCrows(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Shooting Star pattern with dots void SeriesSetDrawingAsDotsPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternShootingStar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Hammer pattern with dots void SeriesSetDrawingAsDotsPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternHammer(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Inverted Hammer pattern with dots void SeriesSetDrawingAsDotsPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternInvertedHammer(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Hanging Man pattern with dots void SeriesSetDrawingAsDotsPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternHangingMan(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Doji pattern with dots void SeriesSetDrawingAsDotsPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternDoji(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Dragonfly Doji pattern with dots void SeriesSetDrawingAsDotsPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternDragonflyDoji(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Gravestone Doji pattern with dots void SeriesSetDrawingAsDotsPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternGravestoneDoji(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Morning Star pattern with dots void SeriesSetDrawingAsDotsPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternMorningStar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Morning Doji Star pattern with dots void SeriesSetDrawingAsDotsPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternMorningDojiStar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Evening Star pattern with dots void SeriesSetDrawingAsDotsPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternEveningStar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Evening Doji Star pattern with dots void SeriesSetDrawingAsDotsPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternEveningDojiStar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Three Stars pattern with dots void SeriesSetDrawingAsDotsPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternThreeStars(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Abandoned Baby pattern with dots void SeriesSetDrawingAsDotsPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternAbandonedBaby(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Pivot Point Reversal pattern with dots //--- Price Action void SeriesSetDrawingAsDotsPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternPivotPointReversal(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Outside Bar pattern with dots void SeriesSetDrawingAsDotsPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternOutsideBar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Inside Bar pattern with dots void SeriesSetDrawingAsDotsPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternInsideBar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Set the flag for drawing the Pin Bar pattern with dots void SeriesSetDrawingAsDotsPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const bool flag,const bool redraw=false, // Flag of drawing with dots and Pin Bar Price Action redraw flag const double ratio_body=30, // Percentage ratio of the candle body to the full size of the candle const double ratio_larger_shadow=60, // Percentage ratio of the size of the larger shadow to the size of the candle const double ratio_smaller_shadow=30) // Percentage ratio of the size of the smaller shadow to the size of the candle { this.m_time_series.SetDrawingAsDotsPatternPinBar(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //--- Set the flag for drawing the Rails pattern with dots void SeriesSetDrawingAsDotsPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag,const bool redraw=false) { this.m_time_series.SetDrawingAsDotsPatternRails(CorrectSymbol(symbol),CorrectTimeframe(timeframe),flag,redraw); } //--- Draw Harami pattern labels on the chart void SeriesDrawPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternHarami(CorrectSymbol(symbol),CorrectTimeframe(timeframe),redraw); }
Die Methoden rufen die entsprechenden Methoden der oben implementierten Zeitreihensammlungsklasse auf.
Im selben Abschnitt implementieren wir die Methode, mit der wir die Infotafeln aller Muster ausblenden, außer denen, die sich zur angegebenen Balkenzeit befinden:
//--- Hides info panels of all patterns except the specified one void SeriesPatternHideAllInfoPanelsExceptOne(const ulong pattern_code,const bool redraw=false) { CArrayObj *list=CSelect::ByPatternProperty(this.GetListAllPatterns(),PATTERN_PROP_CODE,pattern_code,NO_EQUAL); if(list==NULL) return; for(int i=list.Total()-1;i>=0;i--) { CPattern *obj=list.At(i); if(obj!=NULL) obj.HideInfoPanel(); } if(redraw) ::ChartRedraw(); } //--- Hide info panels of all patterns except those at the specified time of the bar void SeriesPatternHideAllInfoPanelsExceptBarTime(const datetime bar_time,const bool redraw=false) { CArrayObj *list=CSelect::ByPatternProperty(this.GetListAllPatterns(),PATTERN_PROP_TIME,bar_time,NO_EQUAL); if(list==NULL) return; for(int i=list.Total()-1;i>=0;i--) { CPattern *obj=list.At(i); if(obj!=NULL) obj.HideInfoPanel(); } if(redraw) ::ChartRedraw(); }
Hier erhalten wir aus der Liste aller Muster eine Liste derjenigen Muster, die nicht auf dem Balken mit der angegebenen Eröffnungszeit liegen. In der Schleife holen wir uns dann den Zeiger auf das nächste Musterobjekt aus der resultierenden Liste und blenden sein Informationsfeld aus. Am Ende des Zyklus wird das Chart neu gezeichnet, wenn das Redraw-Flag gesetzt ist.
Fügen wir die Übergabe des Zeigers auf die Chartsammlung in die Methode ein, die die Zeiger auf alle erforderlichen Sammlungen an die Handelsklasse und die Sammelklasse übergibt:
//--- Play a sound by its description bool PlaySoundByDescription(const string sound_description); //--- Pass the pointers to all the necessary collections to the trading class and the indicator buffer collection class void CollectionOnInit(void) { this.m_trading.OnInit(this.GetAccountCurrent(),this.m_symbols.GetObject(),this.m_market.GetObject(),this.m_history.GetObject(),this.m_events.GetObject()); this.m_buffers.OnInit(this.m_time_series.GetObject(),this.m_indicators.GetObject()); this.m_time_series.OnInit(this.GetChartObjCollection()); } //--- Set the spread multiplier for symbol trading objects in the symbol collection void SetSpreadMultiplier(const uint value=1,const string symbol=NULL) { this.m_trading.SetSpreadMultiplier(value,symbol); }
Erstellen wir in der Ereignisbehandlung der DoEasy-Bibliothek ein Leerzeichen für die Behandlung von Chartsammlungsereignissen:
//--- Handling market watch window events else if(idx>MARKET_WATCH_EVENT_NO_EVENT && idx<SYMBOL_EVENTS_NEXT_CODE) { //--- Market Watch window event string descr=this.GetMWEventDescription((ENUM_MW_EVENT)idx); string name=(idx==MARKET_WATCH_EVENT_SYMBOL_SORT ? "" : ": "+sparam); Print(TimeMSCtoString(lparam)," ",descr,name); } //--- Handle chart events else if(idx>CHART_OBJ_EVENT_NO_EVENT && idx<CHART_OBJ_EVENTS_NEXT_CODE) { } //--- Handling timeseries events else if(idx>SERIES_EVENTS_NO_EVENT && idx<SERIES_EVENTS_NEXT_CODE) {
Anschließend werde ich hier Handler für die Größenänderung des Charts und die Übergabe neuer Werte an die Zeitreihensammlung und von dort an die Musterobjekte hinzufügen.
Jetzt ist alles bereit für die Prüfung der Ergebnisse.Test
Um den Test durchzuführen, verwenden wir den EA aus dem vorherigen Artikel und speichern ihn im neu erstellten Ordner \MQL5\Experts\TestDoEasy\Part135\ als TestDoEasy135.mq5.
Fügen wir die Variable, die das Flag für das Zeichnen von Mustern mit Punkten setzt, zur Liste der Eingaben hinzu:
//--- input variables input ushort InpMagic = 123; // Magic number input double InpLots = 0.1; // Lots input uint InpStopLoss = 150; // StopLoss in points input uint InpTakeProfit = 150; // TakeProfit in points input uint InpDistance = 50; // Pending orders distance (points) input uint InpDistanceSL = 50; // StopLimit orders distance (points) input uint InpDistancePReq = 50; // Distance for Pending Request's activate (points) input uint InpBarsDelayPReq = 5; // Bars delay for Pending Request's activate (current timeframe) input uint InpSlippage = 5; // Slippage in points input uint InpSpreadMultiplier = 1; // Spread multiplier for adjusting stop-orders by StopLevel input uchar InpTotalAttempts = 5; // Number of trading attempts sinput double InpWithdrawal = 10; // Withdrawal funds (in tester) sinput uint InpButtShiftX = 0; // Buttons X shift sinput uint InpButtShiftY = 10; // Buttons Y shift input uint InpTrailingStop = 50; // Trailing Stop (points) input uint InpTrailingStep = 20; // Trailing Step (points) input uint InpTrailingStart = 0; // Trailing Start (points) input uint InpStopLossModify = 20; // StopLoss for modification (points) input uint InpTakeProfitModify = 60; // TakeProfit for modification (points) sinput ENUM_SYMBOLS_MODE InpModeUsedSymbols = SYMBOLS_MODE_CURRENT; // Mode of used symbols list sinput string InpUsedSymbols = "EURUSD,AUDUSD,EURAUD,EURCAD,EURGBP,EURJPY,EURUSD,GBPUSD,NZDUSD,USDCAD,USDJPY"; // List of used symbols (comma - separator) sinput ENUM_TIMEFRAMES_MODE InpModeUsedTFs = TIMEFRAMES_MODE_CURRENT; // Mode of used timeframes list sinput string InpUsedTFs = "M1,M5,M15,M30,H1,H4,D1,W1,MN1"; // List of used timeframes (comma - separator) sinput double InpPinBarRatioBody = 30.0; // Pin Bar Ratio Body to Candle size sinput double InpPinBarRatioLarger = 60.0; // Pin Bar Ratio Larger shadow to Candle size sinput double InpPinBarRatioSmaller= 30.0; // Pin Bar Ratio Smaller shadow to Candle size sinput bool InpDrawPatternsAsDots= true; // Draw Patterns as dots sinput ENUM_INPUT_YES_NO InpUseBook = INPUT_NO; // Use Depth of Market sinput ENUM_INPUT_YES_NO InpUseMqlSignals = INPUT_NO; // Use signal service sinput ENUM_INPUT_YES_NO InpUseCharts = INPUT_NO; // Use Charts control sinput ENUM_INPUT_YES_NO InpUseSounds = INPUT_YES; // Use sounds //--- global variables
Wenn true, werden alle gefundenen Muster als Punkte auf dem Chart gezeichnet. Wenn false, werden die „Inside-Bar“-Muster mit Bitmap-Objekten gezeichnet - die Musterbalken werden mit farbigen Rechtecken umrandet.
In OnInit() des EA konfigurieren wir die Suche und Anzeige von Mustern:
//--- Clear the list of all patterns engine.GetListAllPatterns().Clear(); //--- Set the flag of using the Pin Bar pattern with the parameters specified in the settings engine.SeriesSetUsedPatternPinBar(NULL,PERIOD_CURRENT,true,InpPinBarRatioBody,InpPinBarRatioLarger,InpPinBarRatioSmaller); //--- Set the flag of using the Inside Bar pattern engine.SeriesSetUsedPatternInsideBar(NULL,PERIOD_CURRENT,true); //--- Set the flag for drawing the Inside Bar as dots from the inputs engine.SeriesSetDrawingAsDotsPatternInsideBar(NULL,PERIOD_CURRENT,InpDrawPatternsAsDots); //--- Display the Pin Bar pattern icons with the parameters, specified in the settings, on the chart engine.SeriesDrawPatternPinBar(NULL,PERIOD_CURRENT,InpPinBarRatioBody,InpPinBarRatioLarger,InpPinBarRatioSmaller); //--- Display the Inside Bar pattern icons on the chart engine.SeriesDrawPatternInsideBar(NULL,PERIOD_CURRENT,true); //--- return(INIT_SUCCEEDED); }
Wir implementieren in OnChartEvent() des EA den Code-Block zur Anzeige der Muster-Infopanels:
//--- Check ChartXYToTimePrice() if(id==CHARTEVENT_MOUSE_MOVE) { //--- Get the chart object of the current (main) program chart CChartObj *chart=engine.ChartGetMainChart(); if(chart==NULL) return; //--- Get the index of a subwindow the cursor is located at int wnd_num=chart.XYToTimePrice(lparam,dparam); if(wnd_num==WRONG_VALUE) return; //--- Get the calculated cursor location time and price datetime time=chart.TimeFromXY(); double price=chart.PriceFromXY(); //--- Get the window object of the chart the cursor is located in by the subwindow index CChartWnd *wnd=chart.GetWindowByNum(wnd_num); if(wnd==NULL) return; //--- If X and Y coordinates are calculated by time and price (make a reverse conversion), if(wnd.TimePriceToXY(time,price)) { //--- in the comment, show the time, price and index of the window that are calculated by X and Y cursor coordinates, //--- as well as the cursor X and Y coordinates converted back from the time and price //Comment // ( // DFUN,"time: ",TimeToString(time),", price: ",DoubleToString(price,Digits()), // ", win num: ",(string)wnd_num,": x: ",(string)wnd.XFromTimePrice(), // ", y: ",(string)wnd.YFromTimePrice()," (",(string)wnd.YFromTimePriceRelative(),")" // ); //--- Get the bar open time on the chart using the cursor time datetime bar_time=GetStartTimeOfBarFast(PERIOD_CURRENT,time); //--- Get the pointer to the bar whose opening time was obtained CBar *bar=engine.SeriesGetBar(Symbol(),PERIOD_CURRENT,bar_time); if(bar!=NULL && price>=bar.Low() && price<=bar.High()) { //--- From the bar object, get the list of patterns found in it into the 'array' ulong array[]={}; int total=bar.GetPatternsList(array); //--- If patterns are found on the bar, if(total>0) { //--- display descriptions of all patterns found on the bar in the journal bar.PatternTypeDescriptionPrint(true); //--- In the loop based on the number of patterns found on the bar, for(int i=0;i<(int)array.Size();i++) { //--- get the type of the next pattern from the 'array', as well as the pointer to it ENUM_PATTERN_TYPE type=(ENUM_PATTERN_TYPE)array[i]; CPattern *pattern=engine.GetPattern(Symbol(),PERIOD_CURRENT,bar_time,type); //--- Print a short description of the pattern in the journal if(pattern==NULL) continue; pattern.PrintShort(true); //pattern.Print(false,true); //--- Get the chart coordinates where you want to display the information panel int x=wnd.XFromTimePrice(); int y=wnd.YFromTimePrice(); //--- Hide all panels except those belonging to patterns found on the bar under the cursor engine.SeriesPatternHideAllInfoPanelsExceptBarTime(bar_time); //--- calculate the Y coordinate of the information panel from the loop index static int shift=0; int cy=y+shift*i; //--- Display the information panel on the chart pattern.ShowInfoPanel(x,cy); CForm *form=pattern.GetForm(); //--- If the pointer to the panel is received, calculate the size of the Y coordinate offset (panel height + 1) if(form!=NULL) shift=form.Height()+1; } } } } }
Die Logik des Codes ist in den Kommentaren beschrieben. Wir müssen die Öffnungszeit des Balkens ermitteln, über dem sich der Mauszeiger befindet. Auf der Grundlage der Öffnungszeit erhalten wir das Balkenobjekt, aus dem wir die Liste der erkannten Muster „herausziehen“.
Dann zeigen wir einfach die Infotafeln der einzelnen gefundenen Muster auf dem Bildschirm an.
Kompilieren Sie den EA und starten Sie ihn auf einem Chart:
Wie wir sehen können, funktioniert alles wie vorgesehen. Das Zeichnen von Mustern als Bilder kann zu Verzögerungen führen. Wir werden uns später damit befassen.
Wir sehen das verschachtelte Muster ungefähr in der Mitte des Bildschirms. Wenn Sie den Mauszeiger bewegen und das Informationsfenster erscheint, wird die Gesamtzahl der in der Musterkette enthaltenen Balken angezeigt.
Auf der rechten Seite des Bildschirms werden zwei Muster auf einem Balken gebildet - „Pin-Bar“ und „Inside-Bar“. Die Infotafeln der beiden Muster werden übereinander angezeigt.
Was kommt als Nächstes?
Im nächsten Artikel werde ich mit der Entwicklung von Zeitreihenmustern fortfahren.
Alle erstellten Dateien sind dem Artikel beigefügt und können zum Selbststudium und für Tests heruntergeladen werden.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/14479
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.