DoEasy - サービス関数(第1回):価格パターン
内容
概念
DoEasyライブラリは、取引環境から様々なデータを便利に取得できるツールとして開発されています。このライブラリでは、特定のパラメータで特定のデータにのみアクセスできるように、任意のデータリストを並び替えることができます。これによって、ライブラリに標準的な機能を追加することができるので、ユーザーが簡単にライブラリを作成できるようになります。機能はライブラリから直接使用できるようになります。
様々な種類の標準機能の作成があらかじめ計画されており、その機能は徐々にライブラリに追加されていきます。今回は、時系列データに見られる価格パターンを検索表示するためのツールをライブラリに追加します。時系列クラスは、任意の時系列の任意のデータに素早くアクセスする機能を提供します。このデータを使用すれば、どのような著者が記述したパターンでも、独自に開発したパターンでも、簡単に見つけることができます。
どのようなパターンにも共通するパラメータがあります。この種のデータはすべて、基となる抽象パターンのオブジェクトクラスに集約されます。このクラスを基に、パターンタイプごとに分散した継承クラスを作成します。発見されたパターンはすべて時系列バーと関連付けられ、発見されたバーを使用してそのバーで発見されたパターンを参照することができます。どのようなパターンもベースバーを含み、そこからフォーメーションが探索され、パターンが出来上がります。そのため、1本のバーに異なるパターンが存在することもあります。従って、時系列バーにはパターンのリストが保存され、それがベースとなります。
各パターンについて、チャート上にグラフィカルに表示する機能を提供します。パターンアイコンでチャートに負荷がかからないように、プログラムの指示に従ってアイコンを表示できるようにします。各パターンは、それを検索するための異なる設定を持つことができます。同じタイプだがパラメータセットが異なるパターンを作成する機会もあります。これらは同じタイプの2つ以上の異なるパターンです。このアプローチでは、特定のパターンを、そのさまざまなパラメータを示しながら検索することができます。検出されたすべてのパターンのリストは、指定されたパラメータに従って素早くアクセスできるようにプログラムに保存されます。こうすることで、最初のタイプのパラメータで同じタイプのパターンをすべて見つけ、次に、同じパターンを異なるパラメータで見つけ、何が見つかったかを比較することが可能になります。バーの比率の必要比率を厳格に設定するのではなく、もっと柔軟に、つまり「パラメータをいじる」機会を与えるのが便利だと思います。
あらゆる銘柄とチャート期間で発見されたすべてのパターンは1つのパターンリストに保存され、異なる価格データ上の異なるパターンの共通特性を検索するために、最初に異なるリストから1つのリストに転送することなく、共通のリストを使用することができます。
ライブラリクラスの改善
\MQL5\Include\DoEasy\Defines.mqhで、パターンリストIDのマクロ置換を追加します。
//--- Collection list IDs #define COLLECTION_HISTORY_ID (0x777A) // Historical collection list ID #define COLLECTION_MARKET_ID (0x777B) // Market collection list ID #define COLLECTION_EVENTS_ID (0x777C) // Event collection list ID #define COLLECTION_ACCOUNT_ID (0x777D) // Account collection list ID #define COLLECTION_SYMBOLS_ID (0x777E) // Symbol collection list ID #define COLLECTION_SERIES_ID (0x777F) // Timeseries collection list ID #define COLLECTION_SERIES_PATTERNS_ID (0x7780) // Timeseries pattern list ID #define COLLECTION_BUFFERS_ID (0x7781) // Indicator buffer collection list ID #define COLLECTION_INDICATORS_ID (0x7782) // Indicator collection list ID #define COLLECTION_INDICATORS_DATA_ID (0x7783) // Indicator data collection list ID #define COLLECTION_TICKSERIES_ID (0x7784) // Tick series collection list ID #define COLLECTION_MBOOKSERIES_ID (0x7785) // DOM series collection list ID #define COLLECTION_MQL5_SIGNALS_ID (0x7786) // MQL5 signals collection list ID #define COLLECTION_CHARTS_ID (0x7787) // Chart collection list ID #define COLLECTION_CHART_WND_ID (0x7788) // Chart window list ID #define COLLECTION_GRAPH_OBJ_ID (0x7789) // Graphical object collection list ID #define COLLECTION_ID_LIST_END (COLLECTION_GRAPH_OBJ_ID) // End of collection ID list //--- Pending request type IDs
オブジェクトタイプリストで、今日作成されたパターンクラスの新しいオブジェクトタイプを追加します。
OBJECT_DE_TYPE_SERIES_BAR, // "Bar" object type OBJECT_DE_TYPE_SERIES_PERIOD, // "Period timeseries" object type OBJECT_DE_TYPE_SERIES_SYMBOL, // "Symbol timeseries" object type OBJECT_DE_TYPE_SERIES_PATTERN, // "Pattern" object type OBJECT_DE_TYPE_SERIES_PATTERN_CONTROL, // "Pattern management" object type OBJECT_DE_TYPE_SERIES_PATTERNS_CONTROLLERS, // "Patterns management" object type
- Patternオブジェクトはパターンそのもののオブジェクトです。
- Pattern Managementオブジェクトは、1つの時系列内で同じタイプのパターンを検索作成する機能を持つオブジェクトです。制御オブジェクトはパターンごとに作成されます。
- Patterns Managementオブジェクトは、さまざまなタイプのパターンを管理するためのすべてのオブジェクトのリストを格納し、それらへのアクセスを提供するオブジェクトです。このオブジェクトは、時系列クラスの内部で定義されます。
パターンは、時系列バーの任意のパラメータ、または近接する異なるバーに対するこれらのパラメータの組み合わせを使用して検索されるため、バーのプロパティにローソク足の比率パラメータ(ローソク足のサイズに対するローソク足実体の比率、ローソク足のサイズに対する上髭と下髭のサイズ)を追加し、整数パラメータの総数を10から13に増やします。
//+------------------------------------------------------------------+ //| Real bar properties | //+------------------------------------------------------------------+ enum ENUM_BAR_PROP_DOUBLE { //--- bar data BAR_PROP_OPEN = BAR_PROP_INTEGER_TOTAL, // Bar open price BAR_PROP_HIGH, // Highest price for the bar period BAR_PROP_LOW, // Lowest price for the bar period BAR_PROP_CLOSE, // Bar close price //--- candle data BAR_PROP_CANDLE_SIZE, // Candle size BAR_PROP_CANDLE_SIZE_BODY, // Candle body size BAR_PROP_CANDLE_BODY_TOP, // Candle body top BAR_PROP_CANDLE_BODY_BOTTOM, // Candle body bottom BAR_PROP_CANDLE_SIZE_SHADOW_UP, // Candle upper wick size BAR_PROP_CANDLE_SIZE_SHADOW_DOWN, // Candle lower wick size //--- candle proportions BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE, // Percentage ratio of the candle body to the full size of the candle BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the upper shadow size to the candle size BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the lower shadow size to the candle size }; #define BAR_PROP_DOUBLE_TOTAL (13) // Total number of real bar properties #define BAR_PROP_DOUBLE_SKIP (0) // Number of bar properties not used in sorting
これらの比率を使用すれば、どんなローソク足でも大まかな外観を表現することができ、正しい比率のローソク足を探すこともできます。
パターンタイプとプロパティの列挙を書いてみましょう。
//+------------------------------------------------------------------+ //| Abstract pattern status | //+------------------------------------------------------------------+ enum ENUM_PATTERN_STATUS { PATTERN_STATUS_JC, // Candles PATTERN_STATUS_PA, // Price Action formations };
現時点では、ライブラリにはローソク足のフォーメーションとプライスアクションのフォーメーションという2つの異なるパターンのグループがあります。あるグループに属しているパターンと、別のグループに属しているパターンがあります。上記のリストは、これらの状態について説明したものです。
同じタイプのパターンには、買い、売り、双方向があります。方向別にパターンタイプのリストを書いてみましょう。
//+------------------------------------------------------------------+ //| Pattern type by direction (buy/sell) | //+------------------------------------------------------------------+ enum ENUM_PATTERN_DIRECTION { PATTERN_DIRECTION_BULLISH, // Buy pattern PATTERN_DIRECTION_BEARISH, // Sell pattern PATTERN_DIRECTION_BOTH, // Bidirectional pattern };
パターンタイプを持つ列挙型を書いてみましょう。
//+------------------------------------------------------------------+ //| Pattern type | //+------------------------------------------------------------------+ enum ENUM_PATTERN_TYPE { //--- Candle formations PATTERN_TYPE_HARAMI = 0x0, // Harami PATTERN_TYPE_HARAMI_CROSS = 0x1, // Harami Cross PATTERN_TYPE_TWEEZER = 0x2, // Tweezer PATTERN_TYPE_PIERCING_LINE = 0x4, // Piercing Line PATTERN_TYPE_DARK_CLOUD_COVER = 0x8, // Dark Cloud Cover PATTERN_TYPE_THREE_WHITE_SOLDIERS= 0x10, // Three White Soldiers PATTERN_TYPE_THREE_BLACK_CROWS = 0x20, // Three Black Crows PATTERN_TYPE_SHOOTING_STAR = 0x40, // Shooting Star PATTERN_TYPE_HAMMER = 0x80, // Hammer PATTERN_TYPE_INVERTED_HAMMER = 0x100, // Inverted Hammer PATTERN_TYPE_HANGING_MAN = 0x200, // Hanging Man PATTERN_TYPE_DOJI = 0x400, // Doji PATTERN_TYPE_DRAGONFLY_DOJI = 0x800, // Dragonfly Doji PATTERN_TYPE_GRAVESTONE_DOJI = 0x1000, // Gravestone Doji PATTERN_TYPE_MORNING_STAR = 0x2000, // Morning Star PATTERN_TYPE_MORNING_DOJI_STAR = 0x4000, // Morning Doji Star PATTERN_TYPE_EVENING_STAR = 0x8000, // Evening Star PATTERN_TYPE_EVENING_DOJI_STAR = 0x10000, // Evening Doji Star PATTERN_TYPE_THREE_STARS = 0x20000, // Three Stars PATTERN_TYPE_ABANDONED_BABY = 0x40000, // Abandoned Baby //--- Price Action PATTERN_TYPE_PIVOT_POINT_REVERSAL= 0x80000, // Price Action Reversal Pattern PATTERN_TYPE_OUTSIDE_BAR = 0x100000, // Price Action Outside Bar PATTERN_TYPE_INSIDE_BAR = 0x200000, // Price Action Inside Bar PATTERN_TYPE_PIN_BAR = 0x400000, // Price Action Pin Bar PATTERN_TYPE_RAILS = 0x800000, // Price Action Rails };
このリストにはパターンが含まれており、その検索は徐々にライブラリに追加されていきます。定数の値はビットフラグの形で表されます。これによって、1本のバーに見られるさまざまなタイプのパターンを1つの変数に格納することができ、それが各パターンのベースとなります。
それぞれのパターンには、そのパターン固有の特性があります。しかし、すべてのパターンに共通する性質もあります。パターンの整数、実数、文字列プロパティのリストを書いてみましょう。
//+------------------------------------------------------------------+ //| 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_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 (9) // Total number of integer pattern properties #define PATTERN_PROP_INTEGER_SKIP (0) // Number of pattern properties not used in sorting //+------------------------------------------------------------------+ //| Pattern real properties | //+------------------------------------------------------------------+ enum ENUM_PATTERN_PROP_DOUBLE { //--- bar data PATTERN_PROP_BAR_PRICE_OPEN = PATTERN_PROP_INTEGER_TOTAL,// Pattern defining bar Open price PATTERN_PROP_BAR_PRICE_HIGH, // Pattern defining bar High price PATTERN_PROP_BAR_PRICE_LOW, // Pattern defining bar Low price PATTERN_PROP_BAR_PRICE_CLOSE, // Pattern defining bar Close price PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE, // Percentage ratio of the candle body to the full size of the candle PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the upper shadow size to the candle size PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the lower shadow size to the candle size PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION, // Defined criterion of the ratio of the candle body to the full candle size in % PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION, // Defined criterion of the ratio of the maximum shadow to the candle size in % PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION, // Defined criterion of the ratio of the minimum shadow to the candle size in % }; #define PATTERN_PROP_DOUBLE_TOTAL (10) // Total number of real pattern properties #define PATTERN_PROP_DOUBLE_SKIP (0) // Number of pattern properties not used in sorting //+------------------------------------------------------------------+ //| Pattern string properties | //+------------------------------------------------------------------+ enum ENUM_PATTERN_PROP_STRING { PATTERN_PROP_SYMBOL = (PATTERN_PROP_INTEGER_TOTAL+PATTERN_PROP_DOUBLE_TOTAL), // Pattern symbol PATTERN_PROP_NAME, // Pattern name }; #define PATTERN_PROP_STRING_TOTAL (2) // Total number of pattern string properties
すべてのパターンに固有のプロパティを、これらのプロパティリストに追加していきます。次に、特定のプロパティを使用するためのフラグを返すベースパターンから継承されたメソッドで、これらのリストからどのプロパティがこの特定のパターンに属さないかを示します。
では、一般的なリストのパターンの検索、並び替え、フィルターをおこなうために、可能な基準を列挙して書いてみましょう。
//+------------------------------------------------------------------+ //| 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_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 };
これらのプロパティを使用して、リスト内のパターンを検索することができます。
現在のパターンに最も近いパターンがベースバー上に見つかったら、それを処理して制御プログラムにメッセージを送ることができるように、ライブラリにメッセージを送る必要があります。時系列イベントに関するメッセージを送信し、処理するメソッドはすでにありますが、これらのメソッドでは、新しいパターンを見つけるためにイベントを追加する必要があります。
可能な時系列イベントのリストに、新しいパターンを見つけることに関するメッセージコードを追加 します。
//+------------------------------------------------------------------+ //| List of possible timeseries events | //+------------------------------------------------------------------+ enum ENUM_SERIES_EVENT { SERIES_EVENTS_NO_EVENT = SYMBOL_EVENTS_NEXT_CODE, // no event SERIES_EVENTS_NEW_BAR, // "New bar" event SERIES_EVENTS_MISSING_BARS, // "Bars skipped" event SERIES_EVENTS_PATTERN, // "Pattern" event }; #define SERIES_EVENTS_NEXT_CODE (SERIES_EVENTS_PATTERN+1) // Code of the next event after the "Pattern" event
次のイベントのコードを 「Skipped bars+1」から「 Pattern+1」に変更し、以降のイベントコードが正しい値で始まるようにします。
\MQL5\Include\DoEasy\Data.mqhに、新しいライブラリメッセージのインデックスを書き込みます。
MSG_LIB_TEXT_BAR_TYPE_CANDLE_ZERO_BODY, // Candle with a zero body MSG_LIB_TEXT_BAR_TEXT_FIRS_SET_AMOUNT_DATA, // First, we need to set the required amount of data using SetRequiredUsedData() MSG_LIB_TEXT_BAR_RATIO_BODY_TO_CANDLE_SIZE, // Percentage ratio of the candle body to the full size of the candle MSG_LIB_TEXT_BAR_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE,// Percentage ratio of the upper shadow size to the candle size MSG_LIB_TEXT_BAR_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE,// Percentage ratio of the lower shadow size to the candle size //--- CTimeSeries
...
MSG_LIB_TEXT_TS_TEXT_ATTEMPT, // Attempt: MSG_LIB_TEXT_TS_TEXT_WAIT_FOR_SYNC, // Waiting for data synchronization ... //--- CPattern MSG_LIB_TEXT_PATTERN_CODE, // Code MSG_LIB_TEXT_PATTERN_TIME, // Defining bar time MSG_LIB_TEXT_PATTERN_ID, // Pattern ID MSG_LIB_TEXT_PATTERN_CTRL_OBJ_ID, // Pattern control object ID MSG_LIB_TEXT_PATTERN_CANDLES, // Number of candles that make up the pattern MSG_LIB_TEXT_PATTERN_DIRECTION, // Pattern direction MSG_LIB_TEXT_PATTERN_BAR_PRICE_OPEN, // Pattern defining bar Open price MSG_LIB_TEXT_PATTERN_BAR_PRICE_HIGH, // Pattern defining bar High price MSG_LIB_TEXT_PATTERN_BAR_PRICE_LOW, // Pattern defining bar Low price MSG_LIB_TEXT_PATTERN_BAR_PRICE_CLOSE, // Pattern defining bar Close price MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE, // Percentage ratio of the candle body to the full size of the candle MSG_LIB_TEXT_PATTERN_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the upper shadow size to the candle size MSG_LIB_TEXT_PATTERN_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE, // Percentage ratio of the lower shadow size to the candle size MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE_CRIT, // Defined criterion of the ratio of the candle body to the full candle size in % MSG_LIB_TEXT_PATTERN_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRIT, // Defined criterion of the ratio of the maximum shadow to the candle size in % MSG_LIB_TEXT_PATTERN_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRIT, // Defined criterion of the ratio of the minimum shadow to the candle size in % MSG_LIB_TEXT_PATTERN_NAME, // Name MSG_LIB_TEXT_PATTERN_STATUS_JC, // Candle pattern MSG_LIB_TEXT_PATTERN_STATUS_PA, // Price Action formation MSG_LIB_TEXT_PATTERN_BULLISH, // Bullish pattern MSG_LIB_TEXT_PATTERN_BEARISH, // Bearish pattern MSG_LIB_TEXT_PATTERN_BOTH, // Bidirectional pattern //--- Candles MSG_LIB_TEXT_PATTERN_TYPE_HARAMI, // Harami MSG_LIB_TEXT_PATTERN_TYPE_HARAMI_CROSS, // Harami Cross MSG_LIB_TEXT_PATTERN_TYPE_TWEEZER, // Tweezer MSG_LIB_TEXT_PATTERN_TYPE_PIERCING_LINE, // Piercing Line MSG_LIB_TEXT_PATTERN_TYPE_DARK_CLOUD_COVER, // Dark Cloud Cover MSG_LIB_TEXT_PATTERN_TYPE_THREE_WHITE_SOLDIERS, // Three White Soldiers MSG_LIB_TEXT_PATTERN_TYPE_THREE_BLACK_CROWS, // Three Black Crows MSG_LIB_TEXT_PATTERN_TYPE_SHOOTING_STAR, // Shooting Star MSG_LIB_TEXT_PATTERN_TYPE_HAMMER, // Hammer MSG_LIB_TEXT_PATTERN_TYPE_INVERTED_HAMMER, // Inverted Hammer MSG_LIB_TEXT_PATTERN_TYPE_HANGING_MAN, // Hanging Man MSG_LIB_TEXT_PATTERN_TYPE_DOJI, // Doji MSG_LIB_TEXT_PATTERN_TYPE_DRAGONFLY_DOJI, // Dragonfly Doji MSG_LIB_TEXT_PATTERN_TYPE_GRAVESTONE_DOJI, // Gravestone Doji MSG_LIB_TEXT_PATTERN_TYPE_MORNING_STAR, // Morning Star MSG_LIB_TEXT_PATTERN_TYPE_MORNING_DOJI_STAR, // Morning Doji Star MSG_LIB_TEXT_PATTERN_TYPE_EVENING_STAR, // Evening Star <100/100/72% > MSG_LIB_TEXT_PATTERN_TYPE_EVENING_DOJI_STAR, // Evening Doji Star MSG_LIB_TEXT_PATTERN_TYPE_THREE_STARS, // Three Stars MSG_LIB_TEXT_PATTERN_TYPE_ABANDONED_BABY, // Abandoned Baby //--- Price Action MSG_LIB_TEXT_PATTERN_TYPE_PIVOT_POINT_REVERSAL, // Pivot Point Reversal MSG_LIB_TEXT_PATTERN_TYPE_OUTSIDE_BAR, // Outside Bar MSG_LIB_TEXT_PATTERN_TYPE_INSIDE_BAR, // Inside Bar MSG_LIB_TEXT_PATTERN_TYPE_PIN_BAR, // Pin Bar MSG_LIB_TEXT_PATTERN_TYPE_RAILS, // Rails //--- CBuffer
新しく追加されたインデックスに対応するメッセージを書き込みます。
{"Свеча с нулевым телом","Candle with zero body"}, {"Сначала нужно установить требуемое количество данных при помощи SetRequiredUsedData()","First you need to set the required amount of data using SetRequiredUsedData()"}, {"Отношение тела свечи к полному размеру свечи","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"}, //--- CTimeSeries
...
{"Попытка: ","Attempt: "}, {"Ожидание синхронизации данных ...","Waiting for data synchronization ..."}, //--- CPattern {"Код","Code"}, {"Время определяющего бара","Time of the defining bar"}, {"Идентификатор паттерна","Pattern ID"}, {"Идентификатор объекта управления паттерном","Pattern Control object ID"}, {"Количество свечей, составляющих паттерн","Number of candles in the pattern"}, {"Направление паттерна","Pattern direction"}, {"Цена Open определяющего бара паттерна","Open price of the defining bar"}, {"Цена High определяющего бара паттерна","High price of the defining bar"}, {"Цена Low определяющего бара паттерна","Low price of the defining bar"}, {"Цена Close определяющего бара паттерна","Close price of the defining bar"}, {"Отношение тела свечи к полному размеру свечи в %","Ratio of candle body to full candle size in %"}, {"Отношение размера верхней тени к размеру свечи в %","Ratio of the size of the upper shadow to the size of the candle in %"}, {"Отношение размера нижней тени к размеру свечи в %","Ratio of the size of the lower shadow to the size of the candle in %"}, {"Установленный критерий отношения тела свечи к полному размеру свечи в %","Criterion for the Ratio of candle body to full candle size in %"}, {"Установленный критерий отношения размера наибольшей тени к размеру свечи в %","Criterion for the Ratio of the size of the larger shadow to the size of the candle in %"}, {"Установленный критерий отношения размера наименьшей тени к размеру свечи в %","Criterion for the Ratio of the size of the smaller shadow to the size of the candle in %"}, {"Наименование","Name"}, //--- Pattern status {"Свечной паттерн","Candlestick pattern"}, {"Формация Price Action","Price Action Formation"}, {"Бычий паттерн","Bullish pattern"}, {"Медвежий паттерн","Bearish pattern"}, {"Двунаправленный паттерн","Bidirectional pattern"}, //--- Свечные паттерны {"Харами","Harami"}, {"Крест харами","Harami Cross"}, {"Пинцет","Tweezer"}, {"Просвет в облаках","Piercing pattern"}, {"Завеса из темных облаков","Dark Cloud Cover"}, {"Три белых солдата","Three White Soldiers"}, {"Три черные вороны","Three Black Crows"}, {"Падающая звезда","Shooting Star"}, {"Молот","Hammer"}, {"Перевёрнутый молот","Inverted Hammer"}, {"Повешенный","Hanging Man"}, {"Доджи","Doji"}, {"Доджи стрекоза","Dragonfly doji"}, {"Доджи надгробие","Gravestone Doji"}, {"Утренняя звезда","Morning Star"}, {"Утренняя доджи-звезда","Morning Doji Star"}, {"Вечерняя звезда","Evening Star"}, {"Вечерняя доджи-звезда","Evening Doji Star"}, {"Три звезды","Three stars"}, {"Брошенное дитя","Abandoned baby"}, //--- Формации Price Action {"PPR разворотная точка","Pivot Point Reversal"}, {"Внешний бар","Outside Bar"}, {"Внутренний бар","Inside Bar"}, {"Пин бар","Pin Bar"}, {"Рельсы","Rails"}, //--- CBuffer
Barオブジェクトクラスファイル\MQL5\Include\DoEasy\Objects\Series\Bar.mqh, のprivateセクションに、ローソク足の比率を計算するメソッドと、ローソク足の比率を返すメソッドを記述します。
//+------------------------------------------------------------------+ //| Bar class | //+------------------------------------------------------------------+ class CBar : public CBaseObj { private: MqlDateTime m_dt_struct; // Date structure int m_digits; // Symbol's digits value string m_period_description; // Timeframe string description long m_long_prop[BAR_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[BAR_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[BAR_PROP_STRING_TOTAL]; // String properties //--- Return the index of the array the bar's (1) double and (2) string properties are located at int IndexProp(ENUM_BAR_PROP_DOUBLE property) const { return(int)property-BAR_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_BAR_PROP_STRING property) const { return(int)property-BAR_PROP_INTEGER_TOTAL-BAR_PROP_DOUBLE_TOTAL; } //--- Return the bar type (bullish/bearish/zero) ENUM_BAR_BODY_TYPE BodyType(void) const; //--- Calculate and return the size of (1) candle, (2) candle body, //--- (3) upper, (4) lower candle wick, //--- (5) candle body top and (6) bottom double CandleSize(void) const { return(this.High()-this.Low()); } double BodySize(void) const { return(this.BodyHigh()-this.BodyLow()); } double ShadowUpSize(void) const { return(this.High()-this.BodyHigh()); } double ShadowDownSize(void) const { return(this.BodyLow()-this.Low()); } double BodyHigh(void) const { return ::fmax(this.Close(),this.Open()); } double BodyLow(void) const { return ::fmin(this.Close(),this.Open()); } //--- Calculate and return the percentage ratio of the (1) candle body, (2) upper and (3) lower shadow size to the full candle size double CandleRatioBodyToCandleSize(void) const { return(this.CandleSize()>0 ? this.BodySize()*100.0/this.CandleSize() : 100.0); } double CandleRatioUpperShadowToCandleSize(void) const { return(this.CandleSize()>0 ? this.ShadowUpSize()*100.0/this.CandleSize() : 100.0); } double CandleRatioLowerShadowToCandleSize(void) const { return(this.CandleSize()>0 ? this.ShadowDownSize()*100.0/this.CandleSize(): 100.0); } //--- Return the (1) year and (2) month the bar belongs to, (3) week day, //--- (4) bar serial number in a year, (5) day, (6) hour, (7) minute, int TimeYear(void) const { return this.m_dt_struct.year; } int TimeMonth(void) const { return this.m_dt_struct.mon; } int TimeDayOfWeek(void) const { return this.m_dt_struct.day_of_week; } int TimeDayOfYear(void) const { return this.m_dt_struct.day_of_year; } int TimeDay(void) const { return this.m_dt_struct.day; } int TimeHour(void) const { return this.m_dt_struct.hour; } int TimeMinute(void) const { return this.m_dt_struct.min; } public:
publicセクション、すなわちバープロパティへの簡略化されたアクセスで、ローソク足比率のための新しいバープロパティを返すメソッドを記述します。
//+------------------------------------------------------------------+ //| Methods of simplified access to bar object properties | //+------------------------------------------------------------------+ //--- Return the (1) type, (2) period, (3) spread, (4) tick, (5) exchange volume, //--- (6) bar period start time, (7) year, (8) month the bar belongs to //--- (9) week number since the year start, (10) week number since the month start //--- (11) day, (12) hour, (13) minute ENUM_BAR_BODY_TYPE TypeBody(void) const { return (ENUM_BAR_BODY_TYPE)this.GetProperty(BAR_PROP_TYPE); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(BAR_PROP_PERIOD); } int Spread(void) const { return (int)this.GetProperty(BAR_PROP_SPREAD); } long VolumeTick(void) const { return this.GetProperty(BAR_PROP_VOLUME_TICK); } long VolumeReal(void) const { return this.GetProperty(BAR_PROP_VOLUME_REAL); } datetime Time(void) const { return (datetime)this.GetProperty(BAR_PROP_TIME); } long Year(void) const { return this.GetProperty(BAR_PROP_TIME_YEAR); } long Month(void) const { return this.GetProperty(BAR_PROP_TIME_MONTH); } long DayOfWeek(void) const { return this.GetProperty(BAR_PROP_TIME_DAY_OF_WEEK); } long DayOfYear(void) const { return this.GetProperty(BAR_PROP_TIME_DAY_OF_YEAR); } long Day(void) const { return this.GetProperty(BAR_PROP_TIME_DAY); } long Hour(void) const { return this.GetProperty(BAR_PROP_TIME_HOUR); } long Minute(void) const { return this.GetProperty(BAR_PROP_TIME_MINUTE); } //--- Return bar's (1) Open, (2) High, (3) Low, (4) Close price, //--- size of the (5) candle, (6) body, (7) candle top, (8) bottom, //--- size of the (9) candle upper, (10) lower wick double Open(void) const { return this.GetProperty(BAR_PROP_OPEN); } double High(void) const { return this.GetProperty(BAR_PROP_HIGH); } double Low(void) const { return this.GetProperty(BAR_PROP_LOW); } double Close(void) const { return this.GetProperty(BAR_PROP_CLOSE); } double Size(void) const { return this.GetProperty(BAR_PROP_CANDLE_SIZE); } double SizeBody(void) const { return this.GetProperty(BAR_PROP_CANDLE_SIZE_BODY); } double TopBody(void) const { return this.GetProperty(BAR_PROP_CANDLE_BODY_TOP); } double BottomBody(void) const { return this.GetProperty(BAR_PROP_CANDLE_BODY_BOTTOM); } double SizeShadowUp(void) const { return this.GetProperty(BAR_PROP_CANDLE_SIZE_SHADOW_UP); } double SizeShadowDown(void) const { return this.GetProperty(BAR_PROP_CANDLE_SIZE_SHADOW_DOWN); } //--- Return the properties of the percentage ratio of the (1) candle body, (2) upper and (3) lower shadow size to the candle full size double RatioBodyToCandleSize(void) const { return this.GetProperty(BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE); } double RatioUpperShadowToCandleSize(void) const { return this.GetProperty(BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE);} double RatioLowerShadowToCandleSize(void) const { return this.GetProperty(BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE);} //--- Return bar symbol string Symbol(void) const { return this.GetProperty(BAR_PROP_SYMBOL); } //--- Return bar index on the specified timeframe the bar time falls into int Index(const ENUM_TIMEFRAMES timeframe) const { return ::iBarShift(this.Symbol(),(timeframe==PERIOD_CURRENT ? ::Period() : timeframe),this.Time()); }
バーオブジェクトのパラメータを設定するメソッドで、バーオブジェクトのプロパティに、計算されたローソク足の比率を書き加えます。
//+------------------------------------------------------------------+ //| 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_TYPE,this.BodyType()); //--- Set the object type to the object of the graphical object management class this.m_graph_elm.SetTypeNode(this.m_type); }
バーのrealプロパティの説明を返すメソッドで、新しいバープロパティの説明を返すようにします。
//+------------------------------------------------------------------+ //| Return the description of the bar's real property | //+------------------------------------------------------------------+ string CBar::GetPropertyDescription(ENUM_BAR_PROP_DOUBLE property) { int dg=(this.m_digits>0 ? this.m_digits : 1); return ( property==BAR_PROP_OPEN ? CMessage::Text(MSG_ORD_PRICE_OPEN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_HIGH ? CMessage::Text(MSG_LIB_TEXT_BAR_HIGH)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_LOW ? CMessage::Text(MSG_LIB_TEXT_BAR_LOW)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CLOSE ? CMessage::Text(MSG_ORD_PRICE_CLOSE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_SIZE_BODY ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_SIZE_BODY)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_SIZE_SHADOW_UP ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_SIZE_SHADOW_UP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_SIZE_SHADOW_DOWN ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_SIZE_SHADOW_DOWN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_BODY_TOP ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_BODY_TOP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_CANDLE_BODY_BOTTOM ? CMessage::Text(MSG_LIB_TEXT_BAR_CANDLE_BODY_BOTTOM)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==BAR_PROP_RATIO_BODY_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_BAR_RATIO_BODY_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2)+"%" ) : property==BAR_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_BAR_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2)+"%" ) : property==BAR_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_BAR_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2)+"%" ) : "" ); }
クラスの改善はこれで終わりです。次に基本パターンオブジェクトを作り始めることができます。
抽象パターンクラス
\MQL5\Include\DoEasy\Objects\Series\Patterns\に、新しいPattern.mqhファイルを作成します。このクラスは、基礎となるライブラリオブジェクトから継承される必要があり、そのライブラリのファイルは、作成されたクラスのファイルに接続される必要があります。
//+------------------------------------------------------------------+ //| Pattern.mqh | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\..\BaseObj.mqh" //+------------------------------------------------------------------+ //| Abstract pattern class | //+------------------------------------------------------------------+ class CPattern : public CBaseObj { }
privateセクションで、ライブラリオブジェクトのプロパティの標準的な配列と、対応する配列内のプロパティの実際のインデックスを返すメソッドを宣言します。
class CPattern : public CBaseObj { private: 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:
クラスのprotectedセクションには、その操作に必要なクラスメンバー変数が宣言されます。
protected: CForm *m_form; // Pointer to form 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 public:
パターンが形成されているチャートバー上にマウスを置くと表示される情報パネルを作成するには、フォームオブジェクトが必要です。銘柄のデジタルコードは、銘柄の名前をパターンIDに付加される番号に変換するために必要です。パターンIDは、バーの開始時間 + パターンタイプ + ステータス + パターンの方向 + 時間枠 + 時系列銘柄から構成される一意の番号です。このコードを使用して、まさにそのようなパターンがすでにパターンのリストにあることを判断します。
クラスのpublicセクションには、標準的なライブラリメソッドが宣言されています。
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;} //--- 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); } //+------------------------------------------------------------------+ //| 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: //--- Remove a graphical object bool DeleteGraphObj(bool redraw=false); //--- 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 info panel object bool CreateInfoPanel(void); //--- Create the info panel appearance virtual void CreateInfoPanelView(void){} public: //--- 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 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 a pattern icon on the chart void Draw(const bool redraw=false); //--- (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); void HideInfoPanel(void); };
宣言されたメソッドの実装について考えてみましょう。
クラスのコンストラクタで、パターンオブジェクトのプロパティとグラフィカルオブジェクトのパラメータ(チャート上のパターンラベルと情報パネル)を設定します。
//+------------------------------------------------------------------+ //| 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=clrGreen; 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; } //--- 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; }
クラスのデストラクタで、作成したグラフィカルオブジェクトを削除します。
//+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CPattern::~CPattern(void) { //--- Delete the form object and pattern label on the chart if(this.m_form!=NULL) delete this.m_form; this.DeleteGraphObj(); }
以下は、指定されたプロパティによってCPatternオブジェクトを比較するメソッドです。
//+--------------------------------------------------------------------+ //| Compare CPattern objects with each other by the specified property | //+--------------------------------------------------------------------+ int CPattern::Compare(const CObject *node,const int mode=0) const { const CPattern *obj_compared=node; //--- compare integer properties of two patterns if(mode<PATTERN_PROP_INTEGER_TOTAL) { long value_compared=obj_compared.GetProperty((ENUM_PATTERN_PROP_INTEGER)mode); long value_current=this.GetProperty((ENUM_PATTERN_PROP_INTEGER)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } //--- compare real properties of two patterns else if(mode<PATTERN_PROP_DOUBLE_TOTAL+PATTERN_PROP_INTEGER_TOTAL) { double value_compared=obj_compared.GetProperty((ENUM_PATTERN_PROP_DOUBLE)mode); double value_current=this.GetProperty((ENUM_PATTERN_PROP_DOUBLE)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } //--- compare string properties of two patterns else if(mode<PATTERN_PROP_DOUBLE_TOTAL+PATTERN_PROP_INTEGER_TOTAL+PATTERN_PROP_STRING_TOTAL) { string value_compared=obj_compared.GetProperty((ENUM_PATTERN_PROP_STRING)mode); string value_current=this.GetProperty((ENUM_PATTERN_PROP_STRING)mode); return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0); } return 0; }
これは、2つのオブジェクトのプロパティを比較するための標準的なライブラリメソッドです。
以下は、CPatternオブジェクトをすべてのプロパティで比較するメソッドです。
//+------------------------------------------------------------------+ //| Compare CPattern objects with each other by all properties | //+------------------------------------------------------------------+ bool CPattern::IsEqual(CPattern *compared_obj) const { int begin=0, end=PATTERN_PROP_INTEGER_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_INTEGER prop=(ENUM_PATTERN_PROP_INTEGER)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } begin=end; end+=PATTERN_PROP_DOUBLE_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_DOUBLE prop=(ENUM_PATTERN_PROP_DOUBLE)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } begin=end; end+=PATTERN_PROP_STRING_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_STRING prop=(ENUM_PATTERN_PROP_STRING)i; if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return false; } return true; }
これも標準的なライブラリのメソッドです。比較される2つのオブジェクトのすべてのプロパティが等しい場合にのみtrueを返します。
以下は、パターンプロパティの説明を操作ログに送信するためのメソッドです。
//+------------------------------------------------------------------+ //| Send pattern properties to the journal | //+------------------------------------------------------------------+ void CPattern::Print(const bool full_prop=false,const bool dash=false) { ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") ============="); int begin=0, end=PATTERN_PROP_INTEGER_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_INTEGER prop=(ENUM_PATTERN_PROP_INTEGER)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); begin=end; end+=PATTERN_PROP_DOUBLE_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_DOUBLE prop=(ENUM_PATTERN_PROP_DOUBLE)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("------"); begin=end; end+=PATTERN_PROP_STRING_TOTAL; for(int i=begin; i<end; i++) { ENUM_PATTERN_PROP_STRING prop=(ENUM_PATTERN_PROP_STRING)i; if(!full_prop && !this.SupportProperty(prop)) continue; ::Print(this.GetPropertyDescription(prop)); } ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n"); } //+------------------------------------------------------------------+ //| Display the short pattern description in the journal | //+------------------------------------------------------------------+ void CPattern::PrintShort(const bool dash=false,const bool symbol=false) { ::Print(this.Header(),":\n",(dash ? " - " : ""),this.Symbol(),", ",TimeframeDescription(this.Timeframe())," ",::TimeToString(this.Time()),", ",this.DirectDescription()); } //+------------------------------------------------------------------+ //| Return a short name of a pattern object | //+------------------------------------------------------------------+ string CPattern::Header(void) { return(this.StatusDescription()+" "+this.TypeDescription()); } //+------------------------------------------------------------------+ //| 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|TIME_SECONDS) ) : 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) ) : "" ); } //+------------------------------------------------------------------+ //| Return the description of the pattern real property | //+------------------------------------------------------------------+ string CPattern::GetPropertyDescription(ENUM_PATTERN_PROP_DOUBLE property) { int dg=(this.m_digits>0 ? this.m_digits : 1); return ( property==PATTERN_PROP_BAR_PRICE_OPEN ? CMessage::Text(MSG_LIB_TEXT_PATTERN_BAR_PRICE_OPEN)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==PATTERN_PROP_BAR_PRICE_HIGH ? CMessage::Text(MSG_LIB_TEXT_PATTERN_BAR_PRICE_HIGH)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==PATTERN_PROP_BAR_PRICE_LOW ? CMessage::Text(MSG_LIB_TEXT_PATTERN_BAR_PRICE_LOW)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==PATTERN_PROP_BAR_PRICE_CLOSE ? CMessage::Text(MSG_LIB_TEXT_PATTERN_BAR_PRICE_CLOSE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),dg) ) : property==PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE_CRITERION ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_BODY_TO_CANDLE_SIZE_CRIT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==PATTERN_PROP_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRITERION ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_LARGER_SHADOW_TO_CANDLE_SIZE_CRIT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : property==PATTERN_PROP_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRITERION ? CMessage::Text(MSG_LIB_TEXT_PATTERN_RATIO_SMALLER_SHADOW_TO_CANDLE_SIZE_CRIT)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::DoubleToString(this.GetProperty(property),2) ) : "" ); } //+------------------------------------------------------------------+ //| Return the description of the pattern string property | //+------------------------------------------------------------------+ string CPattern::GetPropertyDescription(ENUM_PATTERN_PROP_STRING property) { return ( property==PATTERN_PROP_SYMBOL ? CMessage::Text(MSG_LIB_PROP_SYMBOL)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetProperty(property) ) : property==PATTERN_PROP_NAME ? CMessage::Text(MSG_LIB_TEXT_PATTERN_NAME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+ //| Return the pattern direction description | //+------------------------------------------------------------------+ string CPattern::DirectDescription(void) const { switch(this.Direction()) { case PATTERN_DIRECTION_BULLISH : return CMessage::Text(MSG_LIB_TEXT_PATTERN_BULLISH); case PATTERN_DIRECTION_BEARISH : return CMessage::Text(MSG_LIB_TEXT_PATTERN_BEARISH); case PATTERN_DIRECTION_BOTH : return CMessage::Text(MSG_LIB_TEXT_PATTERN_BOTH); default : return "Unknown"; } }
同様のメソッドについては、ライブラリに関する以前の記事で何度も説明しているので、ここでは繰り返しません。
以下は、グラフィカルオブジェクトを扱うメソッドです。
//+------------------------------------------------------------------+ //| Delete a graphical label object of a chart pattern | //+------------------------------------------------------------------+ bool CPattern::DeleteGraphObj(bool redraw=false) { if(::ObjectFind(this.m_chart_id,this.m_name_graph_obj)<0) return true; if(::ObjectDelete(this.m_chart_id,this.m_name_graph_obj)) { if(redraw) ::ChartRedraw(this.m_chart_id); return true; } return false; } //+------------------------------------------------------------------+ //| Create the info panel | //+------------------------------------------------------------------+ bool CPattern::CreateInfoPanel(void) { int x=0, y=0; //--- If the panel object has already been created earlier, return 'true' if(this.m_form!=NULL) return true; //--- Determine the price of the upper left corner between the candle High and Low double price=(this.BarPriceHigh()+this.BarPriceLow())/2; //--- Obtain the panel X and Y coordinates using the bar time and calculated price if(!::ChartTimePriceToXY(this.m_chart_id,0,this.Time(),price,x,y)) return false; //--- Create the panel object this.m_form=this.CreateForm(this.ID(),this.Name(),x,y,4,4); if(this.m_form==NULL) return false; //--- Draw the panel appearance this.CreateInfoPanelView(); return true; } //+------------------------------------------------------------------+ //| Display the info panel on the chart | //+------------------------------------------------------------------+ void CPattern::ShowInfoPanel(const int x,const int y) { //--- 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(); } //+------------------------------------------------------------------+ //| Hide the info panel on the chart | //+------------------------------------------------------------------+ void CPattern::HideInfoPanel(void) { if(this.m_form!=NULL) this.m_form.Hide(); } //+------------------------------------------------------------------+ //| Draw the pattern icon on the chart | //+------------------------------------------------------------------+ void CPattern::Draw(const bool redraw=false) { //--- If the graphical object has not yet been created, create it if(::ObjectFind(this.m_chart_id,this.m_name_graph_obj)<0) { if(!this.CreateTrendLine(this.m_chart_id,this.m_name_graph_obj,0,this.Time(),this.m_price,this.Time(),this.m_price,this.m_color,5)) return; } //--- Otherwise - display else this.Show(redraw); } //+------------------------------------------------------------------+ //| Display the pattern icon on the chart | //+------------------------------------------------------------------+ void CPattern::Show(const bool redraw=false) { ::ObjectSetInteger(this.m_chart_id,this.m_name_graph_obj,OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS); if(redraw) ::ChartRedraw(this.m_chart_id); } //+------------------------------------------------------------------+ //| Hide the pattern icon on the chart | //+------------------------------------------------------------------+ void CPattern::Hide(const bool redraw=false) { ::ObjectSetInteger(this.m_chart_id,this.m_name_graph_obj,OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS); if(redraw) ::ChartRedraw(this.m_chart_id); } //+------------------------------------------------------------------+ //| Set graphical object and | //| and pattern display colors | //+------------------------------------------------------------------+ void CPattern::SetColors(const color color_bullish,const color color_bearish,const color color_bidirect,const bool redraw=false) { this.SetColorBullish(color_bullish); this.SetColorBearish(color_bearish); this.SetColorBiDirect(color_bidirect); this.m_color=(this.Direction()==PATTERN_DIRECTION_BULLISH ? this.m_color_bullish : this.Direction()==PATTERN_DIRECTION_BEARISH ? this.m_color_bearish : this.m_color_bidirect); ::ObjectSetInteger(this.m_chart_id,this.m_name_graph_obj,OBJPROP_COLOR,this.m_color); if(redraw) ::ChartRedraw(this.m_chart_id); }
このメソッドはいたってシンプルで、コメントもついています。それぞれのメソッドを逆アセンブルすることはあまり意味がありません。コードを読むだけで十分です。
基本的な抽象パターンオブジェクトができました。ライブラリで計画されているすべてのパターンをこれに基づいて作成する予定です。正確なパラメータと使用/未使用のプロパティはパターンで設定します。
まずは、シンプルでありながら便利なプライスアクションのピンバーパターンから始めましょう。
ピンバーパターン
このクラスは非常にシンプルになります。基本パターンオブジェクトから継承された各クラスについて、このパターンに固有のプロパティをいくつか示し、どのプロパティが子孫クラスでサポートされ、どのプロパティがサポートされないかを示すだけです。
ピンバーパターンクラスを見てみましょう。基本パターンクラスと同じファイルに書き続けます。
//+------------------------------------------------------------------+ //| Pin Bar pattern class | //+------------------------------------------------------------------+ class CPatternPinBar : public CPattern { protected: //--- Create the info panel appearance virtual void CreateInfoPanelView(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_PIN_BAR); } //--- Constructor CPatternPinBar(const uint id,const string symbol,const ENUM_TIMEFRAMES timeframe,MqlRates &rates,const ENUM_PATTERN_DIRECTION direct); };
パターンのステータスとタイプの説明を返すメソッドは、それぞれ「Price Action Formation 」と「Pin Bar」の文字列を返します。プロパティの使用フラグを返すメソッドは、ここではすべてのプロパティに対してtrueを返します。新しいパターンやパターン用の新しいバープロパティを追加する場合、ピンバーパターンに関連しないプロパティは禁止します。
クラスコンストラクタの初期化文字列で、「Price Action」パターンステータス、「Pin Bar」パターンタイプ、およびコンストラクタの入力で渡された残りのパラメータを親クラスに渡します。
//+------------------------------------------------------------------+ //| 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); }
コンストラクタ本体で、「ピンバー」パターンの名前と、パターンを構成するローソクの本数を1に設定します。
情報パネルの外観を作成する仮想メソッドはパターンごとに異なり、パターンに固有のプロパティを表示します。ピンバーパターンの場合、やり方は次のようになります。
//+------------------------------------------------------------------+ //| Create the info panel appearance | //+------------------------------------------------------------------+ void CPatternPinBar::CreateInfoPanelView(void) { //--- If the form object is not created, leave if(this.m_form==NULL) return; //--- Change the color tone for bullish and bearish patterns: the bullish ones will have a blue tint, while the bearish ones will have a red tint color color_bullish=this.m_form.ChangeRGBComponents(this.m_form.ChangeColorLightness(this.m_color_panel_bullish,5),0,0,30); color color_bearish=this.m_form.ChangeRGBComponents(this.m_form.ChangeColorLightness(this.m_color_panel_bearish,5),30,0,0); color color_bidirect=this.m_color_bidirect; //--- Declare the array for the initial and final colors of the gradient fill color clr[2]={}; //--- Depending on the direction of the pattern, change the lightness of the corresponding colors - the initial one is a little darker, the final one is a little lighter switch(this.Direction()) { case PATTERN_DIRECTION_BULLISH : clr[0]=this.m_form.ChangeColorLightness(color_bullish,-2.5); clr[1]=this.m_form.ChangeColorLightness(color_bullish,2.5); break; case PATTERN_DIRECTION_BEARISH : clr[0]=this.m_form.ChangeColorLightness(color_bearish,-2.5); clr[1]=this.m_form.ChangeColorLightness(color_bearish,2.5); break; default: clr[0]=this.m_form.ChangeColorLightness(color_bidirect,-2.5); clr[1]=this.m_form.ChangeColorLightness(color_bidirect,2.5); break; } //--- Set the background and form frame colors this.m_form.SetBackgroundColor(this.Direction()==PATTERN_DIRECTION_BULLISH ? color_bullish : this.Direction()==PATTERN_DIRECTION_BEARISH ? color_bearish : this.m_color_bidirect,true); this.m_form.SetBorderColor(clrGray,true); //--- Create strings to describe the pattern, its parameters and search criteria string name=::StringFormat("Pin Bar (%.2f/%.2f/%.2f)",this.GetProperty(PATTERN_PROP_RATIO_BODY_TO_CANDLE_SIZE),this.GetProperty(PATTERN_PROP_RATIO_UPPER_SHADOW_TO_CANDLE_SIZE),this.GetProperty(PATTERN_PROP_RATIO_LOWER_SHADOW_TO_CANDLE_SIZE)); string param=::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); }
メソッドのロジックはコードのコメントで完全に説明されています。ヘッダーに、パターンの名前と、パターンが見つかったローソクの比率を表示します。ヘッダーの下には、パターンの方向、検索条件、パターンを定義しているバーの日時が表示されます。
ローソク足の比率はヘッダーで指定されます。
- 16.22:ローソク全体の大きさに対するローソク実体の大きさの比率
- 18.92:ローソク足全体のサイズに対する上髭の比率
- 64.86:ローソク足全体のサイズに対する下髭の比率
ヘッダーはパターンの方向と検索条件を示します。
- 30.00:実体がローソク足全体の30%を超えてはならない
- 60.00:一番長い髭は、ローソク全体の大きさの少なくとも60%でなければならない
- 30.00:一番短い髭は、ローソク全体の大きさの30%以下でなければならない
異なるパターンでは、検索条件が異なるため、情報パネルに表示されるデータも異なります。パネルの外観を描画するのは仮想メソッドです。
パターンクラスはひとまず終了です。あとはそれらをライブラリに統合する必要があります。
パターンを分類するためには、このようなツールキットが必要です。必要なものをすべて、゙\MQL5\Include\DoEasy\Services\Select.mqhライブラリファイルのCSelectクラスに追加します。
まず、CSelectクラスファイルにパターンクラスファイルをインクルードします。
//+------------------------------------------------------------------+ //| Select.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ja/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include <Arrays\ArrayObj.mqh> #include "..\Objects\Orders\Order.mqh" #include "..\Objects\Events\Event.mqh" #include "..\Objects\Accounts\Account.mqh" #include "..\Objects\Symbols\Symbol.mqh" #include "..\Objects\PendRequest\PendRequest.mqh" #include "..\Objects\Series\\Patterns\Pattern.mqh" #include "..\Objects\Series\SeriesDE.mqh" #include "..\Objects\Indicators\Buffer.mqh" #include "..\Objects\Indicators\IndicatorDE.mqh" #include "..\Objects\Indicators\DataInd.mqh" #include "..\Objects\Ticks\DataTick.mqh" #include "..\Objects\Book\MarketBookOrd.mqh" #include "..\Objects\MQLSignalBase\MQLSignal.mqh" #include "..\Objects\Chart\ChartObj.mqh" #include "..\Objects\Graph\GCnvElement.mqh" #include "..\Objects\Graph\Standard\GStdGraphObj.mqh"
時系列バーを扱うメソッドを宣言した直後に、パターンを扱うメソッドを宣言します。
//+------------------------------------------------------------------+ //| Methods of working with timeseries bars | //+------------------------------------------------------------------+ //--- Return the list of bars with one out of (1) integer, (2) real and (3) string properties meeting a specified criterion static CArrayObj *ByBarProperty(CArrayObj *list_source,ENUM_BAR_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode); static CArrayObj *ByBarProperty(CArrayObj *list_source,ENUM_BAR_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode); static CArrayObj *ByBarProperty(CArrayObj *list_source,ENUM_BAR_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode); //--- Return the bar index in the list with the maximum value of the bar's (1) integer, (2) real and (3) string properties static int FindBarMax(CArrayObj *list_source,ENUM_BAR_PROP_INTEGER property); static int FindBarMax(CArrayObj *list_source,ENUM_BAR_PROP_DOUBLE property); static int FindBarMax(CArrayObj *list_source,ENUM_BAR_PROP_STRING property); //--- Return the bar index in the list with the minimum value of the bar's (1) integer, (2) real and (3) string properties static int FindBarMin(CArrayObj *list_source,ENUM_BAR_PROP_INTEGER property); static int FindBarMin(CArrayObj *list_source,ENUM_BAR_PROP_DOUBLE property); static int FindBarMin(CArrayObj *list_source,ENUM_BAR_PROP_STRING property); //+------------------------------------------------------------------+ //| Methods for working with timeseries patterns | //+------------------------------------------------------------------+ //--- Return the list of patterns with one out of (1) integer, (2) real and (3) string properties meeting a specified criterion static CArrayObj *ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode); static CArrayObj *ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode); static CArrayObj *ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode); //--- Return the pattern index in the list with the maximum value of the pattern (1) integer, (2) real and (3) string properties static int FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_INTEGER property); static int FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_DOUBLE property); static int FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_STRING property); //--- Return the pattern index in the list with the minimum value of the pattern (1) integer, (2) real and (3) string properties static int FindPatternMin(CArrayObj *list_source,ENUM_PATTERN_PROP_INTEGER property); static int FindPatternMin(CArrayObj *list_source,ENUM_PATTERN_PROP_DOUBLE property); static int FindPatternMin(CArrayObj *list_source,ENUM_PATTERN_PROP_STRING property); //+------------------------------------------------------------------+ //| Methods of working with indicator buffers | //+------------------------------------------------------------------+
クラス本体の外側で実装しましょう。
//+------------------------------------------------------------------+ //| Methods for working with lists of timeseries patterns | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Return the list of patterns with one integer | //| property meeting the specified criterion | //+------------------------------------------------------------------+ CArrayObj *CSelect::ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode) { if(list_source==NULL) return NULL; CArrayObj *list=new CArrayObj(); if(list==NULL) return NULL; list.FreeMode(false); ListStorage.Add(list); int total=list_source.Total(); for(int i=0; i<total; i++) { CPattern *obj=list_source.At(i); if(!obj.SupportProperty(property)) continue; long obj_prop=obj.GetProperty(property); if(CompareValues(obj_prop,value,mode)) list.Add(obj); } return list; } //+------------------------------------------------------------------+ //| Return the list of patterns with one real | //| property meeting the specified criterion | //+------------------------------------------------------------------+ CArrayObj *CSelect::ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode) { if(list_source==NULL) return NULL; CArrayObj *list=new CArrayObj(); if(list==NULL) return NULL; list.FreeMode(false); ListStorage.Add(list); for(int i=0; i<list_source.Total(); i++) { CPattern *obj=list_source.At(i); if(!obj.SupportProperty(property)) continue; double obj_prop=obj.GetProperty(property); if(CompareValues(obj_prop,value,mode)) list.Add(obj); } return list; } //+------------------------------------------------------------------+ //| Return the list of patterns with one string | //| property meeting the specified criterion | //+------------------------------------------------------------------+ CArrayObj *CSelect::ByPatternProperty(CArrayObj *list_source,ENUM_PATTERN_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode) { if(list_source==NULL) return NULL; CArrayObj *list=new CArrayObj(); if(list==NULL) return NULL; list.FreeMode(false); ListStorage.Add(list); for(int i=0; i<list_source.Total(); i++) { CPattern *obj=list_source.At(i); if(!obj.SupportProperty(property)) continue; string obj_prop=obj.GetProperty(property); if(CompareValues(obj_prop,value,mode)) list.Add(obj); } return list; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the maximum integer property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_INTEGER property) { if(list_source==NULL) return WRONG_VALUE; int index=0; CPattern *max_obj=NULL; int total=list_source.Total(); if(total==0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); long obj1_prop=obj.GetProperty(property); max_obj=list_source.At(index); long obj2_prop=max_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,MORE)) index=i; } return index; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the maximum real property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_DOUBLE property) { if(list_source==NULL) return WRONG_VALUE; int index=0; CPattern *max_obj=NULL; int total=list_source.Total(); if(total==0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); double obj1_prop=obj.GetProperty(property); max_obj=list_source.At(index); double obj2_prop=max_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,MORE)) index=i; } return index; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the maximum string property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMax(CArrayObj *list_source,ENUM_PATTERN_PROP_STRING property) { if(list_source==NULL) return WRONG_VALUE; int index=0; CPattern *max_obj=NULL; int total=list_source.Total(); if(total==0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); string obj1_prop=obj.GetProperty(property); max_obj=list_source.At(index); string obj2_prop=max_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,MORE)) index=i; } return index; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the minimum integer property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMin(CArrayObj* list_source,ENUM_PATTERN_PROP_INTEGER property) { int index=0; CPattern *min_obj=NULL; int total=list_source.Total(); if(total==0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); long obj1_prop=obj.GetProperty(property); min_obj=list_source.At(index); long obj2_prop=min_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,LESS)) index=i; } return index; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the minimum real property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMin(CArrayObj* list_source,ENUM_PATTERN_PROP_DOUBLE property) { int index=0; CPattern *min_obj=NULL; int total=list_source.Total(); if(total== 0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); double obj1_prop=obj.GetProperty(property); min_obj=list_source.At(index); double obj2_prop=min_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,LESS)) index=i; } return index; } //+------------------------------------------------------------------+ //| Return the pattern index in the list | //| with the minimum string property value | //+------------------------------------------------------------------+ int CSelect::FindPatternMin(CArrayObj* list_source,ENUM_PATTERN_PROP_STRING property) { int index=0; CPattern *min_obj=NULL; int total=list_source.Total(); if(total==0) return WRONG_VALUE; for(int i=1; i<total; i++) { CPattern *obj=list_source.At(i); string obj1_prop=obj.GetProperty(property); min_obj=list_source.At(index); string obj2_prop=min_obj.GetProperty(property); if(CompareValues(obj1_prop,obj2_prop,LESS)) index=i; } return index; }
CSelectクラスについては、ライブラリを説明する第3回の記事で検討しました。オブジェクトのプロパティによる検索や分類が必要なすべてのオブジェクトのリストについては、論理的に同一のメソッドがCSelectクラスに実装されています。パターンオブジェクトの場合、すべてがまったく同じです。したがって、クラスの説明を読めば、上記のメソッドはすべて理解できます。
先に説明したクラスを区別する唯一のものは、2つのオブジェクトの値を比較するCompareValues()メソッドです。以前は以下のようでした。
//+------------------------------------------------------------------+ //| Method for comparing two values | //+------------------------------------------------------------------+ template<typename T> bool CSelect::CompareValues(T value1,T value2,ENUM_COMPARER_TYPE mode) { return ( mode==EQUAL && value1==value2 ? true : mode==NO_EQUAL && value1!=value2 ? true : mode==MORE && value1>value2 ? true : mode==LESS && value1<value2 ? true : mode==EQUAL_OR_MORE && value1>=value2 ? true : mode==EQUAL_OR_LESS && value1<=value2 ? true : false ); }
現在、古いメソッドで使用されていたif-else構文はswitchに置き換えられています。
//+------------------------------------------------------------------+ //| Method for comparing two values | //+------------------------------------------------------------------+ template<typename T> bool CSelect::CompareValues(T value1,T value2,ENUM_COMPARER_TYPE mode) { switch(mode) { case EQUAL : return(value1==value2 ? true : false); case NO_EQUAL : return(value1!=value2 ? true : false); case MORE : return(value1>value2 ? true : false); case LESS : return(value1<value2 ? true : false); case EQUAL_OR_MORE : return(value1>=value2 ? true : false); case EQUAL_OR_LESS : return(value1<=value2 ? true : false); default : return false; } }
この形であれば、比較はより速く機能するはずです。
パターン制御クラス
パターンごとに、また異なるパラメータを持つ同一のパターンに対しても、パターン制御クラスを作成します。このクラスでは、パターンを検索するために指定されたプロパティを格納し、その検索を時系列に並べ、検索されたパターンへのポインタを返します。各パターンは、銘柄名、時間枠、パターンタイプ、パターン方向、パラメータの合計からなる固有のIDを持ちます。従って、同じ銘柄、同じチャート期間で、パラメータが異なる2つの同じパターンであっても、独立した異なるパターンとなります。その上、それらはすべてのパターンのリストに存在することになります。
ライブラリ内の既存のファイル順序に従って、新しいタイプのクラスはそれぞれ独自のファイルを持つ。これにより、ライブラリの構造が合理化され、各ファイルのサイズが小さくなります。しかし、この場合、パターン制御クラスは、゙\MQL5\Include\DoEasy\Objects\Series\SeriesDE.mqh時系列クラスファイルに配置する必要がありました。これはすべて、ライブラリに異なるクラスの相互接続が多すぎるためです。そのため、時系列クラスとパターン制御クラスを別のファイルに分割し、パターン制御クラスのファイルを時系列ファイルに接続すると、コンパイラがある場所では時系列ファイルにアクセスできず、別の場所ではパターン制御クラスのファイルにアクセスできないため、一部のファイルはコンパイルが止まってしまいます。今のところ、いくらやってもすべてを正しく接続できていません。結局、パターン制御クラスは、パターン制御クラスが配置される時系列のクラスファイルに直接書くことにしました。
プロパティとパラメータのセットを持つパターンごとに、独自の制御クラスが作成されます。検索のために作成されるパターンの数と、必要な同じタイプのパターンの異なるバリエーションの数は、パターン制御オブジェクトの数に等しいです。次に、これらの作成されたオブジェクトは、作成されたすべてのパターン制御オブジェクトの制御クラスのリストに配置されます。そこから管理オブジェクトへのアクセスが提供されます。そこから今度は、パターンに直接アクセスできるようになります。
\MQL5\Include\DoEasy\Objects\Series\SeriesDE.mqh時系列クラスファイルを開きます。抽象パターンを管理するための新しいクラスを開発しましょう。
//+------------------------------------------------------------------+ //| SeriesDE.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ja/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ja/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\..\Services\Select.mqh" #include "..\..\Services\NewBarObj.mqh" #include "Bar.mqh" //+------------------------------------------------------------------+ //| 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 //--- 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 //--- (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) 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; } public: //--- Return itself 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; } //--- 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; } //--- 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(void); //--- 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); };
すべての変数とメソッドは符号付きです。その目的は、説明から明らかなはずです。
このクラスは単独では使用されないので、protected parametricコンストラクタしか持っていません。そこから継承されたクラスはpublicコンストラクタを持ち、対応するパラメータは、制御オブジェクトが作成されるパターンの型に従って、親クラスのプロテクトコンストラクタに渡されます。
protectedパラメトリックコンストラクタは、作成されたパターンのパラメータと、外部リストへのポインタ(時系列リストとすべてのパターンのリスト)を受け取ります。初期化リストでは、デフォルトのパターン検索条件と、パターンを使用するためのフラグ、およびパターンラベルを描画するためのフラグを指定することができます。渡されたパラメータはすべて調整されてコンストラクタ本体で設定され、メソッドに渡されたポインタがクラスリストのポインタに代入され、銘柄コードが作成されます。
//+------------------------------------------------------------------+ //| 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); }
コンストラクタに渡されるリストへのポインタは、このクラスが外部から作成されたどの外部リストを扱うかを示すために必要です。外部リストへのポインタをクラスリストへのポインタに割り当てることで、このクラスが、CArrayObjクラスの他のインスタンスではなく、外部で作成されたリストで正確に動作するようにします。
以下は、CPatternControl オブジェクト同士を比較するメソッドです。
//+------------------------------------------------------------------+ //| Compare CPatternControl objects | //+------------------------------------------------------------------+ int CPatternControl::Compare(const CObject *node,const int mode=0) const { const CPatternControl *obj_compared=node; return ( this.SymbolCode() > obj_compared.SymbolCode() || this.Timeframe() > obj_compared.Timeframe() || this.TypePattern() > obj_compared.TypePattern() || this.ObjectID() > obj_compared.ObjectID() ? 1 : this.SymbolCode() < obj_compared.SymbolCode() || this.Timeframe() < obj_compared.Timeframe() || this.TypePattern() < obj_compared.TypePattern() || this.ObjectID() < obj_compared.ObjectID() ? -1 : 0 ); }
ここでは、現在のオブジェクトの各プロパティが、比較対象のオブジェクトの対応するプロパティと比較されます。比較された各プロパティが等しい場合にのみ、0が返されます。
以下は、パターンを検索し、見つかったパターンを全パターンのリストに追加するメソッドです。
//+------------------------------------------------------------------+ //| CPatternControl::Search for patterns and add | //| found ones to the list of all patterns | //+------------------------------------------------------------------+ int CPatternControl::CreateAndRefreshPatternList(void) { //--- 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; //--- 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(),1); //--- 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; } //--- If the drawing flag is set, draw the pattern label on the chart if(this.m_drawing) pattern.Draw(); } } //--- 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(); }
メソッドのロジックは、コードコメントで詳しく説明されています。要するに、現在のバーを除くすべてのバーのリストを使用して(パターンは完了したバーでのみ検索されるべきです)、FindPattern()仮想メソッドを使用してパターンを検索します。各パターンは独自の方法で検索されるため、その実装は継承されたクラスでおこなう必要があります。パターンが見つかれば、同じ理由で継承されたクラスで実装されている仮想メソッド CreatePattern()を使用して、新しいパターンオブジェクトが作成されます。新しく作成されたオブジェクトは、すべてのライブラリパターンのリストに配置されます。
以下は、チャート上にパターンラベルを表示するメソッドです。
//+------------------------------------------------------------------+ //| Display pattern labels on the chart | //+------------------------------------------------------------------+ void CPatternControl::DrawPatterns(const bool redraw=false) { //--- Get a list of patterns controlled by the control object CArrayObj *list=this.GetListPatterns(); if(list==NULL || list.Total()==0) return; //--- Sort the obtained list by pattern time list.Sort(SORT_BY_PATTERN_TIME); //--- In a loop from the latest pattern, for(int i=list.Total()-1;i>=0;i--) { //--- get the next pattern object CPattern *obj=list.At(i); if(obj==NULL) continue; //--- Display the pattern label on the chart obj.Draw(false); } //--- At the end of the cycle, redraw the chart if the flag is set if(redraw) ::ChartRedraw(this.m_chart_id); }
メソッドのロジックは、コードにコメントされています。要するに、この制御オブジェクトによって制御されているパターンのみのリストを得ることができます。得られたリストを使用したループで、次のパターンオブジェクトをそれぞれ取得し、そのグラフィカルラベルをチャート上に表示します。チャートはループの最後に再描画されるので、ループの反復ごとにチャートが再描画されることはありません。
基本的なパターン制御オブジェクトクラスができました。ここで、パターンの型とそのパラメータがすでに正確に指定されている継承クラスを書く必要があります。
今日はピンバーという1つのパターンしか作らないので、それを制御するオブジェクトを作成します。同じファイルにコードを書き続けましょう。
//+------------------------------------------------------------------+ //| 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) 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(); } };
クラスコンストラクタの初期化リストで、プライスアクションパターンのステータスとピンバーパターンのタイプを親クラスに渡します。また、コンストラクタのパラメータは、外部リストとパターン検索基準へのポインタを渡します。
以下は、パターン検索条件に基づいてオブジェクトIDを作成するメソッドです。
//+------------------------------------------------------------------+ //| Create object ID based on pattern search criteria | //+------------------------------------------------------------------+ ulong CPatternControlPinBar::CreateObjectID(void) { ushort body=(ushort)this.RatioBodyToCandleSizeValue()*100; ushort larger=(ushort)this.RatioLargerShadowToCandleSizeValue()*100; ushort smaller=(ushort)this.RatioSmallerShadowToCandleSizeValue()*100; ulong res=0; this.UshortToLong(body,0,res); this.UshortToLong(larger,1,res); return this.UshortToLong(smaller,2,res); }
3つの基準(ローソク足全体の大きさに対するローソク足実体の割合、ローソク足全体の大きさに対する最も長い髭と最も短い髭の割合)は実数(パーセント)で指定され、100を超えることはできません。そこで、これらを100倍して整数値に変換し、UshortToLong()拡張標準オブジェクトライブラリのメソッドを使用してulong IDを作成し、long番号の指定されたビットをushort値で埋めます。
//+------------------------------------------------------------------+ //| Pack a 'ushort' number to a passed 'long' number | //+------------------------------------------------------------------+ long CBaseObjExt::UshortToLong(const ushort ushort_value,const uchar to_byte,long &long_value) { if(to_byte>3) { ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR_INDEX)); return 0; } return(long_value |= this.UshortToByte(ushort_value,to_byte)); } //+------------------------------------------------------------------+ //| Convert a 'ushort' value to a specified 'long' number byte | //+------------------------------------------------------------------+ long CBaseObjExt::UshortToByte(const ushort value,const uchar to_byte) const { return(long)value<<(16*to_byte); }
以下は、指定された方向のパターンを作成する仮想メソッドです。
//+--------------------------------------------------------------------+ //| 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}; rates.time=bar.Time(); rates.open=bar.Open(); rates.high=bar.High(); rates.low=bar.Low(); rates.close=bar.Close(); //--- 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; }
メソッドのロジックは、コードのコメントで説明されています。パターン制御オブジェクトへのポインタも、作成されたパターンオブジェクトに登録されていることがわかります。したがって、プログラムのどこかでパターンオブジェクトへのポインタを受け取れば、それを使用してこのパターンを作成した制御オブジェクトにアクセスし、それを処理することができます。つまり、制御オブジェクトからパターンへ、そしてその逆へと、双方向のアクセスが可能です。
以下は、パターンを検索するメソッドです。
//+------------------------------------------------------------------+ //| CPatternControlPinBar::Search for the pattern | //+------------------------------------------------------------------+ ENUM_PATTERN_DIRECTION CPatternControlPinBar::FindPattern(const datetime series_bar_time,const uint min_body_size) const { //--- Pointers to objects CBar *bar=NULL; CPatternPinBar *pin_bar=NULL; //--- 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) 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) return PATTERN_DIRECTION_BEARISH; //--- No patterns found - return -1 return WRONG_VALUE; }
メソッドのロジックは、コードにコメントされています。つまり、ピンバーは1本のプライスアクションであり、必要なのは1本のバーだけです。メソッドに渡されたバー時間に基づいてバーを1つ取得します。次に、ローソク足の実体全体の大きさに対する比率を調べます。もし実体が許容サイズより大きければ、間違いなくパターンは存在せず、-1を返します。ローソク足の大きさの基準に合格した場合、同じように、まずローソク足の髭の長さが強気パターンの条件を満たすかどうかを確認します。強気パターンがなければ、ローソク足の髭が弱気パターンのの条件を満たすかどうかを確認します。パターンが見つかったら、その方向を返します。そうでない場合は-1を返します。
以下は、オブジェクトが管理するパターンのリストを返すメソッドです。
//+------------------------------------------------------------------+ //| Returns the list of patterns managed by the object | //+------------------------------------------------------------------+ CArrayObj *CPatternControlPinBar::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_PIN_BAR,EQUAL); return CSelect::ByPatternProperty(list,PATTERN_PROP_CTRL_OBJ_ID,this.ObjectID(),EQUAL); }
全パターンのリストから、このオブジェクトに設定されたチャート期間を持つパターンのみを探します。
出来上がったリストから、このオブジェクトの銘柄セットを持つパターンを探します。
出来上がったリストからピンバーパターンのみを抽出します。
制御オブジェクトIDが設定されているパターンのみのリストへのポインタを返します。
何らかの段階でリストを取得できなかった場合は、NULLが返されます。
ピンバーパターン制御オブジェクトの準備が整いました。次回以降、徐々に新しいパターンとそれを管理するための新しいオブジェクトを追加していく予定です。
次に、上で作成したパターン制御オブジェクトを管理するクラスを書く必要があります。さらに同じファイルに書き続けます。
このクラスの核となるのは、作成されたパターン制御オブジェクトのリストと、それらにアクセスするためのメソッド群です。すべてのメソッドは同じ型であり、クラス本体で直接実装されます。
privateセクションには、パターン制御オブジェクトのリストと、時系列と全パターンのリストが含まれます。publicセクションには、時間枠、銘柄、オブジェクトへのポインタを返すメソッドが含まれています:
//+------------------------------------------------------------------+ //| Pattern control class | //+------------------------------------------------------------------+ class CPatternsControl : public CBaseObjExt { private: CArrayObj m_list_controls; // List of pattern management controllers CArrayObj *m_list_series; // Pointer to the timeseries list CArrayObj *m_list_all_patterns; // Pointer to the list of all patterns //--- Timeseries data ENUM_TIMEFRAMES m_timeframe; // Timeseries timeframe string m_symbol; // Timeseries symbol public: //--- Return (1) timeframe, (2) timeseries symbol, (3) itself ENUM_TIMEFRAMES Timeframe(void) const { return this.m_timeframe; } string Symbol(void) const { return this.m_symbol; } CPatternsControl *GetObject(void) { return &this; } protected:
protectedセクションには、パターン制御オブジェクトを返すメソッドが含まれています。完全に準備できているのは、指定されたパラメータを持つピンバーパターン制御オブジェクトを返すメソッドだけです。
//--- Return the Pin Bar pattern control object CPatternControl *GetObjControlPatternPinBar(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 { //--- In a loop through the list of control objects, int total=this.m_list_controls.Total(); for(int i=0;i<total;i++) { //--- get the next object CPatternControl *obj=this.m_list_controls.At(i); //--- if this is not a Pin Bar pattern control object, go to the next one if(obj==NULL || obj.TypePattern()!=PATTERN_TYPE_PIN_BAR) continue; //--- Check search conditions and return the result if(ratio_body==obj.RatioBodyToCandleSizeValue() && ratio_larger_shadow==obj.RatioLargerShadowToCandleSizeValue() && ratio_smaller_shadow==obj.RatioSmallerShadowToCandleSizeValue()) return obj; } //--- Not found - return NULL return NULL; }
残りのメソッドは空で作成されます。すべてのメソッドのリストを見てみましょう。
protected: //--- Return the Harami pattern control object CPatternControl *GetObjControlPatternHarami(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 || obj.TypePattern()!=PATTERN_TYPE_HARAMI) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Harami Cross pattern control object CPatternControl *GetObjControlPatternHaramiCross(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 || obj.TypePattern()!=PATTERN_TYPE_HARAMI_CROSS) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Tweezer pattern control object CPatternControl *GetObjControlPatternTweezer(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 || obj.TypePattern()!=PATTERN_TYPE_TWEEZER) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Piercing Line pattern control object CPatternControl *GetObjControlPatternPiercingLine(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 || obj.TypePattern()!=PATTERN_TYPE_PIERCING_LINE) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Cloud Cover pattern control object CPatternControl *GetObjControlPatternDarkCloudCover(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 || obj.TypePattern()!=PATTERN_TYPE_DARK_CLOUD_COVER) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Three White Soldiers pattern control object CPatternControl *GetObjControlPatternThreeWhiteSoldiers(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 || obj.TypePattern()!=PATTERN_TYPE_THREE_WHITE_SOLDIERS) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Three Black Crows pattern control object CPatternControl *GetObjControlPatternThreeBlackCrows(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 || obj.TypePattern()!=PATTERN_TYPE_THREE_BLACK_CROWS) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Shooting Star pattern control object CPatternControl *GetObjControlPatternShootingStar(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 || obj.TypePattern()!=PATTERN_TYPE_SHOOTING_STAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Hammer pattern control object CPatternControl *GetObjControlPatternHammer(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 || obj.TypePattern()!=PATTERN_TYPE_HAMMER) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Inverted Hammer pattern control object CPatternControl *GetObjControlPatternInvertedHammer(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 || obj.TypePattern()!=PATTERN_TYPE_INVERTED_HAMMER) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Hanging Man pattern control object CPatternControl *GetObjControlPatternHangingMan(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 || obj.TypePattern()!=PATTERN_TYPE_HANGING_MAN) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Doji pattern control object CPatternControl *GetObjControlPatternDoji(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 || obj.TypePattern()!=PATTERN_TYPE_DOJI) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Dragonfly Doji pattern control object CPatternControl *GetObjControlPatternDragonflyDoji(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 || obj.TypePattern()!=PATTERN_TYPE_DRAGONFLY_DOJI) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Gravestone Doji pattern control object CPatternControl *GetObjControlPatternGravestoneDoji(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 || obj.TypePattern()!=PATTERN_TYPE_GRAVESTONE_DOJI) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Morning Star pattern control object CPatternControl *GetObjControlPatternMorningStar(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 || obj.TypePattern()!=PATTERN_TYPE_MORNING_STAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Morning Doji Star pattern control object CPatternControl *GetObjControlPatternMorningDojiStar(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 || obj.TypePattern()!=PATTERN_TYPE_MORNING_DOJI_STAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Evening Star pattern control object CPatternControl *GetObjControlPatternEveningStar(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 || obj.TypePattern()!=PATTERN_TYPE_EVENING_STAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Evening Doji Star pattern control object CPatternControl *GetObjControlPatternEveningDojiStar(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 || obj.TypePattern()!=PATTERN_TYPE_EVENING_DOJI_STAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Three Stars pattern control object CPatternControl *GetObjControlPatternThreeStars(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 || obj.TypePattern()!=PATTERN_TYPE_THREE_STARS) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Abandoned Body pattern control object CPatternControl *GetObjControlPatternAbandonedBaby(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 || obj.TypePattern()!=PATTERN_TYPE_ABANDONED_BABY) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Price Action //--- Return the Pivot Point Reversal pattern control object CPatternControl *GetObjControlPatternPivotPointReversal(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 || obj.TypePattern()!=PATTERN_TYPE_PIVOT_POINT_REVERSAL) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Outside Bar pattern control object CPatternControl *GetObjControlPatternOutsideBar(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 || obj.TypePattern()!=PATTERN_TYPE_OUTSIDE_BAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- 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 || obj.TypePattern()!=PATTERN_TYPE_INSIDE_BAR) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } //--- Return the Pin Bar pattern control object CPatternControl *GetObjControlPatternPinBar(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 { //--- In a loop through the list of control objects, int total=this.m_list_controls.Total(); for(int i=0;i<total;i++) { //--- get the next object CPatternControl *obj=this.m_list_controls.At(i); //--- if this is not a Pin Bar pattern control object, go to the next one if(obj==NULL || obj.TypePattern()!=PATTERN_TYPE_PIN_BAR) continue; //--- Check search conditions and return the result if(ratio_body==obj.RatioBodyToCandleSizeValue() && ratio_larger_shadow==obj.RatioLargerShadowToCandleSizeValue() && ratio_smaller_shadow==obj.RatioSmallerShadowToCandleSizeValue()) return obj; } //--- Not found - return NULL return NULL; } //--- Return the Rails pattern control object CPatternControl *GetObjControlPatternRails(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 || obj.TypePattern()!=PATTERN_TYPE_RAILS) continue; //--- Check search conditions and return the result //if(condition) // return obj; } return NULL; } public:
新しいパターンを作成しながら、それぞれのメソッドに特定のパターンを作成するのに必要なインプットを追加していきます。
クラスのpublicセクションには、パターンを使用するためのフラグを設定したり、制御オブジェクトを作成したりするメソッドのリストが含まれます。各パターンについて、メソッドのパラメータはそのパターンに固有のプロパティを示します。以下は、ピンバーパターンフラグを設定するメソッドです。
//--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetUsedPatternPinBar(const bool flag, // Price Action Pin Bar usage 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.SetUsed(flag); //--- f there is no object and the flag is passed as 'true' else if(flag) { //--- Create a new Pin Bar pattern control object with the specified parameters obj=new CPatternControlPinBar(this.Symbol(),this.Timeframe(),this.m_list_series,this.m_list_all_patterns,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); 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(ratio_body); obj.SetRatioLargerShadowToCandleSizeValue(ratio_larger_shadow); obj.SetRatioSmallerShadowToCandleSizeValue(ratio_smaller_shadow); obj.CreateAndRefreshPatternList(); } }
残りのメソッドは、あくまでテンプレートとして書いたもので、新しいパターンが生まれるたびに補足していくつもりです。
public: //+------------------------------------------------------------------+ //| Methods for setting the pattern use flag | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetUsedPatternHarami(const bool flag) { } //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetUsedPatternHaramiCross(const bool flag) { } //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetUsedPatternTweezer(const bool flag) { } //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetUsedPatternPiercingLine(const bool flag) { } //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetUsedPatternDarkCloudCover(const bool flag) { } //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetUsedPatternThreeWhiteSoldiers(const bool flag) { } //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetUsedPatternThreeBlackCrows(const bool flag) { } //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetUsedPatternShootingStar(const bool flag) { } //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetUsedPatternHammer(const bool flag) { } //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetUsedPatternInvertedHammer(const bool flag) { } //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetUsedPatternHangingMan(const bool flag) { } //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetUsedPatternDoji(const bool flag) { } //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetUsedPatternDragonflyDoji(const bool flag) { } //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetUsedPatternGravestoneDoji(const bool flag) { } //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetUsedPatternMorningStar(const bool flag) { } //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetUsedPatternMorningDojiStar(const bool flag) { } //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetUsedPatternEveningStar(const bool flag) { } //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetUsedPatternEveningDojiStar(const bool flag) { } //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetUsedPatternThreeStars(const bool flag) { } //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetUsedPatternAbandonedBaby(const bool flag) { } //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist //--- Price Action void SetUsedPatternPivotPointReversal(const bool flag) { } //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetUsedPatternOutsideBar(const bool flag) { } //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const bool flag) { } //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetUsedPatternPinBar(const bool flag, // Price Action Pin Bar usage 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.SetUsed(flag); //--- f there is no object and the flag is passed as 'true' else if(flag) { //--- Create a new Pin Bar pattern control object with the specified parameters obj=new CPatternControlPinBar(this.Symbol(),this.Timeframe(),this.m_list_series,this.m_list_all_patterns,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); 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(ratio_body); obj.SetRatioLargerShadowToCandleSizeValue(ratio_larger_shadow); obj.SetRatioSmallerShadowToCandleSizeValue(ratio_smaller_shadow); obj.CreateAndRefreshPatternList(); } } //--- Set the flag for using the Rails pattern and create a control object if it does not already exist void SetUsedPatternRails(const bool flag) { }
パターンを返すメソッドはフラグを使用します。ここでは、ピンバーパターン使用フラグを返すメソッドのみを用意しました。
//--- Return the flag of using the Pin Bar pattern bool IsUsedPatternPinBar(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.IsUsed() : false); }
残りのメソッドは空で、パターン入力が指定されていません。
//+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsUsedPatternHarami(void) { CPatternControl *obj=GetObjControlPatternHarami(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Harami Cross pattern bool IsUsedPatternHaramiCross(void) { CPatternControl *obj=GetObjControlPatternHaramiCross(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Tweezer pattern bool IsUsedPatternTweezer(void) { CPatternControl *obj=GetObjControlPatternTweezer(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Piercing Line pattern bool IsUsedPatternPiercingLine(void) { CPatternControl *obj=GetObjControlPatternPiercingLine(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Cloud Cover pattern bool IsUsedPatternDarkCloudCover(void) { CPatternControl *obj=GetObjControlPatternDarkCloudCover(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Three White Soldiers pattern bool IsUsedPatternThreeWhiteSoldiers(void) { CPatternControl *obj=GetObjControlPatternThreeWhiteSoldiers(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Three Black Crows pattern bool IsUsedPatternThreeBlackCrows(void) { CPatternControl *obj=GetObjControlPatternThreeBlackCrows(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Shooting Star pattern bool IsUsedPatternShootingStar(void) { CPatternControl *obj=GetObjControlPatternShootingStar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Hammer pattern bool IsUsedPatternHammer(void) { CPatternControl *obj=GetObjControlPatternHammer(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Inverted Hammer pattern bool IsUsedPatternInvertedHammer(void) { CPatternControl *obj=GetObjControlPatternInvertedHammer(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Hanging Man pattern bool IsUsedPatternHangingMan(void) { CPatternControl *obj=GetObjControlPatternHangingMan(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Doji pattern bool IsUsedPatternDoji(void) { CPatternControl *obj=GetObjControlPatternDoji(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Dragonfly Doji pattern bool IsUsedPatternDragonflyDoji(void) { CPatternControl *obj=GetObjControlPatternDragonflyDoji(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Gravestone Doji pattern bool IsUsedPatternGravestoneDoji(void) { CPatternControl *obj=GetObjControlPatternGravestoneDoji(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Morning Star pattern bool IsUsedPatternMorningStar(void) { CPatternControl *obj=GetObjControlPatternMorningStar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Morning Doji Star pattern bool IsUsedPatternMorningDojiStar(void) { CPatternControl *obj=GetObjControlPatternMorningDojiStar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Evening Star pattern bool IsUsedPatternEveningStar(void) { CPatternControl *obj=GetObjControlPatternEveningStar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Evening Doji Star pattern bool IsUsedPatternEveningDojiStar(void) { CPatternControl *obj=GetObjControlPatternEveningDojiStar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Three Stars pattern bool IsUsedPatternThreeStars(void) { CPatternControl *obj=GetObjControlPatternThreeStars(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Abandoned Baby pattern bool IsUsedPatternAbandonedBaby(void) { CPatternControl *obj=GetObjControlPatternAbandonedBaby(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsUsedPatternPivotPointReversal(void) { CPatternControl *obj=GetObjControlPatternPivotPointReversal(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Pattern Outside bool IsUsedPatternOutsideBar(void) { CPatternControl *obj=GetObjControlPatternOutsideBar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Inside Bar pattern bool IsUsedPatternInsideBar(void) { CPatternControl *obj=GetObjControlPatternInsideBar(); return(obj!=NULL ? obj.IsUsed() : false); } //--- Return the flag of using the Pin Bar pattern bool IsUsedPatternPinBar(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.IsUsed() : false); } //--- Return the flag of using the Rails pattern bool IsUsedPatternRails(void) { CPatternControl *obj=GetObjControlPatternRails(); return(obj!=NULL ? obj.IsUsed() : false); }
以下は、すべてのアクティブなパターンを検索し、更新するメソッドです。
//+------------------------------------------------------------------+ //| Pattern data update methods | //+------------------------------------------------------------------+ //--- Search and update all active patterns void RefreshAll(void) { //--- In a loop through the list of pattern control objects, int total=this.m_list_controls.Total(); for(int i=0;i<total;i++) { //--- get the next control object CPatternControl *ctrl=this.m_list_controls.At(i); if(ctrl==NULL) continue; //--- If the object is received, search and create a new pattern ctrl.CreateAndRefreshPatternList(); } //--- At the end of the loop, display the pattern icons on the chart this.DrawPatternPinBar(); }
以下は、チャートにパターンを描くメソッドです。完全に準備できているのは、ピンバーパターンのラベルを描画するメソッドだけです。残りのメソッドは、パターン入力のないテンプレートの形で実装されています。
//+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //--- Set Harami pattern labels on the chart void DrawPatternHarami(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternHarami(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Harami Cross pattern labels on the chart void DrawPatternHaramiCross(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternHaramiCross(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Tweezer pattern labels on the chart void DrawPatternTweezer(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternTweezer(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Piercing Line pattern labels on the chart void DrawPatternPiercingLine(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternPiercingLine(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Cloud Cover pattern labels on the chart void DrawPatternDarkCloudCover(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternDarkCloudCover(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Three White Soldiers pattern labels on the chart void DrawPatternThreeWhiteSoldiers(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternThreeWhiteSoldiers(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Three Black Crows pattern labels on the chart void DrawPatternThreeBlackCrows(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternThreeBlackCrows(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Shooting Star pattern labels on the chart void DrawPatternShootingStar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternShootingStar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Hammer pattern labels on the chart void DrawPatternHammer(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternHammer(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Inverted Hammer pattern labels on the chart void DrawPatternInvertedHammer(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternInvertedHammer(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Hanging Man pattern labels on the chart void DrawPatternHangingMan(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternHangingMan(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Doji pattern labels on the chart void DrawPatternDoji(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternDoji(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Dragonfly Doji pattern labels on the chart void DrawPatternDragonflyDoji(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternDragonflyDoji(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Engraved Doji pattern labels on the chart void DrawPatternGravestoneDoji(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternGravestoneDoji(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Morning Star pattern labels on the chart void DrawPatternMorningStar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternMorningStar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Morning Doji Star pattern labels on the chart void DrawPatternMorningDojiStar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternMorningDojiStar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Evening Star pattern labels on the chart void DrawPatternEveningStar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternEveningStar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Morning Doji Star pattern labels on the chart void DrawPatternEveningDojiStar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternEveningDojiStar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Three Stars pattern labels on the chart void DrawPatternThreeStars(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternThreeStars(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Abandoned Baby pattern labels on the chart void DrawPatternAbandonedBaby(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternAbandonedBaby(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Pivot Point Reversal pattern labels on the chart //--- Price Action void DrawPatternPivotPointReversal(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternPivotPointReversal(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Outside Bar pattern labels on the chart void DrawPatternOutsideBar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternOutsideBar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Inside Bar pattern labels on the chart void DrawPatternInsideBar(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternInsideBar(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Set Pin Bar pattern labels on the chart void DrawPatternPinBar(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 const bool redraw=false) // Chart redraw flag { //--- Get the pattern control object with the specified parameters CPatternControl *obj=GetObjControlPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow); if(obj==NULL) return; //--- Draw pattern labels on the chart obj.DrawPatterns(redraw); } //--- Set Rails pattern labels on the chart void DrawPatternRails(const bool redraw=false) { CPatternControl *obj=GetObjControlPatternRails(); if(obj==NULL) return; obj.DrawPatterns(redraw); } //--- Constructor CPatternsControl(const string symbol,const ENUM_TIMEFRAMES timeframe,CArrayObj *list_timeseries,CArrayObj *list_all_patterns); };
クラスのコンストラクタで、ライブラリオブジェクトタイプを設定し、チャート銘柄と時間枠を調整して設定し、コンストラクタのパラメータで渡された外部リストへのポインタを、時系列リストとすべてのパターンのポインタに設定します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPatternsControl::CPatternsControl(const string symbol,const ENUM_TIMEFRAMES timeframe,CArrayObj *list_timeseries,CArrayObj *list_all_patterns) { this.m_type=OBJECT_DE_TYPE_SERIES_PATTERNS_CONTROLLERS; this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol); this.m_timeframe=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe); this.m_list_series=list_timeseries; this.m_list_all_patterns=list_all_patterns; }
パターン制御クラスの準備が整いました。
あとは、準備されたパターン制御のオブジェクトクラスを時系列クラスに適合させ、それらへのアクセスを整える必要があります。
同じファイル \MQL5\Include\DoEasy\Objects\Series\SeriesDE.mqh内の時系列クラスにいくつか変更を加えてみましょう。
privateセクションで、パターン制御オブジェクトへのポインタを宣言します。protectedセクションで、全銘柄の時系列の全パターンのリストへのポインタを宣言し、publicセクションで、パターン制御オブジェクトへのポインタを返すメソッドを宣言します。
//+------------------------------------------------------------------+ //| Timeseries class | //+------------------------------------------------------------------+ class CSeriesDE : public CBaseObj { private: ENUM_TIMEFRAMES m_timeframe; // Timeframe string m_symbol; // Symbol string m_period_description; // Timeframe string description datetime m_firstdate; // The very first date by a period symbol at the moment datetime m_lastbar_date; // Time of opening the last bar by period symbol uint m_amount; // Amount of applied timeseries data uint m_required; // Required amount of applied timeseries data uint m_bars; // Number of bars in history by symbol and timeframe bool m_sync; // Synchronized data flag CArrayObj m_list_series; // Timeseries list CNewBarObj m_new_bar_obj; // "New bar" object CPatternsControl *m_patterns_control; // Pointer to pattern control object //--- Set the very first date by a period symbol at the moment and the new time of opening the last bar by a period symbol void SetServerDate(void) { this.m_firstdate=(datetime)::SeriesInfoInteger(this.m_symbol,this.m_timeframe,SERIES_FIRSTDATE); this.m_lastbar_date=(datetime)::SeriesInfoInteger(this.m_symbol,this.m_timeframe,SERIES_LASTBAR_DATE); } protected: CArrayObj *m_list_all_patterns; // Pointer to the list of all patterns of all timeseries of all symbols public: //--- Return (1) itself, (2) timeseries list, (3) timeseries "New bar" object and (4) pattern management object CSeriesDE *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &m_list_series; } CNewBarObj *GetNewBarObj(void) { return &this.m_new_bar_obj; } CPatternsControl *GetPatternsCtrlObj(void) { return this.m_patterns_control;}
このクラスには、デフォルトでデストラクタしか作成されていません。クラスのデストラクタを宣言します。また、全パターンの外部リストへのポインタをクラス定数に追加します。類似のオブジェクトメソッドを繰り返すパターン制御オブジェクトを処理するメソッドを書きます。ここでは、パターン制御オブジェクトの対応するメソッドのみが呼び出されます。
//--- Constructors CSeriesDE(CArrayObj *list); CSeriesDE(CArrayObj *list,const string symbol,const ENUM_TIMEFRAMES timeframe,const uint required=0); ~CSeriesDE(void); //+------------------------------------------------------------------+ //| Working with patterns | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for setting the pattern use and data update flag | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetUsedPatternHarami(const bool flag) { } //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetUsedPatternHaramiCross(const bool flag) { } //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetUsedPatternTweezer(const bool flag) { } //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetUsedPatternPiercingLine(const bool flag) { } //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetUsedPatternDarkCloudCover(const bool flag) { } //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetUsedPatternThreeWhiteSoldiers(const bool flag) { } //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetUsedPatternThreeBlackCrows(const bool flag) { } //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetUsedPatternShootingStar(const bool flag) { } //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetUsedPatternHammer(const bool flag) { } //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetUsedPatternInvertedHammer(const bool flag) { } //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetUsedPatternHangingMan(const bool flag) { } //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetUsedPatternDoji(const bool flag) { } //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetUsedPatternDragonflyDoji(const bool flag) { } //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetUsedPatternGravestoneDoji(const bool flag) { } //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetUsedPatternMorningStar(const bool flag) { } //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetUsedPatternMorningDojiStar(const bool flag) { } //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetUsedPatternEveningStar(const bool flag) { } //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetUsedPatternEveningDojiStar(const bool flag) { } //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetUsedPatternThreeStars(const bool flag) { } //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetUsedPatternAbandonedBaby(const bool flag) { } //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist //--- Price Action void SetUsedPatternPivotPointReversal(const bool flag) { } //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetUsedPatternOutsideBar(const bool flag) { } //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const bool flag) { } //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetUsedPatternPinBar(const bool flag, // Price Action Pin Bar usage 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.SetUsedPatternPinBar(flag,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //--- Set the flag for using the Rails pattern and create a control object if it does not already exist void SetUsedPatternRails(const bool flag) { } //+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsUsedPatternHarami(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternHarami() : false); } //--- Return the flag of using the Harami Cross pattern bool IsUsedPatternHaramiCross(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternHaramiCross() : false); } //--- Return the flag of using the Tweezer pattern bool IsUsedPatternTweezer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternTweezer() : false); } //--- Return the flag of using the Piercing Line pattern bool IsUsedPatternPiercingLine(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternPiercingLine() : false); } //--- Return the flag of using the Cloud Cover pattern bool IsUsedPatternDarkCloudCover(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternDarkCloudCover() : false); } //--- Return the flag of using the Three White Soldiers pattern bool IsUsedPatternThreeWhiteSoldiers(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternThreeWhiteSoldiers() : false); } //--- Return the flag of using the Three Black Crows pattern bool IsUsedPatternThreeBlackCrows(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternThreeBlackCrows() : false); } //--- Return the flag of using the Shooting Star pattern bool IsUsedPatternShootingStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternShootingStar() : false); } //--- Return the flag of using the Hammer pattern bool IsUsedPatternHammer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternHammer() : false); } //--- Return the flag of using the Inverted Hammer pattern bool IsUsedPatternInvertedHammer(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternInvertedHammer() : false); } //--- Return the flag of using the Hanging Man pattern bool IsUsedPatternHangingMan(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternHangingMan() : false); } //--- Return the flag of using the Doji pattern bool IsUsedPatternDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternDoji() : false); } //--- Return the flag of using the Dragonfly Doji pattern bool IsUsedPatternDragonflyDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternDragonflyDoji() : false); } //--- Return the flag of using the Gravestone Doji pattern bool IsUsedPatternGravestoneDoji(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternGravestoneDoji() : false); } //--- Return the flag of using the Morning Star pattern bool IsUsedPatternMorningStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternMorningStar() : false); } //--- Return the flag of using the Morning Doji Star pattern bool IsUsedPatternMorningDojiStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternMorningDojiStar() : false); } //--- Return the flag of using the Evening Star pattern bool IsUsedPatternEveningStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternEveningStar() : false); } //--- Return the flag of using the Evening Doji Star pattern bool IsUsedPatternEveningDojiStar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternEveningDojiStar() : false); } //--- Return the flag of using the Three Stars pattern bool IsUsedPatternThreeStars(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternThreeStars() : false); } //--- Return the flag of using the Abandoned Baby pattern bool IsUsedPatternAbandonedBaby(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternAbandonedBaby() : false); } //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsUsedPatternPivotPointReversal(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternPivotPointReversal() : false); } //--- Return the flag of using the Pattern Outside bool IsUsedPatternOutsideBar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternOutsideBar() : false); } //--- Return the flag of using the Inside Bar pattern bool IsUsedPatternInsideBar(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternInsideBar() : false); } //--- Return the flag of using the Pin Bar pattern bool IsUsedPatternPinBar(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.IsUsedPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //--- Return the flag of using the Rails pattern bool IsUsedPatternRails(void) { return(this.m_patterns_control!=NULL ? this.m_patterns_control.IsUsedPatternRails() : false); } //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //--- Set Harami pattern labels on the chart void DrawPatternHarami(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternHarami(redraw); } //--- Set Harami Cross pattern labels on the chart void DrawPatternHaramiCross(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternHaramiCross(redraw); } //--- Set Tweezer pattern labels on the chart void DrawPatternTweezer(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternTweezer(redraw); } //--- Set Piercing Line pattern labels on the chart void DrawPatternPiercingLine(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternPiercingLine(redraw); } //--- Set Cloud Cover pattern labels on the chart void DrawPatternDarkCloudCover(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternDarkCloudCover(redraw); } //--- Set Three White Soldiers pattern labels on the chart void DrawPatternThreeWhiteSoldiers(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternThreeWhiteSoldiers(redraw); } //--- Set Three Black Crows pattern labels on the chart void DrawPatternThreeBlackCrows(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternThreeBlackCrows(redraw); } //--- Set Shooting Star pattern labels on the chart void DrawPatternShootingStar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternShootingStar(redraw); } //--- Set Hammer pattern labels on the chart void DrawPatternHammer(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternHammer(redraw); } //--- Set Inverted Hammer pattern labels on the chart void DrawPatternInvertedHammer(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternInvertedHammer(redraw); } //--- Set Hanging Man pattern labels on the chart void DrawPatternHangingMan(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternHangingMan(redraw); } //--- Set Doji pattern labels on the chart void DrawPatternDoji(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternDoji(redraw); } //--- Set Dragonfly Doji pattern labels on the chart void DrawPatternDragonflyDoji(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternDragonflyDoji(redraw); } //--- Set Engraved Doji pattern labels on the chart void DrawPatternGravestoneDoji(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternGravestoneDoji(redraw); } //--- Set Morning Star pattern labels on the chart void DrawPatternMorningStar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternMorningStar(redraw); } //--- Set Morning Doji Star pattern labels on the chart void DrawPatternMorningDojiStar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternMorningDojiStar(redraw); } //--- Set Evening Star pattern labels on the chart void DrawPatternEveningStar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternEveningStar(redraw); } //--- Set Morning Doji Star pattern labels on the chart void DrawPatternEveningDojiStar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternEveningDojiStar(redraw); } //--- Set Three Stars pattern labels on the chart void DrawPatternThreeStars(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternThreeStars(redraw); } //--- Set Abandoned Baby pattern labels on the chart void DrawPatternAbandonedBaby(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternAbandonedBaby(redraw); } //--- Set Pivot Point Reversal pattern labels on the chart //--- Price Action void DrawPatternPivotPointReversal(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternPivotPointReversal(redraw); } //--- Set Outside Bar pattern labels on the chart void DrawPatternOutsideBar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternOutsideBar(redraw); } //--- Set Inside Bar pattern labels on the chart void DrawPatternInsideBar(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternInsideBar(redraw); } //--- Set Pin Bar pattern labels on the chart void DrawPatternPinBar(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 const bool redraw=false) // Chart redraw flag { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow,redraw); } //--- Set Rails pattern labels on the chart void DrawPatternRails(const bool redraw=false) { if(this.m_patterns_control!=NULL) this.m_patterns_control.DrawPatternRails(redraw); } };
クラスのコンストラクタの実装では、コンストラクタに渡された外部リストへのポインタを、すべてのパターンのリストへのポインタに代入し、新しいパターン制御オブジェクトを作成します。
//+------------------------------------------------------------------+ //| Constructor 1 (current symbol and period timeseries) | //+------------------------------------------------------------------+ CSeriesDE::CSeriesDE(CArrayObj *list) : m_bars(0),m_amount(0),m_required(0),m_sync(false) { this.m_type=OBJECT_DE_TYPE_SERIES_PERIOD; this.m_list_series.Clear(); this.m_list_series.Sort(SORT_BY_BAR_TIME); this.SetSymbolPeriod(NULL,(ENUM_TIMEFRAMES)::Period()); this.m_period_description=TimeframeDescription(this.m_timeframe); this.m_list_all_patterns=list; this.m_patterns_control=new CPatternsControl(this.m_symbol,this.m_timeframe,this.GetList(),this.m_list_all_patterns); } //+------------------------------------------------------------------+ //| Constructor 2 (specified symbol and period timeseries) | //+------------------------------------------------------------------+ CSeriesDE::CSeriesDE(CArrayObj *list,const string symbol,const ENUM_TIMEFRAMES timeframe,const uint required=0) : m_bars(0), m_amount(0),m_required(0),m_sync(false) { this.m_type=OBJECT_DE_TYPE_SERIES_PERIOD; this.m_list_series.Clear(); this.m_list_series.Sort(SORT_BY_BAR_TIME); this.SetSymbolPeriod(symbol,timeframe); this.m_sync=this.SetRequiredUsedData(required,0); this.m_period_description=TimeframeDescription(this.m_timeframe); this.m_list_all_patterns=list; this.m_patterns_control=new CPatternsControl(this.m_symbol,this.m_timeframe,this.GetList(),this.m_list_all_patterns); }
クラスのデストラクタで、コンストラクタで生成されたパターン制御オブジェクトを削除します。
//+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CSeriesDE::~CSeriesDE(void) { if(this.m_patterns_control!=NULL) delete this.m_patterns_control; }
パターンを検索するために、リストと時系列データを更新するメソッドに、パターンリストを検索して更新するコードブロックを追加します。
//+------------------------------------------------------------------+ //| Update timeseries list and data | //+------------------------------------------------------------------+ void CSeriesDE::Refresh(SDataCalculate &data_calculate) { //--- If the timeseries is not used, exit if(!this.m_available) return; MqlRates rates[1]; //--- Set the flag of sorting the list of bars by time this.m_list_series.Sort(SORT_BY_BAR_TIME); //--- If a new bar is present on a symbol and period if(this.IsNewBarManual(data_calculate.rates.time)) { //--- create a new bar object and add it to the end of the list CBar *new_bar=new CBar(this.m_symbol,this.m_timeframe,this.m_new_bar_obj.TimeNewBar(),DFUN_ERR_LINE); if(new_bar==NULL) return; if(!this.m_list_series.InsertSort(new_bar)) { delete new_bar; return; } //--- Write the very first date by a period symbol at the moment and the new time of opening the last bar by a period symbol this.SetServerDate(); //--- if the timeseries exceeds the requested number of bars, remove the earliest bar if(this.m_list_series.Total()>(int)this.m_required) this.m_list_series.Delete(0); //--- Update data of all timeseries patterns if(this.m_patterns_control==NULL) return; this.m_patterns_control.RefreshAll(); //--- save the new bar time as the previous one for the subsequent new bar check this.SaveNewBarTime(data_calculate.rates.time); } //--- Get the bar index with the maximum time (zero bar) and bar object from the list by the obtained index int index=CSelect::FindBarMax(this.GetList(),BAR_PROP_TIME); CBar *bar=this.m_list_series.At(index); if(bar==NULL) return; //--- if the work is performed in an indicator and the timeseries belongs to the current symbol and timeframe, //--- copy price parameters (passed to the method from the outside) to the bar price structure int copied=1; if(this.m_program==PROGRAM_INDICATOR && this.m_symbol==::Symbol() && this.m_timeframe==(ENUM_TIMEFRAMES)::Period()) { rates[0].time=data_calculate.rates.time; rates[0].open=data_calculate.rates.open; rates[0].high=data_calculate.rates.high; rates[0].low=data_calculate.rates.low; rates[0].close=data_calculate.rates.close; rates[0].tick_volume=data_calculate.rates.tick_volume; rates[0].real_volume=data_calculate.rates.real_volume; rates[0].spread=data_calculate.rates.spread; } //--- otherwise, get data to the bar price structure from the environment else copied=::CopyRates(this.m_symbol,this.m_timeframe,0,1,rates); //--- If the prices are obtained, set the new properties from the price structure for the bar object if(copied==1) bar.SetProperties(rates[0]); }
MQL5\Include\DoEasy\Objects\Series\TimeSeriesDE.mqh銘柄時系列クラスファイルのprotectedセクションで、全銘柄の全時系列の全パターンのリストへのポインタを宣言し、publicセクションで、リストへのポインタを返すメソッドを宣言します。
//+------------------------------------------------------------------+ //| Symbol timeseries class | //+------------------------------------------------------------------+ class CTimeSeriesDE : public CBaseObjExt { private: string m_symbol; // Timeseries symbol CNewTickObj m_new_tick; // "New tick" object CArrayObj m_list_series; // List of timeseries by timeframes datetime m_server_firstdate; // The very first date in history by a server symbol datetime m_terminal_firstdate; // The very first date in history by a symbol in the client terminal //--- Return (1) the timeframe index in the list and (2) the timeframe by the list index int IndexTimeframe(const ENUM_TIMEFRAMES timeframe); ENUM_TIMEFRAMES TimeframeByIndex(const uchar index) const { return TimeframeByEnumIndex(uchar(index+1)); } //--- Set the very first date in history by symbol on the server and in the client terminal void SetTerminalServerDate(void) { this.m_server_firstdate=(datetime)::SeriesInfoInteger(this.m_symbol,::Period(),SERIES_SERVER_FIRSTDATE); this.m_terminal_firstdate=(datetime)::SeriesInfoInteger(this.m_symbol,::Period(),SERIES_TERMINAL_FIRSTDATE); } protected: CArrayObj *m_list_all_patterns; // Pointer to the list of all patterns of all timeseries of all symbols public: //--- Return (1) itself, full list of (2) timeseries, (3) patterns, (4) specified timeseries object and (5) timeseries object by index CTimeSeriesDE *GetObject(void) { return &this; } CArrayObj *GetListSeries(void) { return &this.m_list_series; } CArrayObj *GetListPatterns(void) { return this.m_list_all_patterns; } CSeriesDE *GetSeries(const ENUM_TIMEFRAMES timeframe) { return this.m_list_series.At(this.IndexTimeframe(timeframe)); } CSeriesDE *GetSeriesByIndex(const uchar index) { return this.m_list_series.At(index); }
時系列クラスのコンストラクタと同じように、外部パターンリストへのポインタを渡し、パターン制御オブジェクトを扱うメソッドを宣言します。
//--- Constructors CTimeSeriesDE(CArrayObj *list_all_patterns) { this.m_type=OBJECT_DE_TYPE_SERIES_SYMBOL; this.m_list_all_patterns=list_all_patterns; } CTimeSeriesDE(CArrayObj *list_all_patterns,const string symbol); //+------------------------------------------------------------------+ //| Methods for setting the pattern use flag | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetUsedPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetUsedPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetUsedPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetUsedPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetUsedPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetUsedPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetUsedPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetUsedPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetUsedPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetUsedPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetUsedPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetUsedPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetUsedPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetUsedPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetUsedPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetUsedPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetUsedPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetUsedPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetUsedPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetUsedPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist //--- Price Action void SetUsedPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetUsedPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetUsedPatternPinBar(const ENUM_TIMEFRAMES timeframe, const bool flag, // Price Action Pin Bar usage 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 SetUsedPatternRails(const ENUM_TIMEFRAMES timeframe,const bool flag); //+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsUsedPatternHarami(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Harami Cross pattern bool IsUsedPatternHaramiCross(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Tweezer pattern bool IsUsedPatternTweezer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Piercing Line pattern bool IsUsedPatternPiercingLine(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Cloud Cover pattern bool IsUsedPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three White Soldiers pattern bool IsUsedPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Black Crows pattern bool IsUsedPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Shooting Star pattern bool IsUsedPatternShootingStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hammer pattern bool IsUsedPatternHammer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inverted Hammer pattern bool IsUsedPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hanging Man pattern bool IsUsedPatternHangingMan(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Doji pattern bool IsUsedPatternDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Dragonfly Doji pattern bool IsUsedPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Gravestone Doji pattern bool IsUsedPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Star pattern bool IsUsedPatternMorningStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Doji Star pattern bool IsUsedPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Star pattern bool IsUsedPatternEveningStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Doji Star pattern bool IsUsedPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Stars pattern bool IsUsedPatternThreeStars(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Abandoned Baby pattern bool IsUsedPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe); //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsUsedPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pattern Outside bool IsUsedPatternOutsideBar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inside Bar pattern bool IsUsedPatternInsideBar(const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pin Bar pattern bool IsUsedPatternPinBar(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 //--- Return the flag of using the Rails pattern bool IsUsedPatternRails(const ENUM_TIMEFRAMES timeframe); //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //--- Draw Harami pattern labels on the chart void DrawPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Harami Cross pattern labels on the chart void DrawPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Tweezer pattern labels on the chart void DrawPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Piercing Line pattern labels on the chart void DrawPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Dark Cloud Cover pattern labels on the chart void DrawPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three White Soldiers pattern labels on the chart void DrawPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three Black Crows pattern labels on the chart void DrawPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Shooting Star pattern labels on the chart void DrawPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Hammer pattern labels on the chart void DrawPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Inverted Hammer pattern labels on the chart void DrawPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Hanging Man pattern labels on the chart void DrawPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Doji pattern labels on the chart void DrawPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Dragonfly Doji pattern labels on the chart void DrawPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Gravestone Doji pattern labels on the chart void DrawPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Morning Star pattern labels on the chart void DrawPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Morning Doji Star pattern labels on the chart void DrawPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Evening Star pattern labels on the chart void DrawPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Evening Doji Star pattern labels on the chart void DrawPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three Stars pattern labels on the chart void DrawPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Abandoned Baby pattern labels on the chart void DrawPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Pivot Point Reversal pattern labels on the chart //--- Price Action void DrawPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Pattern Outside labels on the chart void DrawPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Inside Bar pattern labels on the chart void DrawPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Pin Bar pattern labels on the chart void DrawPatternPinBar(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 const bool redraw=false); // Chart redraw flag //--- Draw Rails pattern labels on the chart void DrawPatternRails(const ENUM_TIMEFRAMES timeframe,const bool redraw=false); };
ここでは、ピンバーパターンを処理するメソッドにのみ入力します。残りのメソッドでは、新しいパターンのクラスを作成しながら追加していきます。
クラスのコンストラクタで、コンストラクタのパラメータで渡された外部リストへのポインタを、すべてのパターンのリストへのポインタに代入します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CTimeSeriesDE::CTimeSeriesDE(CArrayObj *list_all_patterns,const string symbol) : m_symbol(symbol) { this.m_type=OBJECT_DE_TYPE_SERIES_SYMBOL; this.m_list_series.Clear(); this.m_list_series.Sort(); this.SetTerminalServerDate(); this.m_new_tick.SetSymbol(this.m_symbol); this.m_new_tick.Refresh(); this.m_list_all_patterns=list_all_patterns; }
リスト内の時間枠のインデックスを返すメソッドは、インデックスを検索するために一時オブジェクトを使用します。新しい時系列オブジェクトを作成する際には、外部リストへのポインタを渡す必要があります。実際のリストへのポインタの代わりに、ここでは空のリストオブジェクトへのポインタを渡しています。これは一時的なオブジェクトであり、その後削除されるからです(この動作は後で修正する必要があります。新しいオブジェクトを常に作成して削除するのではなく、グローバルプールに一時的なオブジェクトを作成し、NULLを割り当ててインスタンスとして使用する必要があります。)
//+------------------------------------------------------------------+ //| Return the timeframe index in the list | //+------------------------------------------------------------------+ int CTimeSeriesDE::IndexTimeframe(const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=NULL; const CSeriesDE *obj=new CSeriesDE(list,this.m_symbol,(timeframe==PERIOD_CURRENT ? (ENUM_TIMEFRAMES)::Period() : timeframe)); if(obj==NULL) return WRONG_VALUE; this.m_list_series.Sort(); int index=this.m_list_series.Search(obj); delete obj; return index; }
指定した時系列リストをリストに追加するメソッドのコンストラクタに、パターンリストへのポインタを渡します。
//+------------------------------------------------------------------+ //| Add the specified timeseries list to the list | //+------------------------------------------------------------------+ bool CTimeSeriesDE::AddSeries(const ENUM_TIMEFRAMES timeframe,const uint required=0) { bool res=false; CSeriesDE *series=new CSeriesDE(this.m_list_all_patterns,this.m_symbol,timeframe,required); if(series==NULL) return res; this.m_list_series.Sort(); if(this.m_list_series.Search(series)==WRONG_VALUE) res=this.m_list_series.Add(series); series.SetAvailable(true); if(!res) delete series; return res; }
クラスリストの一番最後に、パターンを処理するために宣言されたメソッドを実装します。
//+------------------------------------------------------------------+ //| Handling timeseries patterns | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for setting the pattern use flag | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Set the flag of using the Harami pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternHarami(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Harami Cross pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternHaramiCross(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Tweezer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternTweezer(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Piercing Line pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternPiercingLine(flag); } //+------------------------------------------------------------------+ //|Set the flag of using the Cloud Cover pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternDarkCloudCover(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three White Soldiers pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternThreeWhiteSoldiers(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three Black Crows pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternThreeBlackCrows(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Shooting Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternShootingStar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Hammer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternHammer(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Inverted Hammer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternInvertedHammer(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Hanging Man pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternHangingMan(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternDoji(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Dragonfly Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternDragonflyDoji(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Gravestone Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternGravestoneDoji(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Morning Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternMorningStar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Morning Doji Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternMorningDojiStar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Evening Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternEveningStar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Evening Doji Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternEveningDojiStar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three Stars pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternThreeStars(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Abandoned Baby pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternAbandonedBaby(flag); } //--- Price Action //+------------------------------------------------------------------+ //| Set the flag of using the Pivot Point Reversal pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternPivotPointReversal(flag); } //+------------------------------------------------------------------+ //|Set the flag of using the Pattern Outside | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternOutsideBar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Inside Bar pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternInsideBar(flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Pin Bar pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternPinBar(const ENUM_TIMEFRAMES timeframe, const bool flag, // Price Action Pin Bar usage 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.SetUsedPatternPinBar(flag,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //+------------------------------------------------------------------+ //| Set the flag of using the Rails pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesDE::SetUsedPatternRails(const ENUM_TIMEFRAMES timeframe,const bool flag) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.SetUsedPatternRails(flag); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //+------------------------------------------------------------------+ //| Return the flag of using the Harami pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternHarami(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternHarami() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Harami Cross pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternHaramiCross(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternHaramiCross() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Tweezer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternTweezer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternTweezer() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Piercing Line pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternPiercingLine(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternPiercingLine() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Cloud Cover pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternDarkCloudCover() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three White Soldiers pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternThreeWhiteSoldiers() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three Black Crows pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternThreeBlackCrows() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Shooting Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternShootingStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternShootingStar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Hammer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternHammer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternHammer() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Inverted Hammer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternInvertedHammer() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Hanging Man pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternHangingMan(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternHangingMan() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternDoji() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Dragonfly Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternDragonflyDoji() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Gravestone Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternGravestoneDoji() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Morning Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternMorningStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternMorningStar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Morning Doji Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternMorningDojiStar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Evening Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternEveningStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternEveningStar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Evening Doji Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternEveningDojiStar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three Stars pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternThreeStars(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternThreeStars() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Abandoned Baby pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternAbandonedBaby() : false); } //--- Price Action //+------------------------------------------------------------------+ //| Return the flag of using the Pivot Point Reversal pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternPivotPointReversal() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Pattern Outside | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternOutsideBar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternOutsideBar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Inside Bar pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternInsideBar(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternInsideBar() : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Pin Bar pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternPinBar(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.IsUsedPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Rails pattern | //+------------------------------------------------------------------+ bool CTimeSeriesDE::IsUsedPatternRails(const ENUM_TIMEFRAMES timeframe) { CSeriesDE *series=this.GetSeries(timeframe); return(series!=NULL ? series.IsUsedPatternRails() : false); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Draw Harami pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternHarami(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternHarami(redraw); } //+------------------------------------------------------------------+ //| Draw Harami Cross pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternHaramiCross(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternHaramiCross(redraw); } //+------------------------------------------------------------------+ //| Draw Tweezer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternTweezer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternTweezer(redraw); } //+------------------------------------------------------------------+ //| Draw Piercing Line pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternPiercingLine(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternPiercingLine(redraw); } //+------------------------------------------------------------------+ //| Draw Dark Cloud Cover pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternDarkCloudCover(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternDarkCloudCover(redraw); } //+------------------------------------------------------------------+ //| Draw Three White Soldiers pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternThreeWhiteSoldiers(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternThreeWhiteSoldiers(redraw); } //+------------------------------------------------------------------+ //| Draw Three Black Crows pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternThreeBlackCrows(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternThreeBlackCrows(redraw); } //+------------------------------------------------------------------+ //| Draw Shooting Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternShootingStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternShootingStar(redraw); } //+------------------------------------------------------------------+ //| Draw Hammer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternHammer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternHammer(redraw); } //+------------------------------------------------------------------+ //| Draw Inverted Hammer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternInvertedHammer(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternInvertedHammer(redraw); } //+------------------------------------------------------------------+ //| Draw Hanging Man pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternHangingMan(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternHangingMan(redraw); } //+------------------------------------------------------------------+ //| Draw Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternDoji(redraw); } //+------------------------------------------------------------------+ //| Draw Dragonfly Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternDragonflyDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternDragonflyDoji(redraw); } //+------------------------------------------------------------------+ //| Draw Gravestone Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternGravestoneDoji(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternGravestoneDoji(redraw); } //+------------------------------------------------------------------+ //| Draw Morning Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternMorningStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternMorningStar(redraw); } //+------------------------------------------------------------------+ //| Draw Morning Doji Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternMorningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternMorningDojiStar(redraw); } //+------------------------------------------------------------------+ //| Draw Evening Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternEveningStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternEveningStar(redraw); } //+------------------------------------------------------------------+ //| Draw Evening Doji Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternEveningDojiStar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternEveningDojiStar(redraw); } //+------------------------------------------------------------------+ //| Draw Three Stars pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternThreeStars(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternThreeStars(redraw); } //+------------------------------------------------------------------+ //| Draw Abandoned Baby pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternAbandonedBaby(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternAbandonedBaby(redraw); } //--- Price Action //+------------------------------------------------------------------+ //| Draw Pivot Point Reversal pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternPivotPointReversal(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternPivotPointReversal(redraw); } //+------------------------------------------------------------------+ //| Draw Pattern Outside labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternOutsideBar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternOutsideBar(redraw); } //+------------------------------------------------------------------+ //| Draw Inside Bar pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternInsideBar(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternInsideBar(redraw); } //+------------------------------------------------------------------+ //| Draw Pin Bar pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternPinBar(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 const bool redraw=false) // Chart redraw flag { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternPinBar(ratio_body,ratio_larger_shadow,ratio_smaller_shadow,redraw); } //+------------------------------------------------------------------+ //| Draw Rails pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesDE::DrawPatternRails(const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CSeriesDE *series=this.GetSeries(timeframe); if(series!=NULL) series.DrawPatternRails(redraw); }
すべてのメソッドは同じです。まず、指定された時間枠で時系列のポインタを取得します。そして、対応するパターンを処理するためにそのメソッドを呼び出します。提示されたメソッドにおける入力は、完成したピンバーパターンに対してのみ示されています。その他のメソッドについては、新しいパターンのクラスを作成する際にパラメータを追加します。
ここで、ファイル\MQL5\Include\DoEasy\Collections\TimeSeriesCollection.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 //--- Return the timeseries index by symbol name int IndexTimeSeries(const string symbol); public: //--- Return (1) oneself, (2) the timeseries list and (3) the list of patterns CTimeSeriesCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } CArrayObj *GetListAllPatterns(void) { return &this.m_list_all_patterns; } //--- Return (1) the timeseries object of the specified symbol and (2) the timeseries object of the specified symbol/period CTimeSeriesDE *GetTimeseries(const string symbol); CSeriesDE *GetSeries(const string symbol,const ENUM_TIMEFRAMES timeframe);
publicセクションで、パターンを処理するメソッドを宣言します。
//--- Copy the specified double property of the specified timeseries of the specified symbol to the array //--- Regardless of the array indexing direction, copying is performed the same way as copying to a timeseries array bool CopyToBufferAsSeries(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_BAR_PROP_DOUBLE property, double &array[], const double empty=EMPTY_VALUE); //+------------------------------------------------------------------+ //| Handling timeseries patterns | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for setting the pattern use flag | //+------------------------------------------------------------------+ //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SetUsedPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SetUsedPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SetUsedPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SetUsedPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SetUsedPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SetUsedPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SetUsedPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SetUsedPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SetUsedPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SetUsedPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SetUsedPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SetUsedPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SetUsedPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SetUsedPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SetUsedPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SetUsedPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SetUsedPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SetUsedPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SetUsedPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SetUsedPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Price Action //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist void SetUsedPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SetUsedPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SetUsedPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SetUsedPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const bool flag, // Price Action Pin Bar usage 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 SetUsedPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag); //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //--- Return the flag of using the Harami pattern bool IsUsedPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Harami Cross pattern bool IsUsedPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Tweezer pattern bool IsUsedPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Piercing Line pattern bool IsUsedPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Cloud Cover pattern bool IsUsedPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three White Soldiers pattern bool IsUsedPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Black Crows pattern bool IsUsedPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Shooting Star pattern bool IsUsedPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hammer pattern bool IsUsedPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inverted Hammer pattern bool IsUsedPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Hanging Man pattern bool IsUsedPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Doji pattern bool IsUsedPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Dragonfly Doji pattern bool IsUsedPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Gravestone Doji pattern bool IsUsedPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Star pattern bool IsUsedPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Morning Doji Star pattern bool IsUsedPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Star pattern bool IsUsedPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Evening Doji Star pattern bool IsUsedPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Three Stars pattern bool IsUsedPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Abandoned Baby pattern bool IsUsedPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Price Action //--- Return the flag of using the Pivot Point Reversal pattern bool IsUsedPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pattern Outside bool IsUsedPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Inside Bar pattern bool IsUsedPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the flag of using the Pin Bar pattern bool IsUsedPatternPinBar(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 //--- Return the flag of using the Rails pattern bool IsUsedPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe); //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //--- Draw Harami pattern labels on the chart void DrawPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Harami Cross pattern labels on the chart void DrawPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Tweezer pattern labels on the chart void DrawPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Piercing Line pattern labels on the chart void DrawPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Dark Cloud Cover pattern labels on the chart void DrawPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three White Soldiers pattern labels on the chart void DrawPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three Black Crows pattern labels on the chart void DrawPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Shooting Star pattern labels on the chart void DrawPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Hammer pattern labels on the chart void DrawPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Inverted Hammer pattern labels on the chart void DrawPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Hanging Man pattern labels on the chart void DrawPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Doji pattern labels on the chart void DrawPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Dragonfly Doji pattern labels on the chart void DrawPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Gravestone Doji pattern labels on the chart void DrawPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Morning Star pattern labels on the chart void DrawPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Morning Doji Star pattern labels on the chart void DrawPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Evening Star pattern labels on the chart void DrawPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Evening Doji Star pattern labels on the chart void DrawPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Three Stars pattern labels on the chart void DrawPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Abandoned Baby pattern labels on the chart void DrawPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Price Action //--- Draw Pivot Point Reversal pattern labels on the chart void DrawPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Pattern Outside labels on the chart void DrawPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Inside Bar pattern labels on the chart void DrawPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Draw Pin Bar pattern labels on the chart void DrawPatternPinBar(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 const bool redraw=false); // Chart redraw flag //--- Draw Rails pattern labels on the chart void DrawPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false); //--- Constructor CTimeSeriesCollection(); };
クラスのコンストラクタで、すべてのパターンのリストをクリアし、リスト並び替えフラグを設定し、パターンリストのIDを代入します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CTimeSeriesCollection::CTimeSeriesCollection() { this.m_type=COLLECTION_SERIES_ID; this.m_list.Clear(); this.m_list.Sort(); this.m_list.Type(COLLECTION_SERIES_ID); this.m_list_all_patterns.Clear(); this.m_list_all_patterns.Sort(); this.m_list_all_patterns.Type(COLLECTION_SERIES_PATTERNS_ID); }
銘柄名で時系列インデックスを返すメソッドで、空のリストを作成し、そのポインタを作成する時系列のクラスコンストラクタに渡します。
//+------------------------------------------------------------------+ //| Return the timeseries index by symbol name | //+------------------------------------------------------------------+ int CTimeSeriesCollection::IndexTimeSeries(const string symbol) { CArrayObj *list=NULL; const CTimeSeriesDE *obj=new CTimeSeriesDE(list,symbol==NULL || symbol=="" ? ::Symbol() : symbol); if(obj==NULL) return WRONG_VALUE; this.m_list.Sort(); int index=this.m_list.Search(obj); delete obj; return index; }
銘柄時系列コレクションリストを作成するメソッドで、作成された時系列コンストラクタに、すべてのパターンのリストへのポインタを渡します。
//+------------------------------------------------------------------+ //| Create the symbol timeseries collection list | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::CreateCollection(const CArrayObj *list_symbols) { //--- If an empty list of symbol objects is passed, exit if(list_symbols==NULL) return false; //--- Get the number of symbol objects in the passed list int total=list_symbols.Total(); //--- Clear the timeseries collection list this.m_list.Clear(); //--- In a loop by all symbol objects for(int i=0;i<total;i++) { //--- get the next symbol object CSymbol *symbol_obj=list_symbols.At(i); //--- if failed to get a symbol object, move on to the next one in the list if(symbol_obj==NULL) continue; //--- Create a new timeseries object with the current symbol name CTimeSeriesDE *timeseries=new CTimeSeriesDE(this.GetListAllPatterns(),symbol_obj.Name()); //--- If failed to create the timeseries object, move on to the next symbol in the list if(timeseries==NULL) continue; //--- Set the sorted list flag for the timeseries collection list this.m_list.Sort(); //--- If the object with the same symbol name is already present in the timeseries collection list, remove the timeseries object if(this.m_list.Search(timeseries)>WRONG_VALUE) delete timeseries; //--- if failed to add the timeseries object to the collection list, remove the timeseries object else if(!this.m_list.Add(timeseries)) delete timeseries; } //--- Return the flag indicating that the created collection list has a size greater than zero return this.m_list.Total()>0; }
コードの最後に、パターンを処理するメソッドを実装します。
//+------------------------------------------------------------------+ //| Handling timeseries patterns | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for setting the pattern use flag | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Set the flag of using the Harami pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternHarami(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Harami Cross pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternHaramiCross(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Tweezer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternTweezer(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Piercing Line pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternPiercingLine(timeframe,flag); } //+------------------------------------------------------------------+ //|Set the flag of using the Cloud Cover pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternDarkCloudCover(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three White Soldiers pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternThreeWhiteSoldiers(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three Black Crows pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternThreeBlackCrows(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Shooting Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternShootingStar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Hammer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternHammer(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Inverted Hammer pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternInvertedHammer(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Hanging Man pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternHangingMan(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternDoji(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Dragonfly Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternDragonflyDoji(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Gravestone Doji pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternGravestoneDoji(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Morning Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternMorningStar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Morning Doji Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternMorningDojiStar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Evening Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternEveningStar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Evening Doji Star pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternEveningDojiStar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Three Stars pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternThreeStars(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Abandoned Baby pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternAbandonedBaby(timeframe,flag); } //--- Price Action //+------------------------------------------------------------------+ //| Set the flag of using the Pivot Point Reversal pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternPivotPointReversal(timeframe,flag); } //+------------------------------------------------------------------+ //|Set the flag of using the Pattern Outside | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternOutsideBar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Inside Bar pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternInsideBar(timeframe,flag); } //+------------------------------------------------------------------+ //| Set the flag of using the Pin Bar pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const bool flag, // Price Action Pin Bar usage 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.SetUsedPatternPinBar(timeframe,flag,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //+------------------------------------------------------------------+ //| Set the flag of using the Rails pattern | //| and create a control object if it does not exist yet | //+------------------------------------------------------------------+ void CTimeSeriesCollection::SetUsedPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.SetUsedPatternRails(timeframe,flag); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for returning the pattern usage flag | //+------------------------------------------------------------------+ //--- Candle formations //+------------------------------------------------------------------+ //| Return the flag of using the Harami pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternHarami(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Harami Cross pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternHaramiCross(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Tweezer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternTweezer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Piercing Line pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternPiercingLine(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Cloud Cover pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternDarkCloudCover(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three White Soldiers pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternThreeWhiteSoldiers(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three Black Crows pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternThreeBlackCrows(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Shooting Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternShootingStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Hammer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternHammer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Inverted Hammer pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternInvertedHammer(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Hanging Man pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternHangingMan(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Dragonfly Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternDragonflyDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Gravestone Doji pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternGravestoneDoji(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Morning Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternMorningStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Morning Doji Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternMorningDojiStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Evening Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternEveningStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Evening Doji Star pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternEveningDojiStar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Three Stars pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternThreeStars(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Abandoned Baby pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternAbandonedBaby(timeframe) : false); } //--- Price Action //+------------------------------------------------------------------+ //| Return the flag of using the Pivot Point Reversal pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternPivotPointReversal(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Pattern Outside | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternOutsideBar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Inside Bar pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternInsideBar(timeframe) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Pin Bar pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternPinBar(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.IsUsedPatternPinBar(timeframe,ratio_body,ratio_larger_shadow,ratio_smaller_shadow) : false); } //+------------------------------------------------------------------+ //| Return the flag of using the Rails pattern | //+------------------------------------------------------------------+ bool CTimeSeriesCollection::IsUsedPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); return(timeseries!=NULL ? timeseries.IsUsedPatternRails(timeframe) : false); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Methods for drawing patterns on a chart | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Draw Harami pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternHarami(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Harami Cross pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternHaramiCross(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Tweezer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternTweezer(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Piercing Line pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternPiercingLine(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Dark Cloud Cover pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternDarkCloudCover(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Three White Soldiers pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternThreeWhiteSoldiers(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Three Black Crows pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternThreeBlackCrows(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Shooting Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternShootingStar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Hammer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternHammer(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Inverted Hammer pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternInvertedHammer(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Hanging Man pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternHangingMan(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternDoji(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Dragonfly Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternDragonflyDoji(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Gravestone Doji pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternGravestoneDoji(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Morning Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternMorningStar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Morning Doji Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternMorningDojiStar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Evening Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternEveningStar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Evening Doji Star pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternEveningDojiStar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Three Stars pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternThreeStars(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Abandoned Baby pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternAbandonedBaby(timeframe,redraw); } //--- Price Action //+------------------------------------------------------------------+ //| Draw Pivot Point Reversal pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternPivotPointReversal(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Pattern Outside labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternOutsideBar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Inside Bar pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternInsideBar(timeframe,redraw); } //+------------------------------------------------------------------+ //| Draw Pin Bar pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternPinBar(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 const bool redraw=false) // Chart redraw flag { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternPinBar(timeframe,ratio_body,ratio_larger_shadow,ratio_smaller_shadow,redraw); } //+------------------------------------------------------------------+ //| Draw Rails pattern labels on the chart | //+------------------------------------------------------------------+ void CTimeSeriesCollection::DrawPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { CTimeSeriesDE *timeseries=this.GetTimeseries(symbol); if(timeseries!=NULL) timeseries.DrawPatternRails(timeframe,redraw); }
すべてのメソッドのロジックは単純で、時系列へのポインタを取得し、そのメソッドを使用して上記で作成したパターンを処理します。ピンバーパターンを処理するメソッドは完全に整っています。あとは、新しいパターンを作りながら最終決定します。
では、CEngineライブラリのメインクラスである、\MQL5\Include\DoEasy\Engine.mqhも同様に改造してみましょう。
時系列を扱うセクションに、時系列パターンを扱うメソッドを追加します。
//--- Copy the specified double property of the specified timeseries of the specified symbol to the array //--- Regardless of the array indexing direction, copying is performed the same way as copying to a timeseries array bool SeriesCopyToBufferAsSeries(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_BAR_PROP_DOUBLE property, double &array[],const double empty=EMPTY_VALUE) { return this.m_time_series.CopyToBufferAsSeries(symbol,timeframe,property,array,empty);} //--- Returns a complete list of patterns CArrayObj *GetListAllPatterns(void) { return this.m_time_series.GetListAllPatterns(); } //--- Return a list of patterns for the specified symbol and timeframe CArrayObj *GetListPatterns(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=CSelect::ByPatternProperty(this.GetListAllPatterns(),PATTERN_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByPatternProperty(list,PATTERN_PROP_PERIOD,timeframe,EQUAL); } //--- Return a list of specified patterns for the specified symbol and timeframe CArrayObj *GetListPatterns(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_PATTERN_TYPE type) { CArrayObj *list=this.GetListPatterns(symbol,timeframe); return CSelect::ByPatternProperty(list,PATTERN_PROP_TYPE,type,EQUAL); } //--- Return a list of patterns based on the specified bar opening time on a symbol and timeframe CArrayObj *GetListPatterns(const string symbol,const ENUM_TIMEFRAMES timeframe,const datetime time) { CArrayObj *list=this.GetListPatterns(symbol,timeframe); return CSelect::ByPatternProperty(list,PATTERN_PROP_TIME,time,EQUAL); } //--- Return a list of specified patterns based on the specified bar opening time on a symbol and timeframe CArrayObj *GetListPatterns(const string symbol,const ENUM_TIMEFRAMES timeframe,const datetime time,const ENUM_PATTERN_TYPE type) { CArrayObj *list=this.GetListPatterns(symbol,timeframe,time); return CSelect::ByPatternProperty(list,PATTERN_PROP_TYPE,type,EQUAL); } //--- Return a pointer to the specified pattern based on the opening time of the bar on the chart of the specified symbol and timeframe CPattern *GetPattern(const string symbol,const ENUM_TIMEFRAMES timeframe,const datetime time,const ENUM_PATTERN_TYPE type) { CArrayObj *list=this.GetListPatterns(symbol,timeframe,time,type); return(list!=NULL ? list.At(0) : NULL); } //--- Set the flag for using the Harami pattern and create a control object if it does not already exist void SeriesSetUsedPatternHarami(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternHarami(symbol,timeframe,flag); } //--- Set the flag for using the Harami Cross pattern and create a control object if it does not already exist void SeriesSetUsedPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternHaramiCross(symbol,timeframe,flag); } //--- Set the flag for using the Tweezer pattern and create a control object if it does not already exist void SeriesSetUsedPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternTweezer(symbol,timeframe,flag); } //--- Set the flag for using the Piercing Line pattern and create a control object if it does not already exist void SeriesSetUsedPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternPiercingLine(symbol,timeframe,flag); } //--- Set the flag for using the Cloud Cover pattern and create a control object if it does not already exist void SeriesSetUsedPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternDarkCloudCover(symbol,timeframe,flag); } //--- Set the flag for using the Three White Soldiers pattern and create a control object if it does not already exist void SeriesSetUsedPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternThreeWhiteSoldiers(symbol,timeframe,flag); } //--- Set the flag for using the Three Black Crows pattern and create a control object if it does not already exist void SeriesSetUsedPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternThreeBlackCrows(symbol,timeframe,flag); } //--- Set the flag for using the Shooting Star pattern and create a control object if it does not already exist void SeriesSetUsedPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternShootingStar(symbol,timeframe,flag); } //--- Set the flag for using the Hammer pattern and create a control object if it does not already exist void SeriesSetUsedPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternHammer(symbol,timeframe,flag); } //--- Set the flag for using the Inverted Hammer pattern and create a control object if it does not already exist void SeriesSetUsedPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternInvertedHammer(symbol,timeframe,flag); } //--- Set the flag for using the Hanging Man pattern and create a control object if it does not already exist void SeriesSetUsedPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternHangingMan(symbol,timeframe,flag); } //--- Set the flag for using the Doji pattern and create a control object if it does not already exist void SeriesSetUsedPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternDoji(symbol,timeframe,flag); } //--- Set the flag for using the Dragonfly Doji pattern and create a control object if it does not already exist void SeriesSetUsedPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternDragonflyDoji(symbol,timeframe,flag); } //--- Set the flag for using the Doji Gravestone pattern and create a control object if it does not already exist void SeriesSetUsedPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternGravestoneDoji(symbol,timeframe,flag); } //--- Set the flag for using the Morning Star pattern and create a control object if it does not already exist void SeriesSetUsedPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternMorningStar(symbol,timeframe,flag); } //--- Set the flag for using the Morning Doji Star pattern and create a control object if it does not already exist void SeriesSetUsedPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternMorningDojiStar(symbol,timeframe,flag); } //--- Set the flag for using the Evening Star pattern and create a control object if it does not already exist void SeriesSetUsedPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternEveningStar(symbol,timeframe,flag); } //--- Set the flag for using the Evening Doji Star pattern and create a control object if it does not already exist void SeriesSetUsedPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternEveningDojiStar(symbol,timeframe,flag); } //--- Set the flag for using the Three Stars pattern and create a control object if it does not already exist void SeriesSetUsedPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternThreeStars(symbol,timeframe,flag); } //--- Set the flag for using the Abandoned Baby pattern and create a control object if it does not already exist void SeriesSetUsedPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternAbandonedBaby(symbol,timeframe,flag); } //--- Price Action //--- Set the flag for using the Pivot Point Reversal pattern and create a control object if it does not already exist void SeriesSetUsedPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternPivotPointReversal(symbol,timeframe,flag); } //--- Set the flag for using the Pattern Outside and create a control object if it does not already exist void SeriesSetUsedPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternOutsideBar(symbol,timeframe,flag); } //--- Set the flag for using the Pattern Inside and create a control object if it does not already exist void SeriesSetUsedPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool flag) { this.m_time_series.SetUsedPatternInsideBar(symbol,timeframe,flag); } //--- Set the flag for using the Pin Bar pattern and create a control object if it does not already exist void SeriesSetUsedPatternPinBar(const string symbol,const ENUM_TIMEFRAMES timeframe, const bool flag, // Price Action Pin Bar usage 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.SetUsedPatternPinBar(symbol,timeframe,flag,ratio_body,ratio_larger_shadow,ratio_smaller_shadow); } //--- 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(symbol,timeframe,flag); } //--- 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(symbol,timeframe,redraw); } //--- Draw Harami Cross pattern labels on the chart void SeriesDrawPatternHaramiCross(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternHaramiCross(symbol,timeframe,redraw); } //--- Draw Tweezer pattern labels on the chart void SeriesDrawPatternTweezer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternTweezer(symbol,timeframe,redraw); } //--- Draw Piercing Line pattern labels on the chart void SeriesDrawPatternPiercingLine(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternPiercingLine(symbol,timeframe,redraw); } //--- Draw Dark Cloud Cover pattern labels on the chart void SeriesDrawPatternDarkCloudCover(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternDarkCloudCover(symbol,timeframe,redraw); } //--- Draw Three White Soldiers pattern labels on the chart void SeriesDrawPatternThreeWhiteSoldiers(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternThreeWhiteSoldiers(symbol,timeframe,redraw); } //--- Draw Three Black Crows pattern labels on the chart void SeriesDrawPatternThreeBlackCrows(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternThreeBlackCrows(symbol,timeframe,redraw); } //--- Draw Shooting Star pattern labels on the chart void SeriesDrawPatternShootingStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternShootingStar(symbol,timeframe,redraw); } //--- Draw Hammer pattern labels on the chart void SeriesDrawPatternHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternHammer(symbol,timeframe,redraw); } //--- Draw Inverted Hammer pattern labels on the chart void SeriesDrawPatternInvertedHammer(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternInvertedHammer(symbol,timeframe,redraw); } //--- Draw Hanging Man pattern labels on the chart void SeriesDrawPatternHangingMan(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternHangingMan(symbol,timeframe,redraw); } //--- Draw Doji pattern labels on the chart void SeriesDrawPatternDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternDoji(symbol,timeframe,redraw); } //--- Draw Dragonfly Doji pattern labels on the chart void SeriesDrawPatternDragonflyDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternDragonflyDoji(symbol,timeframe,redraw); } //--- Draw Gravestone Doji pattern labels on the chart void SeriesDrawPatternGravestoneDoji(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternGravestoneDoji(symbol,timeframe,redraw); } //--- Draw Morning Star pattern labels on the chart void SeriesDrawPatternMorningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternMorningStar(symbol,timeframe,redraw); } //--- Draw Morning Doji Star pattern labels on the chart void SeriesDrawPatternMorningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternMorningDojiStar(symbol,timeframe,redraw); } //--- Draw Evening Star pattern labels on the chart void SeriesDrawPatternEveningStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternEveningStar(symbol,timeframe,redraw); } //--- Draw Evening Doji Star pattern labels on the chart void SeriesDrawPatternEveningDojiStar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternEveningDojiStar(symbol,timeframe,redraw); } //--- Draw Three Stars pattern labels on the chart void SeriesDrawPatternThreeStars(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternThreeStars(symbol,timeframe,redraw); } //--- Draw Abandoned Baby pattern labels on the chart void SeriesDrawPatternAbandonedBaby(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternAbandonedBaby(symbol,timeframe,redraw); } //--- Price Action //--- Draw Pivot Point Reversal pattern labels on the chart void SeriesDrawPatternPivotPointReversal(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternPivotPointReversal(symbol,timeframe,redraw); } //--- Draw Pattern Outside labels on the chart void SeriesDrawPatternOutsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternOutsideBar(symbol,timeframe,redraw); } //--- Draw Inside Bar pattern labels on the chart void SeriesDrawPatternInsideBar(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternInsideBar(symbol,timeframe,redraw); } //--- Draw Pin Bar pattern labels on the chart void SeriesDrawPatternPinBar(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 const bool redraw=false) // Chart redraw flag { this.m_time_series.DrawPatternPinBar(symbol,timeframe,ratio_body,ratio_larger_shadow,ratio_smaller_shadow,redraw); if(redraw) ::ChartRedraw(); } //--- Draw Rails pattern labels on the chart void SeriesDrawPatternRails(const string symbol,const ENUM_TIMEFRAMES timeframe,const bool redraw=false) { this.m_time_series.DrawPatternRails(symbol,timeframe,redraw); } //--- Hide icons of all patterns void SeriesPatternHideAll(const bool redraw=false) { CArrayObj *list=this.GetListAllPatterns(); for(int i=list.Total()-1;i>=0;i--) { CPattern *obj=list.At(i); if(obj!=NULL) obj.Hide(); } if(redraw) ::ChartRedraw(); } //--- Hides the icons of all patterns except the specified one void SeriesPatternHideAllExceptOne(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.Hide(); } if(redraw) ::ChartRedraw(); } //--- Hide the info panels of all patterns void SeriesPatternHideAllInfoPanels(const bool redraw=false) { CArrayObj *list=this.GetListAllPatterns(); for(int i=list.Total()-1;i>=0;i--) { CPattern *obj=list.At(i); if(obj!=NULL) obj.HideInfoPanel(); } if(redraw) ::ChartRedraw(); } //--- 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(); } //--- Return (1) the tick series collection, (2) the list of tick series from the tick series collection CTickSeriesCollection *GetTickSeriesCollection(void) { return &this.m_tick_series; } CArrayObj *GetListTickSeries(void) { return this.m_tick_series.GetList(); }
ここでは、ピンバーパターンと、指定されたプロパティに基づくパターンオブジェクトのリストを扱うメソッドが完全に準備されています。新しいパターンを追加しながら、現在スタブの形になっているメソッドを徐々に洗練させていくつもりです。
新しいティックイベントハンドラで、ティックデータ更新を一時的にコメントアウトします。ティックの処理によってチャートが長期間フリーズすることがあるためです。ライブラリのコードのどこかに原因があるのか(以前はすべてうまくいっていました)、それとも端末のアップデートに関係しているのか、原因はまだはっきりしていません。
//+------------------------------------------------------------------+ //| NewTick event handler | //+------------------------------------------------------------------+ void CEngine::OnTick(SDataCalculate &data_calculate,const uint required=0) { //--- If this is not a EA, exit if(this.m_program_type!=PROGRAM_EXPERT) return; //--- Re-create empty timeseries and update the current symbol timeseries this.SeriesSync(data_calculate,required); this.SeriesRefresh(NULL,data_calculate); //--- Commented out because TickSeriesRefresh causes freezes - I will look into it later //this.TickSeriesRefresh(NULL); //--- end }
今は以上です。結果をテストしてみましょう。
検証
テストには「DoEasyライブラリの他のクラス(第72回):コレクションにおけるチャートオブジェクトパラメータの追跡と記録」のEAを使います。
新しい\MQL5\Experts\TestDoEasy\Part134\フォルダにTestDoEasyPart134.mq5として保存します。
入力では、パターンを検索するために使用されるローソク足の比率を追加し、現在の時間枠上でのみ作業を有効化し、市場の深さ、信号、チャートイベントの追跡の使用を無効化します:
//--- 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 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
OnInit()ハンドラで、パターンのリストを準備します。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Calling the function displays the list of enumeration constants in the journal //--- (the list is set in the strings 22 and 25 of the DELib.mqh file) for checking the constants validity //EnumNumbersTest(); //--- Set EA global variables prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_"; testing=engine.IsTester(); for(int i=0;i<TOTAL_BUTT;i++) { butt_data[i].name=prefix+EnumToString((ENUM_BUTTONS)i); butt_data[i].text=EnumToButtText((ENUM_BUTTONS)i); } lot=NormalizeLot(Symbol(),fmax(InpLots,MinimumLots(Symbol())*2.0)); magic_number=InpMagic; stoploss=InpStopLoss; takeprofit=InpTakeProfit; distance_pending=InpDistance; distance_stoplimit=InpDistanceSL; slippage=InpSlippage; trailing_stop=InpTrailingStop*Point(); trailing_step=InpTrailingStep*Point(); trailing_start=InpTrailingStart; stoploss_to_modify=InpStopLossModify; takeprofit_to_modify=InpTakeProfitModify; distance_pending_request=(InpDistancePReq<5 ? 5 : InpDistancePReq); bars_delay_pending_request=(InpBarsDelayPReq<1 ? 1 : InpBarsDelayPReq); g_point=SymbolInfoDouble(NULL,SYMBOL_POINT); g_digits=(int)SymbolInfoInteger(NULL,SYMBOL_DIGITS); //--- Initialize random group numbers group1=0; group2=0; srand(GetTickCount()); //--- Initialize DoEasy library OnInitDoEasy(); //--- Check and remove remaining EA graphical objects if(IsPresentObectByPrefix(prefix)) ObjectsDeleteAll(0,prefix); //--- Create the button panel if(!CreateButtons(InpButtShiftX,InpButtShiftY)) return INIT_FAILED; //--- Set trailing activation button status ButtonState(butt_data[TOTAL_BUTT-1].name,trailing_on); //--- Reset states of the buttons for working using pending requests for(int i=0;i<14;i++) { ButtonState(butt_data[i].name+"_PRICE",false); ButtonState(butt_data[i].name+"_TIME",false); } //--- Check playing a standard sound by macro substitution and a custom sound by description engine.PlaySoundByDescription(SND_OK); //--- Wait for 600 milliseconds engine.Pause(600); engine.PlaySoundByDescription(TextByLanguage("Звук упавшей монетки 2","Falling coin 2")); //--- Check the calculation of the cursor coordinates in the chart windows. //--- Allow the current chart to track mouse movement events if(engine.ChartGetMainChart()!=NULL) engine.ChartGetMainChart().SetEventMouseMoveON(); //--- 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); //--- Hide all pattern icons, if any engine.SeriesPatternHideAll(); //--- Hide all pattern info panels, if any engine.SeriesPatternHideAllInfoPanels(); //--- Display the pattern icons on the chart with the parameters specified in the settings engine.SeriesDrawPatternPinBar(NULL,PERIOD_CURRENT,InpPinBarRatioBody,InpPinBarRatioLarger,InpPinBarRatioSmaller,true); //--- return(INIT_SUCCEEDED); }
OnChartEvent()イベントハンドラで、チャートの変更イベントの処理を追加し、変更があれば現在アクティブな情報パネルが非表示になるようにします。また、パターンが見つかったローソク足の上にカーソルを置くと、チャート上にこれらのパネルを表示するようにするコードブロックを追加します。
//+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- If working in the tester, exit if(MQLInfoInteger(MQL_TESTER)) return; //--- Handling mouse events if(id==CHARTEVENT_OBJECT_CLICK) { //--- Handle pressing the buttons in the panel if(StringFind(sparam,"BUTT_")>0) PressButtonEvents(sparam); } //--- Handling DoEasy library events if(id>CHARTEVENT_CUSTOM-1) { OnDoEasyEvent(id,lparam,dparam,sparam); } //--- Chart change if(id==CHARTEVENT_CHART_CHANGE) { //--- Whenever the chart changes, hide all information panels engine.SeriesPatternHideAllInfoPanels(); return; } //--- 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,