diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 4f7e8e4a..e401c6ed 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -1,119 +1,40 @@ { - "todo": [ - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-22T04:32:09.973Z", - "id": "94", - "references": [], - "title": "Implement 1 Min VWap Indicator for momentum change" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-22T04:33:34.181Z", - "id": "95", - "references": [], - "title": "implement strategy based on ichimoku" - } - ], + "todo": [], "in-progress": [], "testing": [ { "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2024-09-16T10:58:36.122Z", + "category": "Indicators", + "creation_time": "2025-04-24T03:00:57.022Z", "description": { - "content": "Complete Position Protector Tasks\n\n- [x] Hedge;\n- [x] Position Profit in Point;\n- [x] Protector Start;\n- [x] Same Signals Delay;\n- [x] Signal Protecting;", + "content": "there are some issues on BTCUSDT for Finding Peaks and Vales ...", "mime": "text/markdown" }, - "id": "89", - "references": [ - "90", - "91", - "92", - "93" - ], - "title": "Complete Position Protector" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-16T10:59:11.810Z", "details": { - "content": "BE Hedge Occures When a Position has Protected by Protecting Positions", + "content": "since some buffers use XOHCL instance Bar for Calculations \nthere are some situations which a Bar Initialization Faild ...\ni use last Values for these cases ...", "mime": "text/markdown" }, - "id": "91", + "id": "1", "references": [], - "title": "Implement BE Hedge Mechanism" + "title": "FIX XCA Indicator Issues on BTCUSDT ...", + "type": "bug" }, { "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2024-09-16T10:58:57.770Z", - "details": { - "content": "HE Hedge Occures when there is More than X Main Positions open and there isn't any Protecting Positions.", - "mime": "text/markdown" - }, - "id": "90", - "references": [], - "title": "Implement HE Hedge mechanism" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-16T13:08:56.494Z", - "id": "92", - "references": [], - "title": "Implement Protector Start Point" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-16T23:16:09.221Z", + "category": "XCAEA", + "creation_time": "2025-04-24T03:33:55.609Z", "description": { - "content": "- [x] Conditions for In Profit;\n- [x] Conditions for In DrawDown;", + "content": "we Have Daily Ticks and Volume Boxes ...", "mime": "text/markdown" }, - "id": "93", + "id": "2", "references": [], - "title": "Implement Signal Protecting Mechanism" + "title": "Add Support for Daily Max Volume and Ticks Box in XCAEA POI Detector ..." } ], - "done": [ - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-08-29T16:46:03.495Z", - "id": "87", - "references": [], - "title": "Require Assets", - "details": { - "content": "- [x] EURUSDb; GPC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] GBPUSDb; AMD PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURGBPb; i3 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDCHFb; iMac Slim 2 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURCHFb; HP i7 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDJPYb; iMac Slim 1 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURJPYb; Surface i7;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDCADb; HP i5 10;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURCADb; GPC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] AUDUSDb; iMac Slim 1;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n 4. [x] Level 4;\n- [x] EURAUDb; iMac Slim 2;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n 4. [x] Level 4;\n- [x] NZDUSDb; AMD PC\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURNZDb; HP i7 17;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] XAUUSDb; i3 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] XAGUSDb; GPC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] BRENT; HP i5 12;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] DOWEJONES3\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n", - "mime": "text/markdown" - } - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-09-08T10:04:18.986Z", - "details": { - "content": "- [x] EURUSDb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] GBPUSDb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURGBPb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDCHFb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURCHFb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDJPYb; iMac Slim 2;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURJPYb; iMac Slim 2;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] USDCADb; AMD PC\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURCADb; i3 PC;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] AUDUSDb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURAUDb; HP i7 17;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] NZDUSDb; HP i7 17;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] EURNZDb; iMac Slim 1;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] XAUUSDb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] XAGUSDb;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] BRENT;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n- [x] DOWEJONES3;\n 1. [x] Level 1;\n 2. [x] Level 2;\n 3. [x] Level 3;\n", - "mime": "text/markdown" - }, - "id": "88", - "references": [], - "title": "XCH.CHE V1.1" - } - ] + "done": [] } \ No newline at end of file diff --git a/Indicators/x-saherelm.x121.xca.mq5 b/Indicators/x-saherelm.x121.xca.mq5 index da87c6b2..ef775f50 100644 --- a/Indicators/x-saherelm.x121.xca.mq5 +++ b/Indicators/x-saherelm.x121.xca.mq5 @@ -1427,41 +1427,6 @@ void CalculateBuffers( low, tickVolume // ); - - // - int swingBarIndex = bar_index; - if (bar_index < swingLength) - { - swingBarIndex = bar_index + swingLength; - } - - // // - // // Calcultae Swing High and Low and Trends ... - // CalculateSwingsAndTrend( - // swingBarIndex, - // prevCalculated, - // ratesTotal, - // open, - // high, - // close, - // low, - // tickVolume // - // ); - - // - if (bar_index < swingLength) - { - // - // for (int i = bar_index; i < bar_index + swingLength; i++) - // { - // // - // trendBuffer[i] = lTrend; - // swingLowsBuffer[i] = lSwingLow; - // swingHighsBuffer[i] = lSwingHigh; - // trendStateBuffer[i] = lTrendState; - // trendColorBuffer[i] = lTrendColor; - // } - } } else { @@ -2002,6 +1967,11 @@ void CalculateValues( // // Calculate KI / Color ... + double lastKI = + isFirstBar + ? emptyValue + : kiBuffer[lastBarIndex]; + double iKI = lastKI; if (isInited) { // @@ -2009,46 +1979,78 @@ void CalculateValues( double iHHKI = iBar.FindHighest(kiLength, MODE_HIGH); // - double iKI = (iHHKI + iLLKI) / 2; - kiBuffer[bar_index] = iKI; - - // - double iKIState = neuturalState; - double iKIColor = neuturalColorIDX; - if (iClose > iKI) + iKI = (iHHKI + iLLKI) / 2; + if (iLLKI == 0 || iHHKI == 0) { - // - iKIState = bullishState; - iKIColor = - !showKI - ? hideColorIDX - : bullishColorIDX; + iKI = lastKI; } - else if (iClose < iKI) - { - // - iKIState = bearishState; - iKIColor = - !showKI - ? hideColorIDX - : bearishColorIDX; - } - kiStateBuffer[bar_index] = iKIState; - kiColorBuffer[bar_index] = iKIColor; } + else + { + iKI = lastKI; + } + kiBuffer[bar_index] = iKI; + + // + double iKIState = neuturalState; + double iKIColor = neuturalColorIDX; + if (iClose > iKI) + { + // + iKIState = bullishState; + iKIColor = + !showKI + ? hideColorIDX + : bullishColorIDX; + } + else if (iClose < iKI) + { + // + iKIState = bearishState; + iKIColor = + !showKI + ? hideColorIDX + : bearishColorIDX; + } + kiStateBuffer[bar_index] = iKIState; + kiColorBuffer[bar_index] = iKIColor; // // Calculate PV Gold ... + double lastPeakGold = + isFirstBar + ? emptyValue + : peakGoldenBuffer[lastBarIndex]; + double lastValeGold = + isFirstBar + ? emptyValue + : valeGoldenBuffer[lastBarIndex]; + double iPeakGold = lastPeakGold; + double iValeGold = lastValeGold; if (isInited) { // - double iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); - peakGoldenBuffer[bar_index] = iPeakGold; + iPeakGold = iBar.FindHighest(mHCLength, MODE_CLOSE); + if (iPeakGold == 0) + { + iPeakGold = lastPeakGold; + } // - double iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); - valeGoldenBuffer[bar_index] = iValeGold; + iValeGold = iBar.FindLowest(mHCLength, MODE_CLOSE); + if (iValeGold == 0) + { + iValeGold = lastValeGold; + } } + else + { + // + iPeakGold = lastPeakGold; + iValeGold = lastValeGold; + } + peakGoldenBuffer[bar_index] = iPeakGold; + valeGoldenBuffer[bar_index] = iValeGold; // // Calculate Swings ... diff --git a/Libraries/x-saherelm.x-poi.lib.mq5 b/Libraries/x-saherelm.x-poi.lib.mq5 index d2fc14cb..01de9cee 100644 --- a/Libraries/x-saherelm.x-poi.lib.mq5 +++ b/Libraries/x-saherelm.x-poi.lib.mq5 @@ -5017,6 +5017,194 @@ class XCTicksZone : public XCTwoBarZone return result; } + // + bool GetMaxTickZone(XCTickZone *&zone) + { + // + bool result = false; + + // + zone = NULL; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int count = Count(); + for (int i = 0; i < count; i++) + { + // + XCTickZone *iZone = GetZone(i); + + // + bool canSet = + zone == NULL + ? true + : zone.ticks < iZone.ticks + ? true + : false; + if (canSet) + { + zone = iZone; + } + + // + ZeroMemory(iZone); + } + + // + result = zone != NULL && + zone.IsValid(); + + // + return result; + } + + // + bool GetMinTickZone(XCTickZone *&zone) + { + // + bool result = false; + + // + zone = NULL; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int count = Count(); + for (int i = 0; i < count; i++) + { + // + XCTickZone *iZone = GetZone(i); + + // + bool canSet = + zone == NULL + ? true + : zone.ticks > iZone.ticks + ? true + : false; + if (canSet) + { + zone = iZone; + } + + // + ZeroMemory(iZone); + } + + // + result = zone != NULL && + zone.IsValid(); + + // + return result; + } + + // + bool GetMaxVolumeZone(XCTickZone *&zone) + { + // + bool result = false; + + // + zone = NULL; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int count = Count(); + for (int i = 0; i < count; i++) + { + // + XCTickZone *iZone = GetZone(i); + + // + bool canSet = + zone == NULL + ? true + : zone.volume < iZone.volume + ? true + : false; + if (canSet) + { + zone = iZone; + } + + // + ZeroMemory(iZone); + } + + // + result = zone != NULL && + zone.IsValid(); + + // + return result; + } + + // + bool GetMinVolumeZone(XCTickZone *&zone) + { + // + bool result = false; + + // + zone = NULL; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + int count = Count(); + for (int i = 0; i < count; i++) + { + // + XCTickZone *iZone = GetZone(i); + + // + bool canSet = + zone == NULL + ? true + : zone.volume > iZone.volume + ? true + : false; + if (canSet) + { + zone = iZone; + } + + // + ZeroMemory(iZone); + } + + // + result = zone != NULL && + zone.IsValid(); + + // + return result; + } + // protected: // @@ -5465,7 +5653,7 @@ struct XBoxZone // string typeStr = IsValid(type) - ? type + ? type : "XBOX"; string result = // diff --git a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 index 50bcebda..aa4eab5b 100644 --- a/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.detector.class.mq5 @@ -611,9 +611,25 @@ class XCXCAEAPOIDetector : public XCBase // // Pivot Verifications and Max Allowed Holding Items ... - int maxAllowedPivots; // Max Allowed Holding Pibots ... - int pivotVerifications; // Pivots Verifications ... - int pivotDetectionLoopbac; // Pivots Detection Loopback ... + int maxAllowedPivots; // Max Allowed Holding Pibots ... + int pivotVerifications; // Pivots Verifications ... + int pivotDetectionLoopbac; // Pivots Detection Loopback ... + double ticksDividerInPoints; // Ticks and Volume Detection Divider in Point ... + ENUM_TIMEFRAMES ticksDetectionPerid; // Ticks and Volume Detection Loopback ... + + // + // TICK Pivots ... + + // + bool detectTickPivots; + XBoxZone tickPivots[]; + + // + // VOLUME Pivots ... + + // + bool detectVolumePivots; + XBoxZone volumePivots[]; // // RSI Peak Pivot ... @@ -749,9 +765,13 @@ class XCXCAEAPOIDetector : public XCBase // maxAllowedPivots = 50; pivotVerifications = 5; + ticksDividerInPoints = 15; pivotDetectionLoopbac = 100; + ticksDetectionPerid = PERIOD_D1; // + detectTickPivots = true; + detectVolumePivots = true; detectRSIPeakPivots = true; detectRSIValePivots = true; detectCCIPeakPivots = true; @@ -1016,6 +1036,161 @@ class XCXCAEAPOIDetector : public XCBase // // Checking Pivots ... + // + // Detect TICK and VOLUME Pivots ... + if (detectTickPivots || detectVolumePivots) + { + // + XOHCL ticksToBar; + XOHCL ticksFromBar; + XCTicksZone *ticksZone = NULL; + + // + datetime ticksTo = GetPeriodStartTime( + zBar.symbol, + ticksDetectionPerid, + zBar.time // + ); + bool isTicksBarInited = ticksToBar.Init( + zBar.symbol, + zBar.period, + ticksTo // + ); + datetime ticksFrom = ticksTo - PeriodSeconds(ticksDetectionPerid); + isTicksBarInited = isTicksBarInited && + ticksFromBar.Init( + zBar.symbol, + zBar.period, + ticksFrom // + ); + bool hasValidTicksTimeRange = IsValid(ticksTo) && + isTicksBarInited && + IsValid(ticksFrom) && + ticksFrom < ticksTo; + + // + bool isTickPivotExists = + hasValidTicksTimeRange && + IsExistsTickPivot( + ticksTo, + ticksFrom // + ); + + // + bool isVolumePivotExists = + hasValidTicksTimeRange && + IsExistsVolumePivot( + ticksTo, + ticksFrom // + ); + + // + bool isInitializedZone = !isTickPivotExists || + !isVolumePivotExists; + if (isInitializedZone) + { + // + isInitializedZone = InitializeTicksZone( + ticksZone, + ticksToBar, + ticksFromBar // + ); + } + + // + // TICK Pivots ... + if (detectTickPivots) + { + // + // Check Current Zone Exists or Not ... + if (isInitializedZone && !isTickPivotExists) + { + // + XBoxZone iBox; + XCTickZone *iZone; + has = ticksZone.GetMaxTickZone(iZone); + if (has) + { + // + // Try to Converts a Tick Zone to XBoxZone ... + iBox.to = ticksTo; + iBox.from = ticksFrom; + iBox.lower = iZone.low; + iBox.upper = iZone.high; + iBox.symbol = iZone.symbol; + iBox.period = iZone.period; + iBox.type = "XCA_MAX_TICK"; + iBox.dir = X_DIRECTION_BULLISH; // Temparory ... + + // + has = iBox.IsValid(); + if (has) + { + // + AddBox( + iBox, + tickPivots // + ); + } + } + + // + iBox.Clean(); + ZeroMemory(iZone); + } + } + + // + // VOLUME Pivots ... + if (detectVolumePivots) + { + // + // Check Current Zone Exists or Not ... + if (isInitializedZone && !isVolumePivotExists) + { + // + XBoxZone iBox; + XCTickZone *iZone; + has = ticksZone.GetMaxVolumeZone(iZone); + if (has) + { + // + // Try to Converts a Tick Zone to XBoxZone ... + iBox.to = ticksTo; + iBox.from = ticksFrom; + iBox.lower = iZone.low; + iBox.upper = iZone.high; + iBox.symbol = iZone.symbol; + iBox.period = iZone.period; + iBox.type = "XCA_MAX_VOLUME"; + iBox.dir = X_DIRECTION_BULLISH; // Temparory ... + + // + has = iBox.IsValid(); + if (has) + { + // + AddBox( + iBox, + volumePivots // + ); + } + } + + // + iBox.Clean(); + ZeroMemory(iZone); + } + } + + // + ticksToBar.Clean(); + ticksFromBar.Clean(); + ZeroMemory(ticksZone); + + // + } + // // RSI Peak Pivot ... if (detectRSIPeakPivots) @@ -1755,6 +1930,28 @@ class XCXCAEAPOIDetector : public XCBase // // Implement Validation Senarios ... + // + // TICK Pivots ... + + // + // TODO: Complete this ... + has = HasTickPivots(); + if (has) + { + // + } + + // + // VOLUME Pivots ... + + // + // TODO: Complete this ... + has = HasVolumePivots(); + if (has) + { + // + } + // // RSI Peak Pivot ... @@ -2480,6 +2677,36 @@ class XCXCAEAPOIDetector : public XCBase // // Counters ... + // + // TICK Pivot ... + + // + bool HasTickPivots() + { + return HasChild(tickPivots); + } + + // + int CountTickPivots() + { + return ArraySize(tickPivots); + } + + // + // VOLUME Pivots ... + + // + bool HasVolumePivots() + { + return HasChild(volumePivots); + } + + // + int CountVolumePivots() + { + return ArraySize(volumePivots); + } + // // RSI Peak Pivot ... @@ -2896,6 +3123,8 @@ class XCXCAEAPOIDetector : public XCBase void CleanPivots() { // + Clean(tickPivots); + Clean(volumePivots); Clean(rsiPeakPivots); Clean(rsiValePivots); Clean(cciPeakPivots); @@ -2912,6 +3141,8 @@ class XCXCAEAPOIDetector : public XCBase void ReversePivots() { // + ArrayReverse(tickPivots); + ArrayReverse(volumePivots); ArrayReverse(rsiPeakPivots); ArrayReverse(rsiValePivots); ArrayReverse(cciPeakPivots); @@ -2925,6 +3156,169 @@ class XCXCAEAPOIDetector : public XCBase } // + + // + bool IsExistsTickPivot( + datetime to, + datetime from // + ) + { + // + bool result = false; + + // + // Validate Args ... + result = IsValid(to) && + IsValid(from) && + to > from; + if (!result) + { + return result; + } + + // + result = HasTickPivots(); + if (!result) + { + return result; + } + + // + int idx = -1; + int count = CountTickPivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = tickPivots[i]; + + // + result = iBox.to == to && + iBox.from == from; + if (result) + { + // + idx = i; + iBox.Clean(); + + // + break; + } + + // + iBox.Clean(); + } + + // + result = IsValidIndex(idx); + + // + return result; + } + + // + bool IsExistsVolumePivot( + datetime to, + datetime from // + ) + { + // + bool result = false; + + // + // Validate Args ... + result = IsValid(to) && + IsValid(from) && + to > from; + if (!result) + { + return result; + } + + // + result = HasVolumePivots(); + if (!result) + { + return result; + } + + // + int idx = -1; + int count = CountVolumePivots(); + for (int i = 0; i < count; i++) + { + // + XBoxZone iBox = volumePivots[i]; + + // + result = iBox.to == to && + iBox.from == from; + if (result) + { + // + idx = i; + iBox.Clean(); + + // + break; + } + + // + iBox.Clean(); + } + + // + result = IsValidIndex(idx); + + // + return result; + } + + // + bool InitializeTicksZone( + XCTicksZone *&zone, + XOHCL &toBar, + XOHCL &fromBar // + ) + { + // + bool result = false; + + // + result = zone == NULL; + if (!result) + { + return result; + } + + // + int toIDX = toBar.Index(); + int fromIDX = fromBar.Index(); + int rangeLength = fromIDX - toIDX; + double rangeDivider = ticksDividerInPoints * GetPoints(toBar.symbol); + double rangeL = toBar.FindLowest(rangeLength, MODE_LOW); + double rangeH = toBar.FindHighest(rangeLength, MODE_HIGH); + double rangeDiff = (rangeH - rangeL); + int zoneLevels = (int)(rangeDiff / rangeDivider); + + // + zone = new XCTicksZone(); + zone.Levels(zoneLevels); + + // + result = zone.Init( + fromBar, + toBar // + ); + if (!result) + { + ZeroMemory(zone); + } + + // + return result; + } + + // }; // \ No newline at end of file diff --git a/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 b/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 index 852e771a..c6955f60 100644 --- a/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 +++ b/XCAEA/Classes/xcaea.x-poi.drawer.class.mq5 @@ -43,6 +43,8 @@ class XCXCAEAPOIDrawer : public XCBase // // Drawers ... + bool drawTickPivots; + bool drawVolumePivots; bool drawRSIPeakPivots; bool drawRSIValePivots; bool drawCCIPeakPivots; @@ -62,6 +64,8 @@ class XCXCAEAPOIDrawer : public XCBase color defaultBearishColor; // + color tickPivotsColor; + color volumePivotsColor; color rsiPeakPivotsColor; color rsiValePivotsColor; color cciPeakPivotsColor; @@ -81,6 +85,8 @@ class XCXCAEAPOIDrawer : public XCBase int defaultBearishWidth; // + int tickPivotsWidth; + int volumePivotsWidth; int rsiPeakPivotsWidth; int rsiValePivotsWidth; int cciPeakPivotsWidth; @@ -100,6 +106,8 @@ class XCXCAEAPOIDrawer : public XCBase ENUM_LINE_STYLE defaultBearishStyle; // + ENUM_LINE_STYLE tickPivotsStyle; + ENUM_LINE_STYLE volumePivotsStyle; ENUM_LINE_STYLE rsiPeakPivotsStyle; ENUM_LINE_STYLE rsiValePivotsStyle; ENUM_LINE_STYLE cciPeakPivotsStyle; @@ -159,6 +167,8 @@ class XCXCAEAPOIDrawer : public XCBase ignoreUpdateOSCTos = true; // + drawTickPivots = false; + drawVolumePivots = false; drawRSIPeakPivots = false; drawRSIValePivots = false; drawCCIPeakPivots = false; @@ -174,6 +184,10 @@ class XCXCAEAPOIDrawer : public XCBase defaultBullishColor = clrLime; defaultBearishColor = clrRed; + // + tickPivotsColor = defaultBullishColor; + volumePivotsColor = defaultBearishColor; + // rsiValePivotsColor = defaultBullishColor; cciValePivotsColor = defaultBullishColor; @@ -192,6 +206,10 @@ class XCXCAEAPOIDrawer : public XCBase defaultBullishWidth = 1; defaultBearishWidth = 1; + // + tickPivotsWidth = defaultBullishWidth; + volumePivotsWidth = defaultBearishWidth; + // rsiValePivotsWidth = defaultBullishWidth; cciValePivotsWidth = defaultBullishWidth; @@ -210,6 +228,10 @@ class XCXCAEAPOIDrawer : public XCBase defaultBullishStyle = STYLE_SOLID; defaultBearishStyle = STYLE_SOLID; + // + tickPivotsStyle = defaultBullishStyle; + volumePivotsStyle = defaultBearishStyle; + // rsiValePivotsStyle = defaultBullishStyle; cciValePivotsStyle = defaultBullishStyle; @@ -229,6 +251,8 @@ class XCXCAEAPOIDrawer : public XCBase void Draw(datetime to = NULL) { // + DrawTickPivots(to); + DrawVolumePivots(to); DrawRSIPeakPivots(to); DrawRSIValePivots(to); DrawCCIPeakPivots(to); @@ -245,6 +269,8 @@ class XCXCAEAPOIDrawer : public XCBase void Clear() { // + mTickPivotObjects.Clear(); + mVolumePivotObjects.Clear(); mRSIPeakPivotObjects.Clear(); mRSIValePivotObjects.Clear(); mCCIPeakPivotObjects.Clear(); @@ -261,6 +287,116 @@ class XCXCAEAPOIDrawer : public XCBase // // + // + void DrawTickPivots(datetime to = NULL) + { + // + bool has = drawTickPivots; + if (!has) + { + return; + } + + // + has = detector.HasTickPivots(); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountTickPivots(); + for (int i = 0; i < count; i++) { + // + XBoxZone iBox = detector.tickPivots[i]; + + // + if (canUpdateTo) { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + if (has) { + // + // Style Pivot ... + iObj.BoxColor(tickPivotsColor); + iObj.BoxWidth(tickPivotsWidth); + iObj.BoxStyle(tickPivotsStyle); + + // + // Store Pivot ... + mTickPivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + + // + void DrawVolumePivots(datetime to = NULL) + { + // + bool has = drawVolumePivots; + if (!has) + { + return; + } + + // + has = detector.HasVolumePivots(); + if (!has) + { + return; + } + + // + bool canUpdateTo = IsValid(to); + + // + int count = detector.CountVolumePivots(); + for (int i = 0; i < count; i++) { + // + XBoxZone iBox = detector.volumePivots[i]; + + // + if (canUpdateTo) { + iBox.to = to; + } + + // + XCBoxObject *iObj; + has = drawer.DrawBox( + iBox, + iObj // + ); + if (has) { + // + // Style Pivot ... + iObj.BoxColor(volumePivotsColor); + iObj.BoxWidth(volumePivotsWidth); + iObj.BoxStyle(volumePivotsStyle); + + // + // Store Pivot ... + mVolumePivotObjects.Add(iObj); + } + + // + iBox.Clean(); + ZeroMemory(iObj); + } + } + // void DrawRSIPeakPivots(datetime to = NULL) { @@ -892,6 +1028,8 @@ class XCXCAEAPOIDrawer : public XCBase XCXCAEAPOIDetector *detector; // + CArrayObj mTickPivotObjects; + CArrayObj mVolumePivotObjects; CArrayObj mRSIPeakPivotObjects; CArrayObj mRSIValePivotObjects; CArrayObj mCCIPeakPivotObjects; diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/XCAEA/Signals/xcaea.signaller.class.mq5 index 8eb5647a..a27f29e8 100644 --- a/XCAEA/Signals/xcaea.signaller.class.mq5 +++ b/XCAEA/Signals/xcaea.signaller.class.mq5 @@ -728,12 +728,16 @@ class XCXCAEASignaller : XCBase detector = new XCXCAEAPOIDetector(helper); // - detector.maxAllowedPivots = 50; + detector.maxAllowedPivots = 50; detector.pivotVerifications = 5; + detector.ticksDividerInPoints = 15; detector.pivotDetectionLoopbac = 100; + detector.ticksDetectionPerid = PERIOD_D1; // // Configure Detector ... + detector.detectTickPivots = true; + detector.detectVolumePivots = true; detector.detectRSIPeakPivots = true; detector.detectRSIValePivots = true; detector.detectCCIPeakPivots = true; @@ -754,6 +758,8 @@ class XCXCAEASignaller : XCBase // // Configure Drawer ... + drawer.drawTickPivots = true; + drawer.drawVolumePivots = false; drawer.drawRSIPeakPivots = true; drawer.drawRSIValePivots = true; drawer.drawCCIPeakPivots = true; @@ -767,6 +773,8 @@ class XCXCAEASignaller : XCBase // // Configure Widths ... + drawer.tickPivotsWidth = 2; + drawer.volumePivotsWidth = 2; drawer.rsiPeakPivotsWidth = 4; drawer.rsiValePivotsWidth = 4; drawer.cciPeakPivotsWidth = 4; @@ -780,6 +788,8 @@ class XCXCAEASignaller : XCBase // // Configure Colors ... + drawer.tickPivotsColor = clrYellow; + drawer.volumePivotsColor = clrDodgerBlue; drawer.rsiPeakPivotsColor = clrMagenta; drawer.rsiValePivotsColor = clrAqua; drawer.cciPeakPivotsColor = clrMagenta; @@ -793,6 +803,8 @@ class XCXCAEASignaller : XCBase // // Configures Styles ... + drawer.tickPivotsStyle = STYLE_DOT; + drawer.volumePivotsStyle = STYLE_DOT; drawer.rsiPeakPivotsStyle = STYLE_DASH; drawer.rsiValePivotsStyle = STYLE_DASH; drawer.cciPeakPivotsStyle = STYLE_DASH;