/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // -------------------------------------- // Name: XPOIDrawer // Description: Provides Point of Interests // Drawing Tools ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Imports ... #include "../Classes/x-saherelm.base.class.mq5" #include "../Classes/x-saherelm.x-cobject.class.mq5" #include "../Libraries/x-saherelm.x-pivot.analysis.lib.mq5" #include "../Libraries/x-saherelm.x-poi.extensions.lib.mq5" // // Definitions ... // // Implementations ... class XCPOIDrawer : public XCBase { // public: // // Props ... // XPOIStyle defaultBullishStyle; XPOIStyle defaultBearishStyle; // XPOIStyle boxBullishStyle; XPOIStyle boxBearishStyle; // // Constructor ... void XCPOIDrawer() { // Default(); } // // Deconstructor ... void ~XCPOIDrawer() { // boxBullishStyle.Clean(); boxBearishStyle.Clean(); defaultBullishStyle.Clean(); defaultBearishStyle.Clean(); } // // Setter Getter (s) ... /** * Get Prefix ... * * @return ( string ) */ string Prefix() { return mPrefix; } /** * Set Prifx ... * * @param value: String ... */ void Prefix(string value) { mPrefix = value; } /** * Get Chart ID ... * * @return ( long ) */ long ChartIdentification() { return mChartIdentification; } /** * Set Chart ID ... * * @param value: Long ... */ void ChartIdentification(long value) { // if (value < 0) { value = 0; } // mChartIdentification = value; } /** * Get SubWindow Id ... * * @return ( int ) */ int SubWindowIdentification() { return mSubWindowIdentification; } /** * Set SubWindow Id ... * * @param value: Integer ... */ void SubWindowIdentification(int value) { // if (value < 0) { value = 0; } // mSubWindowIdentification = value; } // // Virtuals ... /** * Apply Default Configurations ... */ virtual void Default() { // // Apply Default Props ... // Prefix(NULL); ChartIdentification(0); SubWindowIdentification(0); // defaultBullishStyle.width = 1; defaultBullishStyle.clr = clrLime; defaultBullishStyle.style = STYLE_SOLID; // defaultBearishStyle.width = 1; defaultBearishStyle.clr = clrRed; defaultBearishStyle.style = STYLE_SOLID; // boxBullishStyle = defaultBullishStyle; boxBearishStyle = defaultBearishStyle; } // // Drawers ... /** * Draw Specified Bar ... * * @param bar: XOHCL, refrence to Specified Bar ... * @param object: XCOHCLObject, pointer reference for Drawn Object ... * @param to: datetime, Specified To Time ... * * @return ( bool ) */ bool DrawBar( XOHCL &bar, XCOHCLObject *&object, datetime to = NULL // ) { // bool result = false; // // Prepare ... object = NULL; // // Validate ... result = bar.IsValid(); if (!result) { return result; } // string prefix = Prefix(); ulong chartId = ChartIdentification(); int window = SubWindowIdentification(); to = IsSpecifiedValid(to) ? to : ((datetime)((int)bar.time) + (PeriodSeconds(bar.period) - 1)); object = new XCOHCLObject(); result = object.Create( chartId, window, bar, to, prefix // ); if (result) { // ApplyBarStyle( object, bar // ); } // return result; } /** * Draw Bar Arrow Object ... * * @param bar: XOHCL instance Reference ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param priceType: ENUM_X_PRICE member ... * @param arrow: int, Arrow Code ... * @param clr: color, Arro Color ... * @param width: int, Arrow Width ... * @param anchor: ENUM_ARROW_ANCHOR, anchor of Arrow ... * @param name: string, name of Arrow ... * * @return ( bool ) */ bool DrawBarArrow( XOHCL &bar, XCBarArrowObject *&object, ENUM_X_PRICE priceType, int arrow = 159, color clr = clrYellow, int width = 3, ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, string name = NULL, bool ignoreBarTag = true // ) { // bool result = false; // object = NULL; // result = bar.IsValid(); if (!result) { return result; } // string barTag = bar.GetTag(name); // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // prefix = (IsValid(prefix) ? prefix + "_" : prefix) + (IsSpecifiedValid(name) ? name : "") + (ignoreBarTag ? "" : ToMD5(barTag)); // object = new XCBarArrowObject(); result = object .CreateByBar( chartID, prefix, window, arrow, bar, priceType // ); if (result) { // object.ArrowColor(clr); object.ArrowWidth(width); object.ArrowAnchor(anchor); } // return result; } /** * Dar Specified Pivot ... * * @param pivot: XPivot, Specified Pivot ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param threshold: int, distance between price and arrow in Point ... * * @return ( bool ) */ bool DrawPivot( XPivot &pivot, XCBarArrowObject *&object, int peakArrow = 159, int valeArrow = 159, int threshold = 5 // ) { // bool result = false; // // Prepare ... object = NULL; // // Normalize ... threshold = NormalizeInt(threshold, 5); peakArrow = NormalizeInt(peakArrow, 159); valeArrow = NormalizeInt(valeArrow, 159); // // Validate ... result = pivot.IsValid(); if (!result) { return result; } // // Get Pivot's Bar ... XOHCL bar; result = pivot.GetBar(bar); if (!result) { return result; } // int arrow = pivot.IsPeak() ? peakArrow : valeArrow; string name = pivot.GetObjectID(); ENUM_X_PRICE type = pivot.IsPeak() ? X_PRICE_HIGH : X_PRICE_LOW; XPOIStyle style = pivot.IsPeak() ? defaultBearishStyle : defaultBullishStyle; ENUM_ARROW_ANCHOR anchor = pivot.IsPeak() ? ANCHOR_BOTTOM : ANCHOR_TOP; object = new XCBarArrowObject(); result = object.CreateByBar( ChartIdentification(), name, SubWindowIdentification(), arrow, bar, type, threshold // ); if (result) { // // Apply Styles ... object.ArrowAnchor(anchor); ApplyBarArrowStyle( object, style // ); } // // Cleanup Resources ... bar.Clean(); // return result; } /** * Draw Specified Pivot Collection ... * * @param pivots: XPivot, reference Collection to Draw ... * @param draws: CArrayObj, pointer reference to Hold Drawn Objects ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param threshold: int, distance between price and arrow in Point ... * * @return ( int ) */ int DrawPivots( XPivot &pivots[], CArrayObj *&draws, int peakArrow = 159, int valeArrow = 159, int threshold = 5 // ) { // int result = 0; // // Prepare ... if (draws == NULL) { draws = new CArrayObj(); } draws.Clear(); // // Validate ... if (!HasChild(pivots)) { return result; } // bool has = false; XCBarArrowObject *iObj; int count = ArraySize(pivots); for (int i = 0; i < count; i++) { // // Draw Indexed Pivot ... has = DrawPivot( pivots[i], iObj, peakArrow, valeArrow, threshold // ); // if (has) { draws.Add(iObj); } // ZeroMemory(iObj); } // result = draws.Total(); // return result; } /** * Draw Specified Box ... * * @param object: XCBoxObject, pointer reference for Drawn Object ... * @param name: Box Name ... * @param upper: double, Box Upper ... * @param lower: double, Box Lower ... * @param from: datetime, From Time ... * @param to: datetime, To Time ... * @param at: datetime, Specified At Time ... * * @return ( bool ) */ bool DrawBox( XCBoxObject *&object, string name, double upper, double lower, datetime from, datetime to, datetime at // ) { // bool result = false; // // Prepare ... object = NULL; // // Normalize ... to = NormalizeTime(to); from = NormalizeTime(from); // // Validate ... result = upper > 0 && lower > 0 && to > from && IsSpecifiedValid(to) && IsSpecifiedValid(name) && IsSpecifiedValid(from) && upper > lower; if (!result) { return result; } // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // object = new XCBoxObject(); result = object.Create( chartID, window, name, upper, lower, from, to, at, prefix // ); // return result; } /** * Draw Specific Box ... * * @param box: XBoxZone, Specified Box ... * @param object: XCBarArrowObject, pointer reference for Drawn Object ... * @param ignoreAt: bool, Ignore Box at or not ... * * @return ( bool ) */ bool DrawBox( XBoxZone &box, XCBoxObject *&object, bool ignoreAt = true // ) { // bool result = false; // // Prepare ... object = NULL; // // Validate ... result = box.IsValid(); if (!result) { return result; } // datetime at = box.at; if (ignoreAt) { at = NULL; } // string name = box.GetTag(); result = DrawBox( object, name, box.upper, box.lower, box.from, box.to, at // ); if (result) { // // Apply Style ... XPOIStyle style; GetBoxStyle( style, box.dir // ); // ApplyBoxStyle( object, style // ); // style.Clean(); } // return result; } /** * Draw a Collection of Boxes ... * * @param boxes: reference collection to Provide Boxes ... * @param objects: reference pointer to holds drawn Objects ... * @param ignoreAt: bool, ignore Box At Drawn ... * * @return ( int ) */ int DrawBoxes( XBoxZone &boxes[], CArrayObj *&objects, bool ignoreAt = true // ) { // int result = 0; // // Prepare ... objects = new CArrayObj(); // // Validate ... if (!HasChild(boxes)) { return result; } // bool has = false; XCBoxObject *iObj; int count = ArraySize(boxes); for (int i = 0; i < count; i++) { // has = DrawBox( boxes[i], iObj, ignoreAt // ); if (has) { objects.Add(iObj); } // ZeroMemory(iObj); } // result = objects.Total(); // return result; } /** * Draw Specified Signal ... * * @param signal: XSignal, Specified Signal ... * @param object: XCSignalObject, pointer reference for Drawn Object ... * @param length: int, Signal Length ... */ bool DrawSignal( XSignal &signal, XCSignalObject *&object, int length = 3 // ) { // bool result = false; // object = NULL; length = NormalizeInt(length, 3); // result = signal.IsValid(); if (!result) { return result; } // string prefix = Prefix(); long chartID = ChartIdentification(); int window = SubWindowIdentification(); // object = new XCSignalObject(); result = object.Create( chartID, window, signal, length, prefix // ); if (!result) { return result; } // object.TPWidth(1); object.TPColor(clrGreen); object.TPWidth(STYLE_DOT); // object.SLWidth(1); object.SLColor(clrRed); object.SLWidth(STYLE_DOT); // object.TargetWidth(1); object.TargetColor(clrLightBlue); object.TargetWidth(STYLE_DOT); // object.EntryWidth(1); object.EntryColor(clrYellow); object.EntryWidth(STYLE_DOT); // return result; } /** * Draw Specified Trend Line ... * * @param fromPrice: double, from Price ... * @param fromTime: datetime, from Time ... * @param toPrice: double, to Price ... * @param toTime: datetime, to Time ... * @param object: CChartObjectTrend, pointer reference for Drawn Object ... * @param name: Object Name ... * @param rayRight: bool, ray to Right ... * @param rayLeft: boo, ray to Left ... * * @return ( bool ) */ bool DrawTrendLine( double fromPrice, datetime fromTime, double toPrice, datetime toTime, CChartObjectTrend *&object, string name, bool rayRight = false, bool rayLeft = false // ) { // bool result = false; // // Prepare ... object = new CChartObjectTrend(); // // Validate ... result = toPrice > 0 && fromPrice > 0 && IsSpecifiedValid(toTime) && IsSpecifiedValid(fromTime) && toTime > fromTime; if (!result) { return result; } // // Create Object ... result = object.Create( ChartIdentification(), name, SubWindowIdentification(), fromTime, fromPrice, toTime, toPrice // ); if (result) { // ENUM_X_DIRECTION dir = fromPrice < toPrice ? X_DIRECTION_BULLISH : fromPrice > toPrice ? X_DIRECTION_BEARISH : X_DIRECTION_NONE; ApplyTrendLineStyle( object, dir // ); // object.RayLeft(rayLeft); object.RayRight(rayRight); } // return result; } /** * Draw Trend Line based on Swings Points ... * * @param swings: XOHCL, Specified Swings ... * @param dir: ENUM_X_DIRECTION, Specified Trend Direction ... * @param object: CChartObjectTrend, pointer reference for Drawn Object ... * @param rayRight: Ray to Right ... * @param rayLeft: Ray to Left ... * * @return ( bool ) */ bool DrawSwingTrend( XOHCL &swings[], ENUM_X_DIRECTION dir, CChartObjectTrend *&object, bool rayRight = false, bool rayLeft = false // ) { // bool result = false; // // Prepare ... object = NULL; // int count = ArraySize(swings); result = HasChild(swings) && count >= 2 && HasDirection(dir); if (!result) { return result; } // bool isBullish = IsSpecifiedBullish(dir); // XOHCL _swings[]; Copy( swings, _swings // ); SortBar( _swings, X_SORT_BY_DATE, X_DIRECTION_BULLISH // ); // double price1 = isBullish ? _swings[0].low : _swings[0].high; datetime time1 = _swings[0].time; // double price2 = isBullish ? _swings[count - 1].low : _swings[count - 1].high; datetime time2 = _swings[count - 1].time; // ulong chartId = ChartIdentification(); int subWindow = SubWindowIdentification(); string name = ToXString(dir) + "_Trend_" + ToXString(price1) + "_" + ToXString(price2); RemoveObjects("_Trend_", chartId, subWindow); // object = new CChartObjectTrend(); result = object.Create( chartId, name, subWindow, time1, price1, time2, price2 // ); if (result) { // ApplyTrendLineStyle( object, dir // ); // object.RayLeft(rayLeft); object.RayRight(rayRight); } // SpecifiedClean(_swings); // return result; } /** * Draw Pivot Analysis ... * * @param analysis: XPivotAnalysis, referece Specified Pivot Analysis ... * @param object: XCPivotAnalysisObject, pointer reference for Drawn Object ... * @param drawTrends: Specified to Draw Trends or not ... * @param drawZones: Specified to Draw Support and Resistance Zones or not ... * @param drawPivots: Specified to Draw Pivots or not ... * @param peakArrow: int, Specified Arrow Code for Peak Pivots ... * @param valeArrow: int, Specified Arrow Code for Vale Pivots ... * @param threshold: int, distance between price and arrow in Point ... * * @return ( bool ) */ bool DrawPivotAnalysis( XPivotAnalysis &analysis, XCPivotAnalysisObject *&object, bool drawTrends = true, bool drawZones = true, bool drawPivots = true, int peakArrow = 159, int valeArrow = 159, int threshold = 5 // ) { // bool result = false; // // Prepare ... object = NULL; // // Normalize ... // // Validate ... result = analysis.IsValid() && analysis.IsAnalysed(); if (!result) { return result; } // object = new XCPivotAnalysisObject(); result = object.Create( ChartIdentification(), SubWindowIdentification(), analysis, drawTrends, drawZones, drawPivots, peakArrow, valeArrow, threshold // ); if (result) { // ApplyPivotAnalysisStyle( object, analysis // ); } // return result; } // // Stylers ... /** * Get Specified Style for Specified Direction ... * * @param style: XPOIStyle, reference to hold result ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void GetStyle( XPOIStyle &style, ENUM_X_DIRECTION forDir // ) { // // Prepare ... style.Clean(); // // Validate ... if (!HasDirection(forDir)) { return; } // if (IsSpecifiedBullish(forDir)) { style = defaultBullishStyle; } else { style = defaultBearishStyle; } } /** * Get Specified Box Style for Specified Direction ... * * @param style: XPOIStyle, reference to hold result ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void GetBoxStyle( XPOIStyle &style, ENUM_X_DIRECTION forDir // ) { // // Prepare ... style.Clean(); // // Validate ... if (!HasDirection(forDir)) { return; } // if (IsSpecifiedBullish(forDir)) { style = boxBullishStyle; } else { style = boxBearishStyle; } } /** * Apply Specified Style to Specified Object ... * * @param object: XCBoxObject, pointer reference of Object ... * @param bar: XOHCL, Specified Bar ... * @param fill: boolean, Fill Bar's Body or not ... */ void ApplyBarStyle( XCOHCLObject *&object, XOHCL &bar, bool fill = false // ) { // // Validate ... bool has = bar.IsValid() && object != NULL; if (!has) { return; } // XPOIStyle style; GetStyle( style, bar.GetDirection() // ); // object.BarSpes( style.width, style.clr, style.style, fill // ); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: XCBoxObject, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBoxStyle( XCBoxObject *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.BoxFill(style.fill); object.BoxColor(style.clr); object.BoxWidth(style.width); object.BoxStyle(style.style); } /** * Apply Specified Style to a Collection on Drawn Boxes ... * * @param objects: pointer reference of Objects ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBoxesStyle( CArrayObj *&objects, XPOIStyle &style // ) { // // Validate ... if (objects == NULL || objects.Total() <= 0) { return; } // for (int i = 0; i < objects.Total(); i++) { // XCBoxObject *iObj = ((XCBoxObject *)objects.At(i)); ApplyBoxStyle( iObj, style // ); ZeroMemory(iObj); } } /** * Apply Specified Style to Specified Object ... * * @param object: XCBarArrowObject, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyBarArrowStyle( XCBarArrowObject *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.ArrowColor(style.clr); object.ArrowWidth(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectVLine, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyLineStyle( CChartObjectVLine *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.Color(style.clr); object.Style(style.style); object.Width(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectVLine, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyLineStyle( CChartObjectVLine *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // has = HasDirection(forDir); if (!has) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectHLine, pointer reference of Object ... * @param style: XPOIStyle, Specifed Style to Apply ... */ void ApplyLineStyle( CChartObjectHLine *&object, XPOIStyle &style // ) { // bool has = object != NULL; if (!has) { return; } // object.Color(style.clr); object.Style(style.style); object.Width(style.width); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectHLine, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyLineStyle( CChartObjectHLine *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // has = HasDirection(forDir); if (!has) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObjectTrend, pointer reference of Object ... * @param forDir: ENUM_X_DIRECTION, Specified Direction ... */ void ApplyTrendLineStyle( CChartObjectTrend *&object, ENUM_X_DIRECTION forDir // ) { // bool has = object != NULL; if (!has) { return; } // if (!HasDirection(forDir)) { return; } // XPOIStyle style; GetStyle(style, forDir); // object.Color(style.clr); object.Style(style.style); object.Width(style.width); // style.Clean(); } /** * Apply Specified Style to Specified Object ... * * @param object: CChartObject, pointer reference of Object ... * @param model: XPivotAnalysis, referece to access requirements ... */ void ApplyPivotAnalysisStyle( XCPivotAnalysisObject *&object, XPivotAnalysis &model // ) { // // Validate ... bool has = model.IsValid() && model.IsAnalysed() && object != NULL; if (!has) { return; } // XPOIStyle style; // // Support ... style = defaultBullishStyle; object.SupportColor(style.clr); object.SupportWidth(style.width); object.SupportStyle(style.style); // // Resistance ... style = defaultBearishStyle; object.ResistanceColor(style.clr); object.ResistanceWidth(style.width); object.ResistanceStyle(style.style); // // Upper ... if (model.IsPeakAnalysed()) { // GetStyle( style, model.peakDir // ); if (!HasDirection(model.peakDir)) { // style.Default(); style.clr = clrGray; } // object.UpperColor(style.clr); object.UpperWidth(style.width); object.UpperStyle(style.style); object.UpperRayLeft(false); object.UpperRayRight(true); } // // Lower ... if (model.IsValeAnalysed()) { // GetStyle( style, model.valeDir // ); if (!HasDirection(model.valeDir)) { // style.Default(); style.clr = clrGray; } // object.LowerColor(style.clr); object.LowerWidth(style.width); object.LowerStyle(style.style); object.UpperRayLeft(false); object.LowerRayRight(true); } // // Peak Pivots ... style = defaultBearishStyle; object.PeaksColor(style.clr); object.PeaksWidth(style.width); object.PeaksAnchor(ANCHOR_BOTTOM); // // Vale Pivots ... style = defaultBullishStyle; object.ValesColor(style.clr); object.ValesWidth(style.width); object.ValesAnchor(ANCHOR_TOP); // style.Clean(); } // protected: // // private: // // // Props ... // string mPrefix; // Prefix of Created Objects ... long mChartIdentification; // Chart Id ... int mSubWindowIdentification; // Sub Window ... // };