diff --git a/Indicators/test-xpv.ind.mq5 b/Documents/BKP/test-xpv.ind.mq5 similarity index 76% rename from Indicators/test-xpv.ind.mq5 rename to Documents/BKP/test-xpv.ind.mq5 index 8328ff85..24cd2f7a 100644 --- a/Indicators/test-xpv.ind.mq5 +++ b/Documents/BKP/test-xpv.ind.mq5 @@ -391,7 +391,7 @@ void DefineBuffers() PlotIndexSetInteger(peakBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); // - PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetDouble(peakBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(peakBufferPlotIndex, PLOT_ARROW, peakArrowCode); // @@ -406,7 +406,7 @@ void DefineBuffers() PlotIndexSetInteger(valeBufferPlotIndex, PLOT_DRAW_TYPE, pvDrawType); // - PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetDouble(valeBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(valeBufferPlotIndex, PLOT_ARROW, valeArrowCode); // @@ -427,7 +427,7 @@ void DefineBuffers() PlotIndexSetInteger(highBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType); // - PlotIndexSetDouble(highBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetDouble(highBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(highBufferPlotIndex, PLOT_ARROW, highArrowCode); // @@ -442,7 +442,7 @@ void DefineBuffers() PlotIndexSetInteger(lowBufferPlotIndex, PLOT_DRAW_TYPE, hlDrawType); // - PlotIndexSetDouble(lowBufferPlotIndex, PLOT_EMPTY_VALUE, emptyValue); + PlotIndexSetDouble(lowBufferPlotIndex, PLOT_EMPTY_VALUE, EMPTY_VALUE); PlotIndexSetInteger(lowBufferPlotIndex, PLOT_ARROW, lowArrowCode); // @@ -450,11 +450,11 @@ void DefineBuffers() // ArraySetAsSeries(lowRawBuffer, true); - SetIndexBuffer(lowRawBufferIndex, lowRawBuffer, INDICATOR_DATA); + SetIndexBuffer(lowRawBufferIndex, lowRawBuffer, INDICATOR_CALCULATIONS); // ArraySetAsSeries(highRawBuffer, true); - SetIndexBuffer(highRawBufferIndex, highRawBuffer, INDICATOR_DATA); + SetIndexBuffer(highRawBufferIndex, highRawBuffer, INDICATOR_CALCULATIONS); } /** @@ -582,6 +582,9 @@ void CalculateValues( // // Common Requirements ... + // + FillBuffersZero(barIndex); + // int lastBarIndex = barIndex + 1; int maxBarIndex = startCalculationForLastBars > 0 @@ -596,95 +599,167 @@ void CalculateValues( // // Calculate Highs and Lows ... - double iLow = IsLow(barIndex); - double iHigh = IsHigh(barIndex); -} - -// -// Calculator Functions ... - -bool IsLow( - double &value, - int barIndex // -) { - // - bool result = false; - - // - // Prepare ... - value = emptyValue; - - // XOHCL iBar; - result = iBar.Init( + bool has = iBar.Init( _Symbol, _Period, barIndex // ); - if (!result) { - // - iBar.Clean(); - return result; + if (!has) + { + return; } // - value = iBar.FindXLowest(pvValidationLength, peakPriceType); - result = value >= iBar.low; - if (!result) { - // - iBar.Clean(); - value = emptyValue; - return result; - } - - // - // Cleanup Resources ... - iBar.Clean(); - - // - return result; -} - -bool IsHigh( - double &value, - int barIndex // -) { - // - bool result = false; - - // - // Prepare ... - value = emptyValue; - - // - XOHCL iBar; - result = iBar.Init( - _Symbol, - _Period, - barIndex // + int lowestIDX = -1; + double iRawLow = iBar.FindLowest( + lowestIDX, + pvValidationLength, + valePriceType // ); - if (!result) { + + // + int highestIDX = -1; + double iRawHigh = iBar.FindHighest( + highestIDX, + pvValidationLength, + peakPriceType // + ); + + // + lowRawBuffer[barIndex] = iRawLow; + highRawBuffer[barIndex] = iRawHigh; + + // + lowBuffer[barIndex] = iRawLow; + highBuffer[barIndex] = iRawHigh; + + // + if (barIndex < firstBarIndex - (pvValidationLength + 1)) + { // - iBar.Clean(); - return result; + double tmp[]; + ArrayCopy( + tmp, + lowRawBuffer, + 0, + barIndex, + pvValidationLength // + ); + double minLow = GetMin(tmp); + bool isLow = iRawLow < minLow; + lowBuffer[barIndex] = + isLow + ? iRawLow + : lowBuffer[lastBarIndex]; + + // + XClean(tmp); + ArrayCopy( + tmp, + highRawBuffer, + 0, + barIndex, + pvValidationLength // + ); + double maxHigh = GetMax(tmp); + bool isHigh = iRawHigh > maxHigh; + highBuffer[barIndex] = + isHigh + ? iRawHigh + : highBuffer[lastBarIndex]; + + // + // Cleanup Resources ... + XClean(tmp); } - // - value = iBar.FindXHighest(pvValidationLength, valePriceType); - result = value <= iBar.high; - if (!result) { - // - iBar.Clean(); - value = emptyValue; - return result; - } + // // + // double iLow = emptyValue; + // // IsLow(iLow, barIndex); + // double iPLow = isFirstBar + // ? iLow + // : lowRawBuffer[lastBarIndex]; - // - // Cleanup Resources ... - iBar.Clean(); + // // + // double iHigh = emptyValue; + // IsHigh(iHigh, barIndex); + // double iPHigh = isFirstBar + // ? iHigh + // : highRawBuffer[lastBarIndex]; - // - return result; + // // + // // Clculate Values ... + + // // + // lowRawBuffer[barIndex] = iLow; + // highRawBuffer[barIndex] = iHigh; + + // // + // lowBuffer[barIndex] = NotEmptyZero(iLow) + // ? iLow + // : iPLow; + // highBuffer[barIndex] = NotEmptyZero(iHigh) + // ? iHigh + // : iPHigh; + + // // + // double iP2Low = + // barIndex < maxBarIndex - 2 + // ? lowBuffer[barIndex + 2] + // : emptyValue; + // double iP2High = + // barIndex < maxBarIndex - 2 + // ? highBuffer[barIndex + 2] + // : emptyValue; + + // // + // double mLowValues[]; + // double iVale = emptyValue; + // if (NotEmptyZero(iPLow)) + // { + // Add(iPLow, mLowValues); + // } + // if (NotEmptyZero(iP2Low)) + // { + // Add(iP2Low, mLowValues); + // } + // bool isVale = iLow <= GetMin(mLowValues); + // iVale = isVale + // ? iLow + // : isFirstBar + // ? emptyValue + // : valeBuffer[lastBarIndex]; + // valeBuffer[barIndex] = iVale; + + // // + // double mHighValues[]; + // double iPeak = emptyValue; + // if (NotEmptyZero(iPHigh)) + // { + // Add(iPHigh, mHighValues); + // } + // if (NotEmptyZero(iP2High)) + // { + // Add(iP2High, mHighValues); + // } + // bool isPeak = iHigh >= GetMax(mHighValues); + // iPeak = isPeak + // ? iHigh + // : isFirstBar + // ? emptyValue + // : peakBuffer[lastBarIndex]; + // peakBuffer[barIndex] = iPeak; + + // // + // bool has = + // NotEmptyZero(iLow) || + // NotEmptyZero(iPLow) || + // NotEmptyZero(iHigh) || + // NotEmptyZero(iPHigh); + // if (has) + // { + // } } // \ No newline at end of file diff --git a/Libraries/x-saherelm.x-ohcl.lib.mq5 b/Libraries/x-saherelm.x-ohcl.lib.mq5 index a2ab693d..a3477d42 100644 --- a/Libraries/x-saherelm.x-ohcl.lib.mq5 +++ b/Libraries/x-saherelm.x-ohcl.lib.mq5 @@ -1214,6 +1214,81 @@ struct XOHCL return result; } + /** + * Detect Highest of Specified Price type in Market ... + * + * @param index: souble, reference to hold detected Value Bar index ... + * @param mLength: int, Specified Loopback Length ... + * @param mPriceType: ENUM_X_PRICE, Specified Price type to Detect ... + * + * @return ( double ) + */ + double FindHighest( + int &index, // Index ... + int mLength, // Loopback ... + ENUM_X_PRICE mPriceType // Price Type ... + ) + { + // + double result = EMPTY_VALUE; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + mLength = NormalizeInt(mLength, 1); + + // + // Validate ... + bool has = IsValid() && + IsXValid(mPriceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int start = Index(); + int end = start + mLength; + double iValue = EMPTY_VALUE; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + has = BarAt(i, iBar); + if (!has) + { + continue; + } + + // + // Calculate Price ... + iValue = iBar.GetPrice(mPriceType); + + // + // Compare Price With Prev Detected ... + has = !NotEmptyZero(result) + ? true + : iValue > result; + if (has) + { + // + index = i; + result = iValue; + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + + // + return result; + } + // // Find Highest ... double FindHighestUp( @@ -1316,6 +1391,81 @@ struct XOHCL return result; } + /** + * Detect Lowest of Specified Price type in Market ... + * + * @param index: souble, reference to hold detected Value Bar index ... + * @param mLength: int, Specified Loopback Length ... + * @param mPriceType: ENUM_X_PRICE, Specified Price type to Detect ... + * + * @return ( double ) + */ + double FindLowest( + int &index, // Index ... + int mLength, // Loopback ... + ENUM_X_PRICE mPriceType // Price Type ... + ) + { + // + double result = EMPTY_VALUE; + + // + // Prepare ... + index = -1; + + // + // Normalize ... + mLength = NormalizeInt(mLength, 1); + + // + // Validate ... + bool has = IsValid() && + IsXValid(mPriceType); + if (!has) + { + return result; + } + + // + XOHCL iBar; + int start = Index(); + int end = start + mLength; + double iValue = EMPTY_VALUE; + for (int i = start; i < end; i++) + { + // + iBar.Clean(); + has = BarAt(i, iBar); + if (!has) + { + continue; + } + + // + // Calculate Price ... + iValue = iBar.GetPrice(mPriceType); + + // + // Compare Price With Prev Detected ... + has = !NotEmptyZero(result) + ? true + : iValue < result; + if (has) + { + // + index = i; + result = iValue; + } + } + + // + // Cleanup Resources ... + iBar.Clean(); + + // + return result; + } + // // Find Lowest ... double FindLowesttDown( diff --git a/MQL5.code-workspace b/MQL5.code-workspace index 04efa605..19d29201 100644 --- a/MQL5.code-workspace +++ b/MQL5.code-workspace @@ -13,7 +13,8 @@ "C_Cpp.clang_format_style": "{ BasedOnStyle: Microsoft, UseTab: Never, IndentWidth: 4, TabWidth: 4, ColumnLimit: 0}", "files.associations": { "*.mq5": "cpp", - "*.mqh": "cpp" + "*.mqh": "cpp", + "*.ex5": "cpp" } } }