From 827697dae73495e90c83130de4fed3f0ba771db1 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 11 Jul 2024 08:31:23 +0330 Subject: [PATCH] last works on adding threshold to pivots ... --- Documents/BKP/Templates/trend.detector.mq5 | 562 +++++++ Experts/x-test.ea.mq5 | 150 +- Libraries/x-saherelm.tools.mq5 | 1766 +++++++++----------- 3 files changed, 1401 insertions(+), 1077 deletions(-) create mode 100644 Documents/BKP/Templates/trend.detector.mq5 diff --git a/Documents/BKP/Templates/trend.detector.mq5 b/Documents/BKP/Templates/trend.detector.mq5 new file mode 100644 index 00000000..95db2b5a --- /dev/null +++ b/Documents/BKP/Templates/trend.detector.mq5 @@ -0,0 +1,562 @@ + +// +// Detect Trends ... +struct XTrendDetector +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double higherHighs[]; + datetime higherHighTimes[]; + + // + double higherLows[]; + datetime higherLowTimes[]; + + // + double lowerHighs[]; + datetime lowerHighTimes[]; + + // + double lowerLows[]; + datetime lowerLowTimes[]; + + // + bool isFirstLow; + + // + bool isUpTrend; + bool isDownTrend; + + // + int _numberOfPivots; + int _pivotShoulders; + + // + // Constructor ... + XTrendDetector() + { + Clean(); + } + + // + bool FindTrend( + string _symbol, + ENUM_TIMEFRAMES _period, + int barIndex = 0, + int _requiredPivots = 3, + int _requiredShoulders = 3 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (_requiredPivots < 3) + { + _requiredPivots = 3; + } + + // + if (_requiredShoulders < 3) + { + _requiredShoulders = 3; + } + + // + result = + // + IsValid(_symbol) && + IsValid(_period) + // + ; + if (!result) + { + return result; + } + + // + // Find Swing Lows and Swing Highs ... + + // + int hhIndexes[]; + datetime hhTimes[]; + double hhs[]; + + // + int llIndexes[]; + datetime llTimes[]; + double lls[]; + + // + bool isEnough = false; + + // + double lastHH = 0; + int lastHHIndex = barIndex; + datetime lastHHTime = NULL; + + // + double lastLL = 0; + int lastLLIndex = barIndex; + datetime lastLLTime = NULL; + + // + // Calculate First ... + lastHHIndex = FindSwing( + _symbol, + _period, + X_SWING_HIGH, + _requiredShoulders, + lastHHIndex + 1 // + ); + if (lastHHIndex >= 0) + { + // + XOHCL lastBar; + bool isInited = lastBar.Init( + _symbol, + _period, + lastHHIndex // + ); + if (isInited) + { + // + lastHH = lastBar.high; + lastHHTime = lastBar.time; + } + } + + // + lastLLIndex = FindSwing( + _symbol, + _period, + X_SWING_LOW, + _requiredShoulders, + lastLLIndex + 1 // + ); + if (lastLLIndex >= 0) + { + // + XOHCL lastBar; + bool isInited = lastBar.Init( + _symbol, + _period, + lastLLIndex // + ); + if (isInited) + { + // + lastHH = lastBar.high; + lastHHTime = lastBar.time; + } + } + + // + result = + // + lastLLIndex >= 0 && + lastHHIndex >= 0 + // + ; + if (!result) + { + return result; + } + + // + bool isFirstLow = + // + lastLLIndex < lastHHIndex + // + ; + + // + + + // + while (!isEnough) + { + // + int hhSize = ArraySize(hhs); + if (hhSize < _requiredPivots) + { + // + } + + // + int llSize = ArraySize(lls); + if (llSize < _requiredPivots * 2) + { + } + + // + } + + // while (!isEnough) + // { + // // + // int hhSize = ArraySize(hhs); + // if (hhSize < _requiredPivots * 2) + // { + // // + // lastHHIndex = FindSwing( + // _symbol, + // _period, + // X_SWING_HIGH, + // _requiredShoulders, + // lastHHIndex + 1 // + // ); + // if (lastHHIndex >= 0) + // { + // // + // XOHCL hBar; + // bool isInited = hBar.Init( + // _symbol, + // _period, + // lastHHIndex // + // ); + // if (isInited) + // { + // // + // Add( + // hBar.high, + // hhs // + // ); + + // // + // Add( + // hBar.time, + // hhTimes // + // ); + + // // + // Add( + // lastHHIndex, + // hhIndexes // + // ); + // } + // } + // } + + // // + // int llSize = ArraySize(lls); + // if (llSize < _requiredPivots * 2) + // { + // // + // lastLLIndex = FindSwing( + // _symbol, + // _period, + // X_SWING_LOW, + // _requiredShoulders, + // lastLLIndex + 1 // + // ); + // if (lastLLIndex >= 0) + // { + // // + // XOHCL lBar; + // bool isInited = lBar.Init( + // _symbol, + // _period, + // lastLLIndex // + // ); + // if (isInited) + // { + // // + // Add( + // lBar.low, + // lls // + // ); + + // // + // Add( + // lBar.time, + // llTimes // + // ); + + // // + // Add( + // lastHHIndex, + // llIndexes // + // ); + // } + // } + // } + + // // + // hhSize = ArraySize(hhs); + // llSize = ArraySize(lls); + // isEnough = + // // + // hhSize == _requiredPivots * 2 && + // llSize == _requiredPivots * 2 + // // + // ; + // } + + // // + // ArrayReverse(hhs); + // ArrayReverse(hhTimes); + // ArrayReverse(hhIndexes); + + // // + // ArrayReverse(lls); + // ArrayReverse(llTimes); + // ArrayReverse(llIndexes); + + // + // Draws ... + for (int i = 0; i < ArraySize(hhs); i++) + { + // + DrawArrow( + ChartID(), + "XTRND_HH" + ToString(i), + 0, + hhTimes[i], + hhs[i], + 234, + ANCHOR_BOTTOM, + clrMagenta, + STYLE_SOLID, + 3 // + ); + + // + DrawArrow( + ChartID(), + "XTRND_LL" + ToString(i), + 0, + llTimes[i], + lls[i], + 233, + ANCHOR_TOP, + clrAqua, + STYLE_SOLID, + 3 // + ); + } + + // // + // // Here We Try to Detect Trands ... + // int idxHH = 0; + // int idxLL = 0; + // isEnough = false; + // isFirstLow = llTimes[0] > hhTimes[0]; + // while(!isEnough) { + // // + // datetime firstTime = NULL; + // if (isFirstLow) { + // // + // firstTime = llTimes[0]; + + // // + // // Looking for a High ... + + // // + // if (hhs[hhIdx] > lls[llIdx]) { + + // } + // } else { + // // + // firstTime = hhTimes[0]; + + // // + // // Looking for a Low ... + // } + // } + + // + isUpTrend = + // + isFirstLow + ? + // + lls[0] > lls[1] && + lls[1] > lls[2] && + // + hhs[0] > hhs[1] && + hhs[1] > hhs[2] + // + : + // + hhs[0] > hhs[1] && + hhs[1] > hhs[2] && + // + lls[0] > lls[1] && + lls[1] > lls[2] + // + ; + isDownTrend = + // + isFirstLow + ? + // + lls[0] < lls[1] && + lls[1] < lls[2] && + // + hhs[0] < hhs[1] && + hhs[1] < hhs[2] + // + : + // + hhs[0] < hhs[1] && + hhs[1] < hhs[2] && + // + lls[0] < lls[1] && + lls[1] < lls[2] + // + ; + for (int i = 1; i < _requiredPivots; i++) + { + // + // Lows ... + + // + // Lower Lows ... + if (lls[i - 1] < lls[i]) + { + // + Add( + lls[i - 1], + lowerLows // + ); + + // + Add( + llTimes[i - 1], + lowerLowTimes // + ); + } + else + // + // Higher Lows ... + if (lls[i - 1] > lls[i]) + { + // + Add( + lls[i - 1], + higherLows // + ); + + // + Add( + llTimes[i - 1], + higherLowTimes // + ); + } + + // + // Highs ... + + // + // Higher Highs ... + if (hhs[i - 1] > hhs[i]) + { + // + Add( + hhs[i - 1], + higherHighs // + ); + + // + Add( + hhTimes[i - 1], + higherHighTimes // + ); + } + else + // + // Lower Highs ... + if (hhs[i - 1] < hhs[i]) + { + // + Add( + hhs[i - 1], + lowerHighs // + ); + + // + Add( + hhTimes[i - 1], + lowerHighTimes // + ); + } + } + + // + // Remove Draws ... + RemoveDraws("XTRND"); + + // + symbol = _symbol; + period = _period; + _numberOfPivots = _requiredPivots; + _pivotShoulders = _requiredShoulders; + + // + result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + period = NULL; + + // + _numberOfPivots = 0; + _pivotShoulders = 0; + + // + Clean(higherHighs); + Clean(higherHighTimes); + + // + Clean(higherLows); + Clean(higherLowTimes); + + // + Clean(lowerHighs); + Clean(lowerHighTimes); + + // + Clean(lowerLows); + Clean(lowerLowTimes); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } +}; diff --git a/Experts/x-test.ea.mq5 b/Experts/x-test.ea.mq5 index 71556725..697b722d 100644 --- a/Experts/x-test.ea.mq5 +++ b/Experts/x-test.ea.mq5 @@ -60,8 +60,8 @@ XPivot lastResistancePivot; // // For Zone Checking ... -XZone lastSupportZone; -XZone lastResistanceZone; +// XZone lastSupportZone; +// XZone lastResistanceZone; // XTrendDetector trendDetector; @@ -151,7 +151,7 @@ void OnTick() // // Check Pivots ... - // HandleCheckPivots(); + HandleCheckPivots(); // // Check Zones ... @@ -163,7 +163,7 @@ void OnTick() // // Check Trend State ... - HandleCheckTrend(); + // HandleCheckTrend(); } // @@ -413,8 +413,6 @@ void HandleCheckPivots() ); if (!isInited) { - // - lastResistancePivot.Clean(); return; } @@ -424,6 +422,26 @@ void HandleCheckPivots() { Print("Valid Resistance ..."); } + } else { + // + bool isBreaked = lastResistancePivot.IsBreaked(); + bool isRejected = lastResistancePivot.IsRejected(); + + // + if (isBreaked) + { + // + // lastResistancePivot.Clean(); + Print("Resistance Breaked ..."); + } + + // + if (isRejected) + { + // + // lastResistancePivot.Clean(); + Print("Resistance Rejected ..."); + } } // @@ -437,8 +455,6 @@ void HandleCheckPivots() ); if (!isInited) { - // - lastSupportPivot.Clean(); return; } @@ -459,7 +475,7 @@ void HandleCheckPivots() if (isBreaked) { // - lastSupportPivot.Clean(); + // lastSupportPivot.Clean(); Print("Support Breaked ..."); } @@ -467,7 +483,7 @@ void HandleCheckPivots() if (isRejected) { // - lastSupportPivot.Clean(); + // lastSupportPivot.Clean(); Print("Support Rejected ..."); } } @@ -476,58 +492,58 @@ void HandleCheckPivots() // void HandleCheckZones() { - // - bool result = false; + // // + // bool result = false; - // - // Find Last Support Zone ... - if (!lastSupportZone.IsValid()) - { - // - result = lastSupportZone.FindLastSupportZone( - _Symbol, - _Period // - ); - if (!result) - { - return; - } + // // + // // Find Last Support Zone ... + // if (!lastSupportZone.IsValid()) + // { + // // + // result = lastSupportZone.FindLastSupportZone( + // _Symbol, + // _Period // + // ); + // if (!result) + // { + // return; + // } - // - result = lastSupportZone.Draw(ChartID()); - if (result) - { - Print("Valid Support Zone ..."); - } - } - else - { - } + // // + // result = lastSupportZone.Draw(ChartID()); + // if (result) + // { + // Print("Valid Support Zone ..."); + // } + // } + // else + // { + // } - // - // Find Last Resistance Zone ... - if (!lastResistanceZone.IsValid()) - { - // - result = lastResistanceZone.FindLastResistanceZone( - _Symbol, - _Period // - ); - if (!result) - { - return; - } + // // + // // Find Last Resistance Zone ... + // if (!lastResistanceZone.IsValid()) + // { + // // + // result = lastResistanceZone.FindLastResistanceZone( + // _Symbol, + // _Period // + // ); + // if (!result) + // { + // return; + // } - // - result = lastResistanceZone.Draw(ChartID()); - if (result) - { - Print("Valid Resistance Zone ..."); - } - } - else - { - } + // // + // result = lastResistanceZone.Draw(ChartID()); + // if (result) + // { + // Print("Valid Resistance Zone ..."); + // } + // } + // else + // { + // } } // @@ -573,10 +589,20 @@ void HandleCheckTimeTracker() void HandleCheckTrend() { // - bool hasTren = trendDetector.FindTrend( - _Symbol, - _Period // - ); + bool hasTrend = trendDetector.HasTrend(); + if (!hasTrend) + { + // + bool trendFound = trendDetector.FindTrend( + _Symbol, + _Period // + ); + } + else + { + // + Print("Has Trend: " + (trendDetector.isUpTrend ? "Bullish" : "Bearish")); + } } // diff --git a/Libraries/x-saherelm.tools.mq5 b/Libraries/x-saherelm.tools.mq5 index bebdfefa..7a3c7123 100644 --- a/Libraries/x-saherelm.tools.mq5 +++ b/Libraries/x-saherelm.tools.mq5 @@ -27,6 +27,460 @@ // // Definitions ... +// +// Detect Trends ... +struct XTrendDetector +{ + // + string symbol; + ENUM_TIMEFRAMES period; + + // + double higherHighs[]; + datetime higherHighTimes[]; + + // + double higherLows[]; + datetime higherLowTimes[]; + + // + double lowerHighs[]; + datetime lowerHighTimes[]; + + // + double lowerLows[]; + datetime lowerLowTimes[]; + + // + bool isFirstLow; + + // + bool isUpTrend; + bool isDownTrend; + + // + int _numberOfPivots; + int _pivotShoulders; + + // + // Constructor ... + XTrendDetector() + { + Clean(); + } + + // + bool FindTrend( + string _symbol, + ENUM_TIMEFRAMES _period, + int barIndex = 0, + int _requiredPivots = 3, + int _requiredShoulders = 3 // + ) + { + // + bool result = false; + + // + Clean(); + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + if (_requiredPivots < 3) + { + _requiredPivots = 3; + } + + // + if (_requiredShoulders < 3) + { + _requiredShoulders = 3; + } + + // + result = + // + IsValid(_symbol) && + IsValid(_period) + // + ; + if (!result) + { + Clean(); + return result; + } + + // + // Find Swing Lows and Swing Highs ... + + // + int hhIndexes[]; + datetime hhTimes[]; + double hhs[]; + + // + int llIndexes[]; + datetime llTimes[]; + double lls[]; + + // + bool isEnough = false; + + // + int lastHHIndex = barIndex; + int lastLLIndex = barIndex; + while (!isEnough) + { + // + int hhSize = ArraySize(hhs); + if (hhSize < _requiredPivots) + { + // + lastHHIndex = FindSwing( + _symbol, + _period, + X_SWING_HIGH, + _requiredShoulders, + lastHHIndex + 1 // + ); + if (lastHHIndex >= 0) + { + // + XOHCL hBar; + bool isInited = hBar.Init( + _symbol, + _period, + lastHHIndex // + ); + if (isInited) + { + // + Add( + hBar.high, + hhs // + ); + + // + Add( + hBar.time, + hhTimes // + ); + + // + Add( + lastHHIndex, + hhIndexes // + ); + } + } + } + + // + int llSize = ArraySize(lls); + if (llSize < _requiredPivots) + { + // + lastLLIndex = FindSwing( + _symbol, + _period, + X_SWING_LOW, + _requiredShoulders, + lastLLIndex + 1 // + ); + if (lastLLIndex >= 0) + { + // + XOHCL lBar; + bool isInited = lBar.Init( + _symbol, + _period, + lastLLIndex // + ); + if (isInited) + { + // + Add( + lBar.low, + lls // + ); + + // + Add( + lBar.time, + llTimes // + ); + + // + Add( + lastHHIndex, + llIndexes // + ); + } + } + } + + // + hhSize = ArraySize(hhs); + llSize = ArraySize(lls); + isEnough = + // + hhSize == _requiredPivots && + llSize == _requiredPivots + // + ; + } + + // + // Draws ... + // for (int i = 0; i < ArraySize(hhs); i++) + // { + // // + // DrawArrow( + // ChartID(), + // "XTRND_HH" + ToString(i), + // 0, + // hhTimes[i], + // hhs[i], + // 234, + // ANCHOR_BOTTOM, + // clrMagenta, + // STYLE_SOLID, + // 3 // + // ); + + // // + // DrawArrow( + // ChartID(), + // "XTRND_LL" + ToString(i), + // 0, + // llTimes[i], + // lls[i], + // 233, + // ANCHOR_TOP, + // clrAqua, + // STYLE_SOLID, + // 3 // + // ); + // } + + // + isUpTrend = + // + isFirstLow + ? + // + lls[0] > lls[1] && + lls[1] > lls[2] && + // + hhs[0] > hhs[1] && + hhs[1] > hhs[2] + // + : + // + hhs[0] > hhs[1] && + hhs[1] > hhs[2] && + // + lls[0] > lls[1] && + lls[1] > lls[2] + // + ; + isDownTrend = + // + isFirstLow + ? + // + lls[0] < lls[1] && + lls[1] < lls[2] && + // + hhs[0] < hhs[1] && + hhs[1] < hhs[2] + // + : + // + hhs[0] < hhs[1] && + hhs[1] < hhs[2] && + // + lls[0] < lls[1] && + lls[1] < lls[2] + // + ; + for (int i = 1; i < _requiredPivots; i++) + { + // + // Lows ... + + // + // Lower Lows ... + if (lls[i - 1] < lls[i]) + { + // + Add( + lls[i - 1], + lowerLows // + ); + + // + Add( + llTimes[i - 1], + lowerLowTimes // + ); + } + else + // + // Higher Lows ... + if (lls[i - 1] > lls[i]) + { + // + Add( + lls[i - 1], + higherLows // + ); + + // + Add( + llTimes[i - 1], + higherLowTimes // + ); + } + + // + // Highs ... + + // + // Higher Highs ... + if (hhs[i - 1] > hhs[i]) + { + // + Add( + hhs[i - 1], + higherHighs // + ); + + // + Add( + hhTimes[i - 1], + higherHighTimes // + ); + } + else + // + // Lower Highs ... + if (hhs[i - 1] < hhs[i]) + { + // + Add( + hhs[i - 1], + lowerHighs // + ); + + // + Add( + hhTimes[i - 1], + lowerHighTimes // + ); + } + } + + // + // Remove Draws ... + // RemoveDraws("XTRND"); + + // + result = isUpTrend || isDownTrend; + if (!result) + { + Clean(); + } + + // + symbol = _symbol; + period = _period; + _numberOfPivots = _requiredPivots; + _pivotShoulders = _requiredShoulders; + + // + result = IsValid(); + if (!result) + { + Clean(); + } + + // + return result; + } + + // + bool HasTrend() + { + // + bool result = isUpTrend || isDownTrend; + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + period = NULL; + + // + isUpTrend = false; + isFirstLow = false; + isDownTrend = false; + + // + _numberOfPivots = 0; + _pivotShoulders = 0; + + // + Clean(higherHighs); + Clean(higherHighTimes); + + // + Clean(higherLows); + Clean(higherLowTimes); + + // + Clean(lowerHighs); + Clean(lowerHighTimes); + + // + Clean(lowerLows); + Clean(lowerLowTimes); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } +}; + // // a Pivot Point ... struct XPivot @@ -56,7 +510,8 @@ struct XPivot datetime resistanceTime; // - int _lastCalculatedBar; + double _threshold; // threshold in Point ... + int _lastCalculatedBar; // last calculated bars ... int _loopbackForSupportAndResistance; // Number of LoopBacks for Support or Resistance ... // @@ -66,66 +521,6 @@ struct XPivot Clean(); } - // - // Initialization ... - bool Init( - string _symbol, - ENUM_TIMEFRAMES _period, - double _price, - int barIndex = 0, - int _supResVerificationsStep = 21 // - ) - { - // - bool result = false; - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - if (_supResVerificationsStep < 0) - { - _supResVerificationsStep = 21; - } - - // - result = - // - _price > 0 && - IsValid(_symbol) && - IsValid(_period) && - IsValidSize(_supResVerificationsStep) - // - ; - - if (!result) - { - return result; - } - - // - symbol = _symbol; - period = _period; - price = _price; - - // - _loopbackForSupportAndResistance = _supResVerificationsStep; - - // - Calculate( - barIndex // - ); - - // - result = IsValid(); - - // - return result; - } - // // Find Last Support for Market and // Initialize Pivot Based On it ... @@ -133,18 +528,28 @@ struct XPivot string _symbol, ENUM_TIMEFRAMES _period, int barIndex = 0, - int _supResVerificationsStep = 21 // + int _supResVerificationsStep = 21, + double __threshold = 5 // ) { // bool result = false; + // + Clean(); + // if (barIndex < 0) { barIndex = 0; } + // + if (__threshold < 0) + { + __threshold = 0; + } + // if (_supResVerificationsStep < 0) { @@ -162,6 +567,8 @@ struct XPivot if (!result) { + // + Clean(); return result; } @@ -178,6 +585,8 @@ struct XPivot ); if (!result) { + // + Clean(); return result; } @@ -231,18 +640,18 @@ struct XPivot } // - result = Init( - _symbol, - _period, - llBar.low, + symbol = _symbol; + period = _period; + price = llBar.low; + + // + _threshold = __threshold; + _loopbackForSupportAndResistance = _supResVerificationsStep; + + // + Calculate( barIndex // ); - if (!result) - { - // - Clean(); - continue; - } // result = isSupport; @@ -256,6 +665,10 @@ struct XPivot // result = IsValid() && isSupport; + if (!result) + { + Clean(); + } // return result; @@ -268,18 +681,28 @@ struct XPivot string _symbol, ENUM_TIMEFRAMES _period, int barIndex = 0, - int _supResVerificationsStep = 21 // + int _supResVerificationsStep = 21, + double __threshold = 5 // ) { // bool result = false; + // + Clean(); + // if (barIndex < 0) { barIndex = 0; } + // + if (__threshold < 0) + { + __threshold = 0; + } + // if (_supResVerificationsStep < 0) { @@ -297,6 +720,8 @@ struct XPivot if (!result) { + // + Clean(); return result; } @@ -313,6 +738,8 @@ struct XPivot ); if (!result) { + // + Clean(); return result; } @@ -366,18 +793,18 @@ struct XPivot } // - result = Init( - _symbol, - _period, - hhBar.high, + symbol = _symbol; + period = _period; + price = hhBar.high; + + // + _threshold = __threshold; + _loopbackForSupportAndResistance = _supResVerificationsStep; + + // + Calculate( barIndex // ); - if (!result) - { - // - Clean(); - continue; - } // result = isResistance; @@ -391,6 +818,10 @@ struct XPivot // result = IsValid() && isResistance; + if (!result) + { + Clean(); + } // return result; @@ -475,11 +906,19 @@ struct XPivot // // Check Support Rejected ... - bool IsSupportRejected() + bool IsSupportRejected( + int barIndex = 0 // + ) { // bool result = false; + // + if (barIndex < 0) + { + barIndex = 0; + } + // result = isSupport; if (!result) @@ -514,86 +953,35 @@ struct XPivot return result; } + // + double threshold = GetPoints(symbol) * _threshold; + // result = // // Check Support Touch or Fake Break ... - pBar.low < price + pBar.low < price && + ( + // + pBar.low < price || + pBar.low < price - threshold + // + ) // && // // Check Rejection ... - cBar.low > price - // - ; - - // - return result; - } - - // - // Check Support Breaked ... - bool IsSupportBreaked() - { - // - bool result = false; - - // - result = isSupport; - if (!result) - { - return result; - } - - // - // Initialize Required Bars ... - - // - XOHCL cBar; - result = cBar.Init( - symbol, - period, - 1 // - ); - if (!result) - { - return result; - } - - // - XOHCL pBar; - result = pBar.Init( - symbol, - period, - 2 // - ); - if (!result) - { - return result; - } - - // - result = - // - // Check Support Breaks ... - pBar.close < price - // - && - // - // Check 50% ... - (price - pBar.close) > (pBar.GetBody() / 100) * 50 - // - && - // - // Also Next Bar must Closed Below Support ... - cBar.high < price - // - && - // - cBar.close < price + cBar.low > price && + ( + // + cBar.low > price || + cBar.low > price + threshold + // + ) // && // + // Check Rejection Must be Bullish ... cBar.IsBullish() // ; @@ -603,12 +991,128 @@ struct XPivot } // - // Check Resistance Rejected ... - bool IsResistanceRejected() + // Check Support Breaked ... + bool IsSupportBreaked( + int barIndex = 0 // + ) { // bool result = false; + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + result = isSupport; + if (!result) + { + return result; + } + + // + // Initialize Required Bars ... + + // + XOHCL cBar; + result = cBar.Init( + symbol, + period, + barIndex + 1 // + ); + if (!result) + { + return result; + } + + // + XOHCL pBar; + result = pBar.Init( + symbol, + period, + barIndex + 2 // + ); + if (!result) + { + return result; + } + + // + double threshold = GetPoints(symbol) * _threshold; + + // + result = + // + // Check Support Breaks ... + pBar.close < price && + ( + // + pBar.close < price - threshold || + pBar.low < price - threshold + // + ) + // + && + // + // Check 50% ... + ( + // + (price - pBar.close) > (pBar.GetBody() / 100) * 50 || + (price - cBar.close) > (cBar.GetBody() / 100) * 50 + // + ) + // + && + // + // Also Next Bar must Closed Below Support ... + cBar.high < price && + cBar.high < price - threshold + // + && + // + cBar.close < price && + cBar.close < price - threshold + // + && + // + cBar.IsBearish() + // + ; + if (result) + { + DrawArrow( + 0, + "PBar", + 0, + pBar.time, + pBar.low, + 233, + ANCHOR_TOP, + clrYellow // + ); + } + + // + return result; + } + + // + // Check Resistance Rejected ... + bool IsResistanceRejected( + int barIndex = 0 // + ) + { + // + bool result = false; + + // + if (barIndex < 0) + { + barIndex = 0; + } + // result = isResistance; if (!result) @@ -643,16 +1147,36 @@ struct XPivot return result; } + // + double threshold = GetPoints(symbol) * _threshold; + // result = // // Check Resistance Touch or Fake Break ... - pBar.high > price + pBar.high > price && + ( + // + pBar.high > price || + pBar.high > price + threshold + // + ) // && // // Check Rejection ... - cBar.high < price + cBar.high < price && + ( + // + cBar.high < price || + cBar.high < price - threshold + // + ) + // + && + // + // Check Rejection Must be Bearish ... + cBar.IsBearish() // ; @@ -662,11 +1186,19 @@ struct XPivot // // Check Resistance Breaked ... - bool IsResistanceBreaked() + bool IsResistanceBreaked( + int barIndex = 0 // + ) { // bool result = false; + // + if (barIndex < 0) + { + barIndex = 0; + } + // result = isResistance; if (!result) @@ -701,25 +1233,41 @@ struct XPivot return result; } + // + double threshold = GetPoints(symbol) * _threshold; + // result = // // Check Resistance Breaks ... - pBar.close > price + pBar.close > price && + ( + // + pBar.close > price + threshold || + pBar.high > price + threshold + // + ) // && // // Check 50% ... - (pBar.close - price) > (pBar.GetBody() / 100) * 50 + ( + // + (pBar.close - price) > (pBar.GetBody() / 100) * 50 || + (cBar.close - price) > (cBar.GetBody() / 100) * 50 + // + ) // && // // Also Next Bar Must Closed Above Resistance ... - cBar.low > price + cBar.low > price && + cBar.low > price + threshold // && // - cBar.close > price + cBar.close > price && + cBar.close > price + threshold // && // @@ -1040,6 +1588,7 @@ struct XPivot long _chartId, string _prefix = "", color _color = clrYellow, + color _thresholdColor = clrAqua, ENUM_LINE_STYLE _style = STYLE_DOT, bool _ray = true, int _width = 1, @@ -1094,491 +1643,57 @@ struct XPivot ); // - return result; - } - - // - // Remove Draw ... - void Remove() - { - // - if (!IsValid(_objName)) - { - return; - } - - // - RemoveDraws(_objName); - } -}; - -// -// a Zone Modeling ... - -// -enum ENUM_XZONE_STATE -{ - XZONE_STATE_INVALID = 0, // Invalid Zone ... - XZONE_STATE_FULL_SUPPORT = 1, // Full Support (up / down) are Support ... - XZONE_STATE_FULL_RESISTANCE = 2, // Full Resistance (up / down) are Resistaence ... - XZONE_STATE_CONSOLIDATE = 3, // Down are Support and Up are Resistance ... -}; - -// -// a Zone Consists an Area of -// an Upper Pivot and a Lower Pivot ... -struct XZone -{ - // - string symbol; // Trading Symbol ... - ENUM_TIMEFRAMES period; // Trading TimeFrame ... - - // - datetime time; - - // - XPivot up; // Up pivot ... - XPivot down; // Down Pivot ... - - // - // Constructor ... - XZone() - { - Clean(); - } - - // - // Initialize a Zone ... - bool Init( - string _symbol, - ENUM_TIMEFRAMES _period, - double _upPrice, - double _downPrice, - int barIndex = 0, - int pivotVerificationStep = 21 // - ) - { - // - bool result = false; - - // - result = - // - IsValid(_symbol) && - IsValid(_period) && - _upPrice > 0 && - _downPrice > 0 && - _downPrice < _upPrice - // - ; - if (!result) - { - return result; - } - - // - symbol = _symbol; - period = _period; - - // - result = up.Init( - symbol, - period, - _upPrice, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - result = down.Init( - symbol, - period, - _downPrice, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - result = IsValid(); - - // - if (result) - { - time = TimeCurrent(); - } - - // - return result; - } - - // - // Find Last Support Zone ... - bool FindLastSupportZone( - string _symbol, - ENUM_TIMEFRAMES _period, - int barIndex = 0, - int pivotVerificationStep = 21 // - ) - { - // - bool result = false; - - // - // Since Support Pivots Used Target Bar's Low price - // Last Resistance Set in Down Line of Zone ... - result = down.FindLastSupport( - _symbol, - _Period, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - // Since Support Pivots Used Target Bar's Low price - // we can Set it's High as Up Zone ... - XOHCL tBar; - result = tBar.Init( - _symbol, - _period, - down.supportTime // - ); - if (!result) - { - return result; - } - - // - // Now we Have Target Bar ... - // Set it's High as Up Line of Zone ... - result = up.Init( - _symbol, - _period, - tBar.high, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - up.supportTime = down.supportTime; - - // - if (result) + if (result && _threshold > 0) { // - symbol = _symbol; - period = _period; + // Calculate Threshodl Value ... + double diff = GetPoints(symbol) * _threshold; // - time = TimeCurrent(); - } - - // - return result; - } - - // - // Find Last Resistance Zone ... - bool FindLastResistanceZone( - string _symbol, - ENUM_TIMEFRAMES _period, - int barIndex = 0, - int pivotVerificationStep = 21 // - ) - { - // - bool result = false; - - // - // Since Resistance Pivots Used Target Bar's High price - // Last Resistance Set in Up Line of Zone ... - result = up.FindLastResistance( - _symbol, - _Period, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - // Since Resistance Pivots Used Target Bar's High price - // we can Set it's Low as Down Zone ... - XOHCL tBar; - result = tBar.Init( - _symbol, - _period, - up.resistanceTime // - ); - if (!result) - { - return result; - } - - // - // Now we Have Target Bar ... - // Set it's Low as Down Line of Zone ... - result = down.Init( - _symbol, - _period, - tBar.low, - barIndex, - pivotVerificationStep // - ); - if (!result) - { - return result; - } - - // - down.resistanceTime = up.resistanceTime; - - // - if (result) - { - // - symbol = _symbol; - period = _period; + // Up Threshold ... + result = DrawTrendLine( + _chartId, + _objName + "_UPTRSH", + _subWindow, + time1, + price + diff, + time, + price + diff, + _thresholdColor, + _style, + _width, + false, + false, + _ray // + ); // - time = TimeCurrent(); + if (result) + { + // + // Down Threshold ... + result = DrawTrendLine( + _chartId, + _objName + "_DOWNTRSH", + _subWindow, + time1, + price - diff, + time, + price - diff, + _thresholdColor, + _style, + _width, + false, + false, + _ray // + ); + } } // return result; } - // - // Tools ... - - // - // Check XZone State ... - ENUM_XZONE_STATE GetState() - { - // - ENUM_XZONE_STATE result = XZONE_STATE_INVALID; - if (!IsValid()) - { - return result; - } - - // - if (up.isSupport && down.isSupport) - { - result = XZONE_STATE_FULL_SUPPORT; - } - else if (up.isResistance && down.isResistance) - { - result = XZONE_STATE_FULL_RESISTANCE; - } - else if (up.isSupport && down.isResistance) - { - result = XZONE_STATE_CONSOLIDATE; - } - - // - return result; - } - - // - // Zone Tools ... - double _threshold; - double GetThresholdPoints() - { - // - double result = 0; - - // - if (!IsValid()) - { - return result; - } - - // - double _points = GetPoints(symbol); - result = - // - _points && - _threshold - // - ; - - // - return result; - } - - // - // Check Zone Rejected ... - bool IsSupportRejected() - { - // - bool result = false; - - // - // Check is Full Support or Not ... - ENUM_XZONE_STATE state = GetState(); - result = state == XZONE_STATE_FULL_SUPPORT; - if (!result) - { - return result; - } - - // - // First Check Price Rejection Above Upper Line ... - - // - return result; - } - - // - // Check Zone Breaked ... - - // - // Cleanup ... - void Clean() - { - // - symbol = NULL; - period = NULL; - time = NULL; - - // - up.Clean(); - down.Clean(); - - // - _threshold = 15; - - // - _objName = NULL; - } - - // - // Validate ... - bool IsValid() - { - // - bool result = false; - - // - result = - // - IsValid(symbol) && - IsValid(period) && - up.IsValid() && - down.IsValid() && - _threshold > 0 - // - ; - - // - return result; - } - - // - string GetTag() - { - return "XZone"; - } - - // - // Draw Functions ... - - // - // Last Draw Object Name ... - string _objName; - - // - // Draw ... - bool Draw( - long _chartId, - string _prefix = "", - color _color = clrYellow, - ENUM_LINE_STYLE _style = STYLE_DOT, - bool _ray = true, - int _width = 1, - int _subWindow = 0 // - ) - { - // - bool result = false; - - // - ENUM_XZONE_STATE state = GetState(); - - // - result = - // - IsValid() && - state != XZONE_STATE_INVALID - // - ; - if (!result) - { - return result; - } - - // - _objName = GetTag() + "_" + (IsValid(_prefix) ? _prefix + "_" : "") + ToString(NormalizeDouble(up.price, 2)) + "," + ToString(NormalizeDouble(down.price, 2)); - - // - datetime time1 = - // - down.isSupport - ? down.supportTime - : down.resistanceTime - // - ; - - // - result = down.Draw( - _chartId, - _objName + "_DOWN", - _color, - _style, - _ray, - _width, - _subWindow, - true // Force PRefix ... - ); - if (!result) - { - return result; - } - - // - result = up.Draw( - _chartId, - _objName + "_UP", - _color, - _style, - _ray, - _width, - _subWindow, - true // Force PRefix ... - ); - - // - return result; - } - // // Remove Draw ... void Remove() @@ -1594,383 +1709,4 @@ struct XZone } }; -// -// a Range Box Model ... -// struct XRBox -// { -// // -// string symbol; -// ENUM_TIMEFRAMES period; - -// // -// datetime time; -// datetime expiration; - -// // -// XZone up; // Up Zone ... -// XZone down; // Down Zone ... - -// // -// // Constructor ... -// XRBox() -// { -// Clean(); -// } - -// // -// // Initialization ... -// bool Init( -// string _symbol, -// ENUM_TIMEFRAMES _period, -// double _upZoneUpperPrice, -// double _upZoneLowerPrice, -// double _downZoneUpperPrice, -// double _downZoneLowerPrice, -// datetime _expiration = NULL // -// ) -// { -// // -// bool result = false; - -// // -// result = -// // -// IsValid(_symbol) && -// IsValid(_period) && -// _upZoneUpperPrice > 0 && -// _upZoneLowerPrice > 0 && -// _upZoneLowerPrice < _upZoneUpperPrice && -// _downZoneUpperPrice > 0 && -// _downZoneLowerPrice > 0 && -// _downZoneLowerPrice < _downZoneUpperPrice -// // -// ; -// // -// if (!result) -// { -// return result; -// } - -// // -// result = IsValid(); - -// // -// if (result) -// { -// // -// time = TimeCurrent(); -// } - -// // -// return result; -// } - -// // -// // Tools ... - -// // -// // Cleanup ... -// void Clean() -// { -// // -// time = NULL; -// symbol = NULL; -// period = NULL; -// expiration = NULL; - -// // -// up.Clean(); -// down.Clean(); -// } - -// // -// // Validation ... -// bool IsValid() -// { -// // -// bool result = false; - -// // -// result = -// // -// IsValid(symbol) && -// IsValid(period) && -// up.IsValid() && -// down.IsValid() -// // -// ; - -// // -// return result; -// } -// }; - -// -// Detect Trends ... -struct XTrendDetector -{ - // - string symbol; - ENUM_TIMEFRAMES period; - - // - double higherHighs[]; - datetime higherHighTimes[]; - - // - double higherLows[]; - datetime higherLowTimes[]; - - // - double lowerHighs[]; - datetime lowerHighTimes[]; - - // - double lowerLows[]; - datetime lowerLowTimes[]; - - // - int _numberOfPivots; - int _pivotShoulders; - - // - // Constructor ... - XTrendDetector() - { - Clean(); - } - - // - bool FindTrend( - string _symbol, - ENUM_TIMEFRAMES _period, - int barIndex = 0, - int _requiredPivots = 5, - int _requiredShoulders = 5 // - ) - { - // - bool result = false; - - // - if (barIndex < 0) - { - barIndex = 0; - } - - // - if (_requiredPivots < 5) - { - _requiredPivots = 5; - } - - // - if (_requiredShoulders < 5) - { - _requiredShoulders = 5; - } - - // - result = - // - IsValid(_symbol) && - IsValid(_period) - // - ; - if (!result) - { - return result; - } - - // - // Find Swing Lows and Swing Highs ... - - // - int hhIndexes[]; - datetime hhTimes[]; - double hhs[]; - - // - int llIndexes[]; - datetime llTimes[]; - double lls[]; - - // - bool isEnough = false; - int lastHHIndex = barIndex; - int lastLLIndex = barIndex; - while (!isEnough) - { - // - int hhSize = ArraySize(hhs); - if (hhSize < _requiredPivots) - { - // - lastHHIndex = FindSwing( - _symbol, - _period, - X_SWING_HIGH, - _requiredShoulders, - lastHHIndex + 1 // - ); - if (lastHHIndex >= 0) - { - // - XOHCL hBar; - bool isInited = hBar.Init( - _symbol, - _period, - lastHHIndex // - ); - if (isInited) - { - // - Add( - hBar.high, - hhs // - ); - - // - Add( - hBar.time, - hhTimes // - ); - - // - Add( - lastHHIndex, - hhIndexes // - ); - } - } - } - - // - int llSize = ArraySize(lls); - if (llSize < _requiredPivots) - { - // - lastLLIndex = FindSwing( - _symbol, - _period, - X_SWING_LOW, - _requiredShoulders, - lastLLIndex + 1 // - ); - if (lastLLIndex >= 0) - { - // - XOHCL lBar; - bool isInited = lBar.Init( - _symbol, - _period, - lastLLIndex // - ); - if (isInited) - { - // - Add( - lBar.low, - lls // - ); - - // - Add( - lBar.time, - llTimes // - ); - - // - Add( - lastHHIndex, - llIndexes // - ); - } - } - } - - // - hhSize = ArraySize(hhs); - llSize = ArraySize(lls); - isEnough = - // - hhSize == _requiredPivots && - llSize == _requiredPivots - // - ; - } - - // // - // ArrayReverse(hhs); - // ArrayReverse(hhTimes); - // ArrayReverse(hhIndexes); - - // // - // ArrayReverse(lls); - // ArrayReverse(llTimes); - // ArrayReverse(llIndexes); - - // - symbol = _symbol; - period = _period; - _numberOfPivots = _requiredPivots; - _pivotShoulders = _requiredShoulders; - - // - result = IsValid(); - - // - return result; - } - - // - // Tools ... - - // - // Cleanup ... - void Clean() - { - // - symbol = NULL; - period = NULL; - - // - _numberOfPivots = 0; - _pivotShoulders = 0; - - // - Clean(higherHighs); - Clean(higherHighTimes); - - // - Clean(higherLows); - Clean(higherLowTimes); - - // - Clean(lowerHighs); - Clean(lowerHighTimes); - - // - Clean(lowerLows); - Clean(lowerLowTimes); - } - - // - // Validate ... - bool IsValid() - { - // - bool result = false; - - // - result = - // - IsValid(symbol) && - IsValid(period) - // - ; - - // - return result; - } -}; +// \ No newline at end of file