diff --git a/Documents/BKP/Templates/XOHCL.unused.mq5 b/Documents/BKP/Templates/XOHCL.unused.mq5 new file mode 100644 index 00000000..ca1caf93 --- /dev/null +++ b/Documents/BKP/Templates/XOHCL.unused.mq5 @@ -0,0 +1,644 @@ + + // + // Check Bar has Strong Body or Not ... + bool HasStrongBody() + { + // + bool result = false; + + // + if (!IsValid()) + { + return result; + } + + // + double body = GetBody(); + double shadow = GetShadows(); + + // + result = body > shadow * 1.5; + + // + return result; + } + + // + // Bar Must Open Below Prce + // and Close Above it ... + bool IsBreakUp( + double price // a Price to Check Breake + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + result = + // + close > price && + open < price; + + // + return result; + } + + // + // Bar Must Open Above Prce + // and Close Below it ... + bool IsBreakDown( + double price // a Price to Check Breake + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + result = + // + open > price && + close < price; + + // + return result; + } + + // + bool IsBreakOut( + double price, // a Price to Check Breake + bool useHighLow = true // if true using High and Low price for Breakeouts, if not use Open Close + ) + { + // + bool result = false; + + // + result = HasStrongBody(); + if (!result || price <= 0) + { + return result; + } + + // + // Select required Prices ... + + // + double selectedUp = + useHighLow + ? high + : GetUp(); + double selectedDown = + useHighLow + ? low + : GetDown(); + + // + result = + // + selectedUp > price && + selectedDown < price; + + // + return result; + } + + // + // Check a Support Line Rejected or not ... + bool IsSupportRejected( + double price // Support Price + ) + { + // + bool result = false; + + // + // this is zBar ... + // so we are try to Recieve CBar ... + XOHCL cBar; + result = this.GetPreviousBar(cBar); + if (!result) + { + return result; + } + + // + // Now we are going to Recieve PBar ... + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // We Have this (0) Bar, cBar (1) and pBar (2) ... + + // + // pBar Down Shadow must break Price Line ... + // cBar and zBar Close must be Above Price Line ... + // also zBar Open must be Above Price Line ... + result = + // + pBar.high > price && + pBar.low < price && + cBar.close > price && + this.close > price && + this.open > price + // + ; + + // + return result; + } + + // + // Check a Support Line Breaked or not ... + bool IsSupportBreaked( + double price // Support Price + ) + { + // + bool result = false; + + // + // this is zBar ... + // so we are try to Recieve CBar ... + XOHCL cBar; + result = this.GetPreviousBar(cBar); + if (!result) + { + return result; + } + + // + // Now we are going to Recieve PBar ... + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // We Have this (0) Bar, cBar (1) and pBar (2) ... + + // + // pBar Down Shadow must break Price Line ... + // cBar and zBar Close must be Below Price Line ... + // also zBar Open must be Below Price Line ... + result = + // + pBar.high > price && + pBar.low < price && + cBar.close < price && + this.close < price && + this.open < price + // + ; + + // + return result; + } + + // + // Check a Resistance Line Rejected or not ... + bool IsResistanceRejected( + double price // Resistance Price + ) + { + // + bool result = false; + + // + // this is zBar ... + // so we are try to Recieve CBar ... + XOHCL cBar; + result = this.GetPreviousBar(cBar); + if (!result) + { + return result; + } + + // + // Now we are going to Recieve PBar ... + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // We Have this (0) Bar, cBar (1) and pBar (2) ... + + // + // pBar Up Shadow must break Price Line ... + // cBar and zBar Close must be Under Price Line ... + // also zBar Open must be Under Price Line ... + result = + // + pBar.high > price && + pBar.low < price && + cBar.close < price && + this.close < price && + this.open < price + // + ; + + // + return result; + } + + // + // Check a Resistance Line Breaked or not ... + bool IsResistanceBreaked( + double price // Support Price + ) + { + // + bool result = false; + + // + // this is zBar ... + // so we are try to Recieve CBar ... + XOHCL cBar; + result = this.GetPreviousBar(cBar); + if (!result) + { + return result; + } + + // + // Now we are going to Recieve PBar ... + XOHCL pBar; + result = cBar.GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // We Have this (0) Bar, cBar (1) and pBar (2) ... + + // + // pBar Up Shadow must break Price Line ... + // cBar and zBar Close must be Over Price Line ... + // also zBar Open must be Pver Price Line ... + result = + // + pBar.low < price && + pBar.high > price && + cBar.close > price && + this.close > price && + this.open > price + // + ; + + // + return result; + } + + // + // Check Bar is Inside Previus Bar ... + bool IsInsideBar( + double threshold = 5 // Points Distance between Up and Down + ) + { + // + bool result = false; + + // + if (threshold < 0) + { + threshold = 0; + } + + // + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + double offset = PointToPrice(threshold, this.symbol); + + // + result = + // + pBar.high > this.high && + pBar.low < this.low && + MathAbs(pBar.low - this.low) > offset && + MathAbs(pBar.high - this.high) > offset + // + ; + + // + return result; + } + + // + // Check Bar has Strongest Body in a Range ... + bool HasStrongestBody( + int mLoopback = 3 // loopback candles to compare it ... + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double body = GetBody(); + XOHCL prev = this; + for (int i = 0; i < mLoopback; i++) + { + // + bool isValid = prev.GetPreviousBar(prev); + if (!isValid) + { + // + result = false; + break; + } + + // + result = + // + result && + body > prev.GetBody() + // + ; + if (!result) + { + break; + } + } + + // + return result; + } + + // + // Check Bar has Weakest Body in a Range ... + bool HasWeakestBody( + int mLoopback = 3 // loopback candles to compare it ... + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double body = GetBody(); + XOHCL prev = this; + for (int i = 0; i < mLoopback; i++) + { + // + bool isValid = prev.GetPreviousBar(prev); + if (!isValid) + { + // + result = false; + break; + } + + // + result = + // + result && + body < prev.GetBody() + // + ; + if (!result) + { + break; + } + } + + // + return result; + } + + + + + // + // Determines Swings based On this Bar ... + // Calculates Based on atleast 3 Bars Prev ... + ENUM_X_SWING_TYPE GetSwingType() + { + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Find Current Index of Bar ... + int barIndex = Index(); + if (barIndex <= -1) + { + return result; + } + + // + // First we have to Retrieve atleast 3 Bars before this bar ... + XOHCL bars[]; + int barsCount = GetBars( + bars, + symbol, + period, + barIndex + 1, + 3 + // + ); + if (barsCount < 3) + { + return result; + } + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = bars[2].HasStrongBody(); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + bars[2].low < bars[1].low && + bars[1].low < bars[0].low && + bars[2].low < bars[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + bars[2].high > bars[1].high && + bars[1].high > bars[0].high && + bars[2].high > bars[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; + } + + + + + + // + // Check Bar Is Hammer Pattern ... + bool IsHammer() + { + // + bool result = false; + + // + double fib382 = GetFibonacciLevel( + high, + low, + 0.382, + -1 // + ); + + // + result = GetDown() > fib382; + + // + return result; + } + + // + // Check Bar Is Shooting Star Pattern ... + bool IsShootingStar() + { + // + bool result = false; + + // + double fib382 = GetFibonacciLevel( + high, + low, + 0.382, + 1 // + ); + + // + result = GetUp() < fib382; + + // + return result; + } + + // + // Check Bar Bullish Engulfing Pattern ... + bool IsBullishEngulf() + { + // + bool result = false; + + // + // Current Bar Must be Bullish ... + result = IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + result = + // + pBar.IsBearish() && + open < pBar.close && close > pBar.open && + high >= pBar.high && low <= pBar.low + // + ; + + // + return result; + } + + // + // Check Bar Bearish Engulfing Pattern ... + bool IsBearishEngulf() + { + // + bool result = false; + + // + // Current Bar Must be Bearish ... + result = IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + result = + // + pBar.IsBullish() && + open > pBar.close && close < pBar.open && + high >= pBar.high && low <= pBar.low + // + ; + + // + return result; + } diff --git a/Experts/x-simple-test.ea.mq5 b/Experts/x-simple-test.ea.mq5 new file mode 100644 index 00000000..cd98a4aa --- /dev/null +++ b/Experts/x-simple-test.ea.mq5 @@ -0,0 +1,1075 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XTest MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XTestEA +// Description: an Exper Advisor which used XTestSetup +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTestEA" +#property strict + +// +#define ShortName "XTestEA" + +// +// Imports ... +#include "../Libraries/x-saherelm.tools.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... +long mMagicNumber = 78692110; // Magic Number +int mSlippage = 10; // Slippgae + +// +double eaVolume = 0.01; +double eaAllowLong = true; +double eaAllowShort = true; + +// +XBarTracker eaBarTracker; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + drawPrefix = ShortName; + + // + bool isInited = eaBarTracker.Init( + _Symbol, + _Period // + ); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XSampleEA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!eaBarTracker.CanProcessBar()) + { + return; + } + + // + // Find Doji Patterns ... + // FindDoji(); + + // + // Find Hammer Patters ... + // FindHammer(); + + // + // Find Shooting Star Pattern ... + // FindShootingStar(); + + // + // Find Bullish Engulfing Pattern ... + // FindBullishEngulfing(); + + // + // Find Bearish Engulfing Pattern ... + // FindBearishEngulfing(); + + // + // Find Morning Star Pattern ... + FindMorningStar(); + + // + // Find Evening Star Pattern ... + FindEveningStar(); + + // + // Find Swing High Pattern ... + // FindSwingHigh(); + + // + // Find Swing Low Pattern ... + // FindSwingLow(); + + // + // Find Bullish FVG ... + // FindBullishFVG(); + + // + // Find Bearish FVG ... + // FindBearishFVG(); + + // + // Find Support ... + // FindSupport(); + + // + // Find Resistance ... + // FindResistance(); + + // + // Find Bullish Trend ... + // FindBullishTrend(); + + // + // Find Bearish Trend ... + // FindBearishTrend(); +} + +// +// Custom Functions ... + +// +bool ValidateInputs() +{ + // + bool result = false; + + // + result = true; + + // + return result; +} + +// +// Custom Testing Functions ... + +// +// Find Doji Pattern ... +void FindDoji() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + if (!cBar.IsDoji()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "Doji-" + ToString((int)cBar.time), + 0, + cBar.time, + cBar.low, + 233, + ANCHOR_TOP, + clrGray, + STYLE_SOLID, + 2 // + ); + + // + Print("Doji Pattern Detected ..."); +} + +// +// Find Hammer Pattern ... +void FindHammer() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + if (!cBar.IsHammer()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "Hammer-" + ToString((int)cBar.time), + 0, + cBar.time, + cBar.low, + 233, + ANCHOR_TOP, + clrAqua, + STYLE_SOLID, + 2 // + ); + + // + Print("Hammer Pattern Detected ..."); +} + +// +// Find Shooting Star Pattern ... +void FindShootingStar() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + if (!cBar.IsShootingStar()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "ShootingStar-" + ToString((int)cBar.time), + 0, + cBar.time, + cBar.high, + 234, + ANCHOR_BOTTOM, + clrMagenta, + STYLE_SOLID, + 2 // + ); + + // + Print("Shooting Star Pattern Detected ..."); +} + +// +// Find Bullish Engulfing Pattern ... +void FindBullishEngulfing() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsBullishEngulfing()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawRectangle( + ChartID(), + "BullishEngulfing-" + ToString((int)cBar.time), + 0, + pBar.time, + pBar.low, + cBar.time, + cBar.high, + clrAqua, + STYLE_SOLID, + 1, + false // + ); + + // + Print("Bullish Engulfing Pattern Detected ..."); +} + +// +// Find Bearish Engulfing Pattern ... +void FindBearishEngulfing() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsBearishEngulfing()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawRectangle( + ChartID(), + "BearishEngulfing-" + ToString((int)cBar.time), + 0, + pBar.time, + pBar.low, + cBar.time, + cBar.high, + clrMagenta, + STYLE_SOLID, + 1, + false // + ); + + // + Print("Bearish Engulfing Pattern Detected ..."); +} + +// +// Find Morning Star Pattern ... +void FindMorningStar() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsMorningStar()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "MorningStar-" + ToString((int)cBar.time), + 0, + cBar.time, + cBar.low, + 233, + ANCHOR_TOP, + clrAqua, + STYLE_SOLID, + 2 // + ); + + // + Print("Morning Star Pattern Detected ..."); +} + +// +// Find Evening Star Pattern ... +void FindEveningStar() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsEveningStar()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "EveningStar-" + ToString((int)cBar.time), + 0, + cBar.time, + cBar.high, + 234, + ANCHOR_BOTTOM, + clrMagenta, + STYLE_SOLID, + 2 // + ); + + // + Print("Evening Star Pattern Detected ..."); +} + +// +// Find Swing High Pattern ... +void FindSwingHigh() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsSwingHigh()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "SwingHigh-" + ToString((int)pBar.time), + 0, + pBar.time, + pBar.high, + 202, + ANCHOR_BOTTOM, + clrMagenta, + 2 // + ); + + // + Print("Swing High Detected ..."); +} + +// +// Find Swing Low Pattern ... +void FindSwingLow() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + XOHCL pBar; + isInited = cBar.GetPreviousBar(pBar); + if (!isInited) + { + return; + } + + // + if (!cBar.IsSwingLow()) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawArrow( + ChartID(), + "SwingLow-" + ToString((int)pBar.time), + 0, + pBar.time, + pBar.low, + 200, + ANCHOR_TOP, + clrAqua, + 2 // + ); + + // + Print("Swing Low Detected ..."); +} + +// +// Find Bullish FVG ... +void FindBullishFVG() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + double upper = 0; + double lower = 0; + bool hasFVG = cBar.HasBullishFVG( + upper, + lower // + ); + if (!hasFVG) + { + return; + } + + // + eaBarTracker.Waits(); + + // + datetime time1 = iTime( + cBar.symbol, + cBar.period, + 1 + 2 // + ); + + // + DrawRectangle( + ChartID(), + "BullishFVG-" + ToString((int)cBar.time), + 0, + time1, + lower, + cBar.time, + upper, + clrAqua // + ); + + // + Print("Bullish FVG Detected ..."); +} + +// +// Find Bearish FVG ... +void FindBearishFVG() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + double upper = 0; + double lower = 0; + bool hasFVG = cBar.HasBearishFVG( + upper, + lower // + ); + if (!hasFVG) + { + return; + } + + // + eaBarTracker.Waits(); + + // + datetime time1 = iTime( + cBar.symbol, + cBar.period, + 1 + 2 // + ); + + // + DrawRectangle( + ChartID(), + "BearishFVG-" + ToString((int)cBar.time), + 0, + time1, + upper, + cBar.time, + lower, + clrMagenta // + ); + + // + Print("Bearish FVG Detected ..."); +} + +// +// Find Support ... +void FindSupport() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + datetime at = NULL; + double support = 0; + bool hasSupport = cBar.HasSupport( + support, + at // + ); + if (!hasSupport) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawTrendLine( + ChartID(), + "Support-" + ToString((int)at), + 0, + at, + support, + TimeCurrent(), + support, + clrAqua, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + Print("Support Detected ..."); +} + +// +// Find Resistance ... +void FindResistance() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + datetime at = NULL; + double resistance = 0; + bool hasResistance = cBar.HasResistance( + resistance, + at // + ); + if (!hasResistance) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawTrendLine( + ChartID(), + "Resistance-" + ToString((int)at), + 0, + at, + resistance, + TimeCurrent(), + resistance, + clrMagenta, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + Print("Resistance Detected ..."); +} + +// +// Find Bullish Trend ... +void FindBullishTrend() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + double hSwings[]; + datetime hSwingTimes[]; + + // + double lSwings[]; + datetime lSwingTimes[]; + + // + bool isBullishTrend = cBar.HasBullishTrend( + hSwings, + hSwingTimes, + lSwings, + lSwingTimes, + false // Method 2 ... + ); + if (!isBullishTrend) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawTrendLine( + ChartID(), + "HSING-BULLTrend-" + ToString((int)hSwingTimes[ArraySize(hSwingTimes) - 1]) + "," + ToString((int)hSwingTimes[0]), + 0, + hSwingTimes[ArraySize(hSwingTimes) - 1], + hSwings[ArraySize(hSwings) - 1], + hSwingTimes[0], + hSwings[0], + clrAqua, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + DrawTrendLine( + ChartID(), + "LSING-BULLTrend-" + ToString((int)lSwingTimes[ArraySize(lSwingTimes) - 1]) + "," + ToString((int)lSwingTimes[0]), + 0, + lSwingTimes[ArraySize(lSwingTimes) - 1], + lSwings[ArraySize(lSwings) - 1], + lSwingTimes[0], + lSwings[0], + clrMagenta, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + // Draw Arrow On Swing Highs ... + for (int i = 0; i < ArraySize(hSwings); i++) + { + // + double iPrice = hSwings[i]; + datetime iTime = hSwingTimes[i]; + + // + DrawArrow( + ChartID(), + "HSIGN-BULLTrend-Arrow-" + ToString((int)iTime), + 0, + iTime, + iPrice, + 234, + ANCHOR_BOTTOM, + clrAqua, + STYLE_SOLID, + 2 // + ); + } + + // + // Draw Arrow On Swing Highs ... + for (int i = 0; i < ArraySize(lSwings); i++) + { + // + double iPrice = lSwings[i]; + datetime iTime = lSwingTimes[i]; + + // + DrawArrow( + ChartID(), + "LSIGN-BULLTrend-Arrow-" + ToString((int)iTime), + 0, + iTime, + iPrice, + 233, + ANCHOR_TOP, + clrMagenta, + STYLE_SOLID, + 2 // + ); + } + + // + Print("Bullish Trend Detected ..."); +} + +// +// Find Bearish Trend ... +void FindBearishTrend() +{ + // + XOHCL cBar; + bool isInited = cBar.Init( + _Symbol, + _Period, + 1 // + ); + if (!isInited) + { + return; + } + + // + double hSwings[]; + datetime hSwingTimes[]; + + // + double lSwings[]; + datetime lSwingTimes[]; + + // + bool isBearishTrend = cBar.HasBearishTrend( + hSwings, + hSwingTimes, + lSwings, + lSwingTimes, + false // Method 2 ... + ); + if (!isBearishTrend) + { + return; + } + + // + eaBarTracker.Waits(); + + // + DrawTrendLine( + ChartID(), + "HSING-BEARTrend-" + ToString((int)hSwingTimes[ArraySize(hSwingTimes) - 1]) + "," + ToString((int)hSwingTimes[0]), + 0, + hSwingTimes[ArraySize(hSwingTimes) - 1], + hSwings[ArraySize(hSwings) - 1], + hSwingTimes[0], + hSwings[0], + clrAqua, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + DrawTrendLine( + ChartID(), + "LSING-BEARTrend-" + ToString((int)lSwingTimes[ArraySize(lSwingTimes) - 1]) + "," + ToString((int)lSwingTimes[0]), + 0, + lSwingTimes[ArraySize(lSwingTimes) - 1], + lSwings[ArraySize(lSwings) - 1], + lSwingTimes[0], + lSwings[0], + clrMagenta, + STYLE_DOT, + 1, + false, + false, + true // + ); + + // + // Draw Arrow On Swing Highs ... + for (int i = 0; i < ArraySize(hSwings); i++) + { + // + double iPrice = hSwings[i]; + datetime iTime = hSwingTimes[i]; + + // + DrawArrow( + ChartID(), + "HSIGN-BEARTrend-Arrow-" + ToString((int)iTime), + 0, + iTime, + iPrice, + 234, + ANCHOR_BOTTOM, + clrAqua, + STYLE_SOLID, + 2 // + ); + } + + // + // Draw Arrow On Swing Highs ... + for (int i = 0; i < ArraySize(lSwings); i++) + { + // + double iPrice = lSwings[i]; + datetime iTime = lSwingTimes[i]; + + // + DrawArrow( + ChartID(), + "LSIGN-BEARTrend-Arrow-" + ToString((int)iTime), + 0, + iTime, + iPrice, + 233, + ANCHOR_TOP, + clrMagenta, + STYLE_SOLID, + 2 // + ); + } + + // + Print("Bearish Trend Detected ..."); +} + +// \ No newline at end of file diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index a0afd5af..6a6e579f 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -316,25 +316,25 @@ bool InitialEA() // MAGIC NUMBER ... long magicNumber = mMagicNumber + 3; - // - // Register XSRBR on XAUUSD in M5 ... - XSCXSRBRStrategy *usdjpyM5SRBRStrategy; - usdjpyM5SRBRStrategy = new XSCXSRBRStrategy( - usdjpySymbol, - PERIOD_M5, - eaVolume, - 1.5, // R2R ... - mSlippage, - magicNumber, - eaAllowLong, - eaAllowShort, - 0, // Max Longs - 0 // Max Shorts - ); - usdjpyM5SRBRStrategy.SetAlertLogAlerts(true); - usdjpyM5SRBRStrategy.SetAlertEnableAlerts(true); - usdjpyM5SRBRStrategy.DarwSupportAndResistances(drawAreas); - RegisterStrategy(usdjpyM5SRBRStrategy); + // // + // // Register XSRBR on XAUUSD in M5 ... + // XSCXSRBRStrategy *usdjpyM5SRBRStrategy; + // usdjpyM5SRBRStrategy = new XSCXSRBRStrategy( + // usdjpySymbol, + // PERIOD_M5, + // eaVolume, + // 1.5, // R2R ... + // mSlippage, + // magicNumber, + // eaAllowLong, + // eaAllowShort, + // 0, // Max Longs + // 0 // Max Shorts + // ); + // usdjpyM5SRBRStrategy.SetAlertLogAlerts(true); + // usdjpyM5SRBRStrategy.SetAlertEnableAlerts(true); + // usdjpyM5SRBRStrategy.DarwSupportAndResistances(drawAreas); + // RegisterStrategy(usdjpyM5SRBRStrategy); } // diff --git a/Indicators/x-saherelm.xobd.mq5 b/Indicators/x-saherelm.xobd.mq5 deleted file mode 100644 index a2531743..00000000 --- a/Indicators/x-saherelm.xobd.mq5 +++ /dev/null @@ -1,395 +0,0 @@ -///////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 OrderBlock Detector Indicator -// ----------------------------------------------------- -// Name: XOBD -// Description: detect Order Blocks based on Swings ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://saherelm.ir" -#property version "1.00" -#property description "SaherElm XOBD Indicator" -#property strict - -// -// START Constants ... -// -#define ShortName "XOBD" -// -// END Constants ... -// - -// -// START Inputs ... -// -// -input int length = 5; // Swing Length - -// -input uchar swingHighArrowCode = 108; // Swing High Arrow Code -input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color - -// -input uchar swingLowArrowCode = 108; // Swing Low Arrow Code -input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color -// -// END Inputs ... -// - -// -// Include Common and Models Library ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Include Draw Library ... -#include "../Libraries/x-saherelm.draw.lib.mq5" - -// -// START Buffers ... -// -#property indicator_chart_window - -// -#property indicator_buffers 1 -#property indicator_plots 0 - -// -#define swingBufferIndex 0 -double swingBuffer[]; -// -// END Buffers ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Event Handlers ... -// -// -// Initialization ... -int OnInit() -{ - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - drawPrefix = ShortName; - - // - // Define Index Buffers ... - DefineBuffers(); - - // - // Set Indicator ShortName ... - SetIndicatorName(); - - // - // Init Succeed ... - return INIT_SUCCEEDED; -} - -// -// DeInitialization ... -void OnDeinit(const int reason) -{ - // - // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function - // REASON_REMOVE 1 Program removed from a chart - // REASON_RECOMPILE 2 Program recompiled - // REASON_CHARTCHANGE 3 A symbol or a chart period is changed - // REASON_CHARTCLOSE 4 Chart closed - // REASON_PARAMETERS 5 Inputs changed by a user - // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings - // REASON_TEMPLATE 7 Another chart template applied - // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value - // REASON_CLOSE 9 Terminal closed -} - -// -// Calculations ... -// -// Calculating what we want ... -int OnCalculate( - // - // total Candles on chart ... - const int rates_total, - // - // total calculated Candles on charts ... - const int prev_calculated, - // - // history of Candles Open Time ... - const datetime &time[], - // - // history of Candles Open Price ... - const double &open[], - // - // history of Candles High Price ... - const double &high[], - // - // history of Candles Low Price ... - const double &low[], - // - // history of Candles Close Price ... - const double &close[], - // - // history of Tick Volumes on Candle ... - const long &tick_volume[], - // - // history of Trade Volumes ... - const long &volume[], - // - // history of Candles Spread Price ... - const int &spread[]) -{ - // - // Prepare Buffers ... - ArraySetAsSeries(time, true); - ArraySetAsSeries(open, true); - ArraySetAsSeries(high, true); - ArraySetAsSeries(low, true); - ArraySetAsSeries(close, true); - ArraySetAsSeries(tick_volume, true); - ArraySetAsSeries(volume, true); - ArraySetAsSeries(spread, true); - - // - // this counts Available Bars ... - int limit; - - // - // because in some cases we may have more than one input for - // calculation and we must prevent any calculation - // untill we pass the biggest input length, here we get max Input length - // and then wait until pass it ... - int maxLength = MathMax(0, length * 3); - - // - limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; - - // - // Main Loop ... - for (int i = limit; i >= 0 && !IsStopped(); i--) - { - // - CalculateBuffers(i); - } - - // - return rates_total; -} -// -// END Event Handlers ... -// - -// -// START Functions ... -// -// -// Validate Input Args for Initialization ... -bool ValidateInputs() -{ - // - bool result = false; - - // - // Validate Args ... - if (length >= 2) - { - result = true; - } - - // - return result; -} - -// -// Define Indexes and Styles ... -void DefineBuffers() -{ - // - ArraySetAsSeries(swingBuffer, true); - SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS); -} - -// -// Set Indicator Short Name and also we can define Buffers Labels ... -void SetIndicatorName() -{ - // - string indicatorShortName = ""; - StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); - - // - IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); -} - -// -// Calculate Buffers ... -void CalculateBuffers(int bar_index) -{ - // - // GetCandleSwing(bar_index); - ENUM_X_SWING_TYPE type = X_NO_SWING; - - // - // Try To Detect Order Blocks ... - bool isSwingLow = false; - bool isSwingHigh = false; - - // - // Reading Candles Data ... - int start = bar_index; - int count = (length * 2) + 2; - int end = start + count; - XOHCL bars[]; - int readedBars = GetBars( - bars, - _Symbol, - _Period, - start, - count - // - ); - if (readedBars < count) { - return; - } - - // - // Swing Low ... - isSwingLow = - // - bars[1].close > bars[2].close && - bars[2].close > bars[3].close && - // - bars[3].close < bars[4].close && - // - bars[5].close > bars[4].close && - bars[6].close > bars[5].close - // - ; - - // - if (isSwingLow) - { - type = X_SWING_LOW; - } - - // - if (!isSwingLow) - { - // - // Swing High ... - isSwingHigh = - // - bars[1].close < bars[2].close && - bars[2].close < bars[3].close && - // - bars[3].close > bars[4].close && - // - bars[5].close < bars[4].close && - bars[6].close < bars[5].close - // - ; - - // - if (isSwingHigh) - { - type = X_SWING_HIGH; - } - } - - // - switch (type) - { - // - // Swing High ... - case X_SWING_HIGH: - // - swingBuffer[bar_index] = type; - DrawSwingArrow(1, bar_index); - break; - - // - // Swinmg Low ... - case X_SWING_LOW: - // - swingBuffer[bar_index] = type; - DrawSwingArrow(0, bar_index); - break; - - // - // No Swing ... - default: - case X_NO_SWING: - // - swingBuffer[bar_index] = 0; - break; - } -} - -// -// Draw a Swing Arrow Shape ... -void DrawSwingArrow( - int type, // Swing Type: 0 - Low / 1 - High ... - int bar_index // -) -{ - // - bool isSwingHigh = type == 1; - - // - if ((isSwingHigh && swingHighArrowCode == 0) || - (!isSwingHigh && swingLowArrowCode == 0)) - { - return; - } - - XOHCL candle; - candle.Init( - _Symbol, - _Period, - bar_index + 3); - double arrowDistanceInPoint = 0; - - // - // Define Required Object Properties fro Draw an Arrow ... - datetime time = iTime(_Symbol, _Period, bar_index + 3); - double purePrice = isSwingHigh ? candle.high : candle.low; - color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor; - ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP; - uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode); - double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint; - string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice; - - // - // Draw desired Arrow ... - DrawArrow( - 0, - name, - 0, - time, - price, - arrowCode, - anchor, - clr); -} -// -// END Functions ... -// diff --git a/Indicators/x-saherelm.xtdp.osc.mq5 b/Indicators/x-saherelm.xtdp.osc.mq5 new file mode 100644 index 00000000..4057a036 --- /dev/null +++ b/Indicators/x-saherelm.xtdp.osc.mq5 @@ -0,0 +1,371 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +#define ShortName "XTDP" + +// +// Imports ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Market Length + +// +input group "Presentation"; +input bool showBullishPower = true; +input bool showBearishPower = true; +input bool showBullishPressure = true; +input bool showBearishPressure = true; +input bool showSignal = true; + +// +// Buffers ... + +// +#property indicator_separate_window + +// +#property indicator_buffers 5 +#property indicator_plots 5 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define bullishPBufferIndex 2 +#define bearishPBufferIndex 3 +#define signalBufferIndex 4 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double bullishPBuffer[]; +double bearishPBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPressure" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPressure" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XBullPow" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrAqua +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +#property indicator_label4 "XBearPow" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrMagenta +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +#property indicator_label5 "XSignal" +#property indicator_type5 DRAW_LINE +#property indicator_color5 clrYellow +#property indicator_style5 STYLE_SOLID +#property indicator_width5 1 + +// +// Event Handlers ... + +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, + open, + high, + low, + close // + ); + } + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + ENUM_DRAW_TYPE bullishDrawType = showBullishPressure ? DRAW_LINE : DRAW_NONE; + string bullishBufferLabel = ShortName + "BullPress " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_TYPE, bullishDrawType); + + // + // Bearish Buffer ... + ENUM_DRAW_TYPE bearishDrawType = showBearishPressure ? DRAW_LINE : DRAW_NONE; + string bearishBufferLabel = ShortName + "BearPress " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_TYPE, bearishDrawType); + + // + // Bullish Buffer ... + ENUM_DRAW_TYPE bullishPDrawType = showBullishPower ? DRAW_LINE : DRAW_NONE; + string bullishPBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishPBuffer, true); + SetIndexBuffer(bullishPBufferIndex, bullishPBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishPBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishPBufferIndex, PLOT_LABEL, bullishPBufferLabel); + PlotIndexSetInteger(bullishPBufferIndex, PLOT_DRAW_TYPE, bullishPDrawType); + + // + // Bearish Buffer ... + ENUM_DRAW_TYPE bearishPDrawType = showBearishPower ? DRAW_LINE : DRAW_NONE; + string bearishPBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishPBuffer, true); + SetIndexBuffer(bearishPBufferIndex, bearishPBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishPBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishPBufferIndex, PLOT_LABEL, bearishPBufferLabel); + PlotIndexSetInteger(bearishPBufferIndex, PLOT_DRAW_TYPE, bearishPDrawType); + + // + // Signal Buffer ... + ENUM_DRAW_TYPE signalDrawType = showSignal ? DRAW_LINE : DRAW_NONE; + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_TYPE, signalDrawType); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[] // History of Close Price ... +) +{ + // + double bullPow = 0; + double bearPow = 0; + double bullPressure = 0; + double bearPressure = 0; + double signal = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + // + double iO = open[i]; + double iH = high[i]; + double iL = low[i]; + double iC = close[i]; + + // + double iUp = MathMax(iO, iC); + double iDown = MathMin(iO, iC); + + // + double iUpShadow = iH - iUp; + double iDownShadow = iDown - iL; + + // + bullPressure += iDownShadow; + bearPressure += iUpShadow; + + // + signal += (iUp - iDown); + + // + // Bearish ... + if (iO > iC) + { + bearPow += signal; + } + + // + // Bullish ... + if (iO < iC) + { + bullPow += signal; + } + } + + // + // Bullish Power Buffer ... + bullishPBuffer[bar_index] = bullPow; + bullishBuffer[bar_index] = bullPressure; + + // + // Bearish Power Buffer ... + bearishPBuffer[bar_index] = bearPow; + bearishBuffer[bar_index] = bearPressure; + + // + // Signal Buffer ... + // signal = length; + signalBuffer[bar_index] = signal; +} + +// diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 65217b17..58af67d8 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -1001,643 +1001,6 @@ struct XOHCL return result; } - // - // Check Bar Is Hammer Pattern ... - bool IsHammer() - { - // - bool result = false; - - // - double fib382 = GetFibonacciLevel( - high, - low, - 0.382, - -1 // - ); - - // - result = GetDown() > fib382; - - // - return result; - } - - // - // Check Bar Is Shooting Star Pattern ... - bool IsShootingStar() - { - // - bool result = false; - - // - double fib382 = GetFibonacciLevel( - high, - low, - 0.382, - 1 // - ); - - // - result = GetUp() < fib382; - - // - return result; - } - - // - // Check Bar Bullish Engulfing Pattern ... - bool IsBullishEngulf() - { - // - bool result = false; - - // - // Current Bar Must be Bullish ... - result = IsBullish(); - if (!result) - { - return result; - } - - // - // Retrieve Previous Bar ... - XOHCL pBar; - result = GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - result = - // - pBar.IsBearish() && - open < pBar.close && close > pBar.open && - high >= pBar.high && low <= pBar.low - // - ; - - // - return result; - } - - // - // Check Bar Bearish Engulfing Pattern ... - bool IsBearishEngulf() - { - // - bool result = false; - - // - // Current Bar Must be Bearish ... - result = IsBearish(); - if (!result) - { - return result; - } - - // - // Retrieve Previous Bar ... - XOHCL pBar; - result = GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - result = - // - pBar.IsBullish() && - open > pBar.close && close < pBar.open && - high >= pBar.high && low <= pBar.low - // - ; - - // - return result; - } - - // - // Check Bar has Strong Body or Not ... - bool HasStrongBody() - { - // - bool result = false; - - // - if (!IsValid()) - { - return result; - } - - // - double body = GetBody(); - double shadow = GetShadows(); - - // - result = body > shadow * 1.5; - - // - return result; - } - - // - // Bar Must Open Below Prce - // and Close Above it ... - bool IsBreakUp( - double price // a Price to Check Breake - ) - { - // - bool result = false; - - // - result = HasStrongBody(); - if (!result || price <= 0) - { - return result; - } - - // - // Select required Prices ... - - // - result = - // - close > price && - open < price; - - // - return result; - } - - // - // Bar Must Open Above Prce - // and Close Below it ... - bool IsBreakDown( - double price // a Price to Check Breake - ) - { - // - bool result = false; - - // - result = HasStrongBody(); - if (!result || price <= 0) - { - return result; - } - - // - // Select required Prices ... - - // - result = - // - open > price && - close < price; - - // - return result; - } - - // - bool IsBreakOut( - double price, // a Price to Check Breake - bool useHighLow = true // if true using High and Low price for Breakeouts, if not use Open Close - ) - { - // - bool result = false; - - // - result = HasStrongBody(); - if (!result || price <= 0) - { - return result; - } - - // - // Select required Prices ... - - // - double selectedUp = - useHighLow - ? high - : GetUp(); - double selectedDown = - useHighLow - ? low - : GetDown(); - - // - result = - // - selectedUp > price && - selectedDown < price; - - // - return result; - } - - // - // Check a Support Line Rejected or not ... - bool IsSupportRejected( - double price // Support Price - ) - { - // - bool result = false; - - // - // this is zBar ... - // so we are try to Recieve CBar ... - XOHCL cBar; - result = this.GetPreviousBar(cBar); - if (!result) - { - return result; - } - - // - // Now we are going to Recieve PBar ... - XOHCL pBar; - result = cBar.GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - // We Have this (0) Bar, cBar (1) and pBar (2) ... - - // - // pBar Down Shadow must break Price Line ... - // cBar and zBar Close must be Above Price Line ... - // also zBar Open must be Above Price Line ... - result = - // - pBar.high > price && - pBar.low < price && - cBar.close > price && - this.close > price && - this.open > price - // - ; - - // - return result; - } - - // - // Check a Support Line Breaked or not ... - bool IsSupportBreaked( - double price // Support Price - ) - { - // - bool result = false; - - // - // this is zBar ... - // so we are try to Recieve CBar ... - XOHCL cBar; - result = this.GetPreviousBar(cBar); - if (!result) - { - return result; - } - - // - // Now we are going to Recieve PBar ... - XOHCL pBar; - result = cBar.GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - // We Have this (0) Bar, cBar (1) and pBar (2) ... - - // - // pBar Down Shadow must break Price Line ... - // cBar and zBar Close must be Below Price Line ... - // also zBar Open must be Below Price Line ... - result = - // - pBar.high > price && - pBar.low < price && - cBar.close < price && - this.close < price && - this.open < price - // - ; - - // - return result; - } - - // - // Check a Resistance Line Rejected or not ... - bool IsResistanceRejected( - double price // Resistance Price - ) - { - // - bool result = false; - - // - // this is zBar ... - // so we are try to Recieve CBar ... - XOHCL cBar; - result = this.GetPreviousBar(cBar); - if (!result) - { - return result; - } - - // - // Now we are going to Recieve PBar ... - XOHCL pBar; - result = cBar.GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - // We Have this (0) Bar, cBar (1) and pBar (2) ... - - // - // pBar Up Shadow must break Price Line ... - // cBar and zBar Close must be Under Price Line ... - // also zBar Open must be Under Price Line ... - result = - // - pBar.high > price && - pBar.low < price && - cBar.close < price && - this.close < price && - this.open < price - // - ; - - // - return result; - } - - // - // Check a Resistance Line Breaked or not ... - bool IsResistanceBreaked( - double price // Support Price - ) - { - // - bool result = false; - - // - // this is zBar ... - // so we are try to Recieve CBar ... - XOHCL cBar; - result = this.GetPreviousBar(cBar); - if (!result) - { - return result; - } - - // - // Now we are going to Recieve PBar ... - XOHCL pBar; - result = cBar.GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - // We Have this (0) Bar, cBar (1) and pBar (2) ... - - // - // pBar Up Shadow must break Price Line ... - // cBar and zBar Close must be Over Price Line ... - // also zBar Open must be Pver Price Line ... - result = - // - pBar.low < price && - pBar.high > price && - cBar.close > price && - this.close > price && - this.open > price - // - ; - - // - return result; - } - - // - // Check Bar is Inside Previus Bar ... - bool IsInsideBar( - double threshold = 5 // Points Distance between Up and Down - ) - { - // - bool result = false; - - // - if (threshold < 0) - { - threshold = 0; - } - - // - XOHCL pBar; - result = GetPreviousBar(pBar); - if (!result) - { - return result; - } - - // - double offset = PointToPrice(threshold, this.symbol); - - // - result = - // - pBar.high > this.high && - pBar.low < this.low && - MathAbs(pBar.low - this.low) > offset && - MathAbs(pBar.high - this.high) > offset - // - ; - - // - return result; - } - - // - // Check Bar has Strongest Body in a Range ... - bool HasStrongestBody( - int mLoopback = 3 // loopback candles to compare it ... - ) - { - // - bool result = false; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - double body = GetBody(); - XOHCL prev = this; - for (int i = 0; i < mLoopback; i++) - { - // - bool isValid = prev.GetPreviousBar(prev); - if (!isValid) - { - // - result = false; - break; - } - - // - result = - // - result && - body > prev.GetBody() - // - ; - if (!result) - { - break; - } - } - - // - return result; - } - - // - // Check Bar has Weakest Body in a Range ... - bool HasWeakestBody( - int mLoopback = 3 // loopback candles to compare it ... - ) - { - // - bool result = false; - - // - result = IsValid(); - if (!result) - { - return result; - } - - // - double body = GetBody(); - XOHCL prev = this; - for (int i = 0; i < mLoopback; i++) - { - // - bool isValid = prev.GetPreviousBar(prev); - if (!isValid) - { - // - result = false; - break; - } - - // - result = - // - result && - body < prev.GetBody() - // - ; - if (!result) - { - break; - } - } - - // - return result; - } - - // - // Determines Swings based On this Bar ... - // Calculates Based on atleast 3 Bars Prev ... - ENUM_X_SWING_TYPE GetSwingType() - { - // - ENUM_X_SWING_TYPE result = X_NO_SWING; - - // - // Find Current Index of Bar ... - int barIndex = Index(); - if (barIndex <= -1) - { - return result; - } - - // - // First we have to Retrieve atleast 3 Bars before this bar ... - XOHCL bars[]; - int barsCount = GetBars( - bars, - symbol, - period, - barIndex + 1, - 3 - // - ); - if (barsCount < 3) - { - return result; - } - - // - // Check Swing Start Candle has Strong Body ... - bool isStrongBodyCandle = bars[2].HasStrongBody(); - if (!isStrongBodyCandle) - { - return result; - } - - // - // Check Swing Low Conditions ... - bool isSwingLowOrderBlock = - bars[2].low < bars[1].low && - bars[1].low < bars[0].low && - bars[2].low < bars[0].low; - if (isSwingLowOrderBlock) - { - result = X_SWING_LOW; - } - - // - // Check Swing High Conditions ... - bool isSwingHighOrderBlock = - bars[2].high > bars[1].high && - bars[1].high > bars[0].high && - bars[2].high > bars[0].high; - if (isSwingHighOrderBlock) - { - result = X_SWING_HIGH; - } - - // - return result; - } - // // Find Lowest Bar Index ... int FindHighestIndex( @@ -1797,9 +1160,88 @@ struct XOHCL } // - // Candlestic Tools ... + // Retrieve Bullish Pressure ... + double GetBullishPressure( + int _loopback = 7 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL bars[]; + int barsCount = GetBars( + bars, + symbol, + period, + Index(), + _loopback // + ); + if (!IsValidSize(barsCount)) + { + return result; + } + + // + for (int i = 0; i < barsCount; i++) + { + result += bars[i].GetLowShadow(); + } + + // + return result; + } // + // Retrieve Bearish Pressure ... + double GetBearishPressure( + int _loopback = 7 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + XOHCL bars[]; + int barsCount = GetBars( + bars, + symbol, + period, + Index(), + _loopback // + ); + if (!IsValidSize(barsCount)) + { + return result; + } + + // + for (int i = 0; i < barsCount; i++) + { + result += bars[i].GetHighShadow(); + } + + // + return result; + } + + // + // Candlestic Patterns ... + + // + // Check Doji ... bool IsDoji() { // @@ -1821,6 +1263,1763 @@ struct XOHCL return result; } + // + // Check Hammer ... + bool IsHammer( + double _upShadowFactor = 0.1, + double _downShadowFactor = 0.6, + bool applyFib382Check = true, + bool applyPrevShadowCheck = true // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_upShadowFactor < 0) + { + _upShadowFactor = 0.1; + } + + // + if (_downShadowFactor < 0) + { + _upShadowFactor = 0.6; + } + + // + double range = GetRange(); + + // + // Check Upper Shadow Must be 0 or Under 10% ... + double upShadow = GetHighShadow(); + result = upShadow < range * _upShadowFactor; + if (!result) + { + return result; + } + + // + // Check Down Shadow Must at least 60% ... + double downShadow = GetLowShadow(); + result = downShadow > range * _downShadowFactor; + if (!result) + { + return result; + } + + // + // Check Fib 382 ... + if (result && applyFib382Check) + { + // + double fib382 = GetFibonacciLevel( + high, + low, + 0.382, + -1 // + ); + result = GetDown() > fib382; + } + + // + // Check Shadow Based on Prev Bar ... + if (result && applyPrevShadowCheck) + { + // + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + result = low < pBar.low; + } + + // + return result; + } + + // + // Check Sgooting Star ... + // Reversal Hammer ... + bool IsShootingStar( + double _upShadowFactor = 0.6, + double _downShadowFactor = 0.1, + bool applyFib382Check = true, + bool applyPrevShadowCheck = true // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_upShadowFactor < 0) + { + _upShadowFactor = 0.6; + } + + // + if (_downShadowFactor < 0) + { + _upShadowFactor = 0.1; + } + + // + double range = GetRange(); + + // + // Check Upper Shadow Must be 0 or Under 10% ... + double upShadow = GetHighShadow(); + result = upShadow > range * _upShadowFactor; + if (!result) + { + return result; + } + + // + // Check Down Shadow Must at least 60% ... + double downShadow = GetLowShadow(); + result = downShadow < range * _downShadowFactor; + if (!result) + { + return result; + } + + // + // Check Fib 382 ... + if (result && applyFib382Check) + { + // + double fib382 = GetFibonacciLevel( + high, + low, + 0.382, + 1 // + ); + result = GetUp() < fib382; + } + + // + // Check Shadow Based on Prev Bar ... + if (result && applyPrevShadowCheck) + { + // + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + result = high > pBar.high; + } + + // + return result; + } + + // + // Check Bullish Engulfing ... + bool IsBullishEngulfing( + double _engulfBarBodyFactor = 0.7 // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_engulfBarBodyFactor < 0) + { + _engulfBarBodyFactor = 0.7; + } + + // + // Check Bar Is Bullish ... + result = IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + double range = GetRange(); + double body = GetBody(); + + // + // Check Prev Bar Must Bearish ... + result = pBar.IsBearish(); + if (!result) + { + return result; + } + + // + // Check Shadows Engulf Prev Bar ... + result = + // + high > pBar.high && + low <= pBar.low + // + ; + if (!result) + { + return result; + } + + // + // Check Engulfed Bar Must Inside Engulfer Body ... + result = + // + GetUp() > pBar.GetUp() && + GetDown() < pBar.GetDown() + // + ; + if (!result) + { + return result; + } + + // + // Check Body of Engulfing Bar ... + if (result && _engulfBarBodyFactor > 0) + { + result = body >= range * _engulfBarBodyFactor; + } + + // + return result; + } + + // + // Check Bearish Engulfing ... + bool IsBearishEngulfing( + double _engulfBarBodyFactor = 0.7 // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_engulfBarBodyFactor < 0) + { + _engulfBarBodyFactor = 0.7; + } + + // + // Check Bar Is Bearish ... + result = IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + double range = GetRange(); + double body = GetBody(); + + // + // Check Prev Bar Must Bullish ... + result = pBar.IsBullish(); + if (!result) + { + return result; + } + + // + // Check Shadows Engulf Prev Bar ... + result = high >= pBar.high && low < pBar.low; + if (!result) + { + return result; + } + + // + // Check Engulfed Bar Must Inside Engulfer Body ... + result = + // + GetUp() > pBar.GetUp() && + GetDown() < pBar.GetDown() + // + ; + if (!result) + { + return result; + } + + // + // Check Body of Engulfing Bar ... + if (result && _engulfBarBodyFactor > 0) + { + result = body >= range * _engulfBarBodyFactor; + } + + // + return result; + } + + // + // Check Morning Star Pattern ... + bool IsMorningStar( + double _middleRangeFactor = 0.3, + double _startBodyFactor = 0.6, + bool forceCheckMiddleBarDirection = true, + bool forceCheckStartBody = true // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_middleRangeFactor < 0) + { + _middleRangeFactor = 0.3; + } + + // + if (_startBodyFactor < 0) + { + _startBodyFactor = 0.6; + } + + // + // Current Bar Must be Bullish ... + result = IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar must be Bearish ... + if (result && forceCheckMiddleBarDirection) + { + // + result = pBar.IsBearish(); + if (!result) + { + return result; + } + } + + // + // Retrieve Previous Bar of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev Of Prev Bar Must be Bearish ... + result = ppBar.IsBearish(); + if (!result) + { + return result; + } + + // + double range = GetRange(); + double pRange = pBar.GetRange(); + double ppRange = ppBar.GetRange(); + + // + // Middle Bar must be Smaller than Ratio of other ... + result = + // + pRange < range * _middleRangeFactor && + pRange < ppRange * _middleRangeFactor + // + ; + if (!result) + { + return result; + } + + // + if (result && forceCheckStartBody) + { + // + result = ppBar.GetBody() > ppRange * _startBodyFactor; + if (!result) + { + return result; + } + } + + // + return result; + } + + // + // Check Evening Star Pattern ... + bool IsEveningStar( + double _middleRangeFactor = 0.3, + double _startBodyFactor = 0.6, + bool forceCheckMiddleBarDirection = true, + bool forceCheckStartBody = true // + ) + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + if (_middleRangeFactor < 0) + { + _middleRangeFactor = 0.3; + } + + // + if (_startBodyFactor < 0) + { + _startBodyFactor = 0.6; + } + + // + // Current Bar Must be Bearish ... + result = IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Previous Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar must be Bullish ... + if (result && forceCheckMiddleBarDirection) + { + // + result = pBar.IsBullish(); + if (!result) + { + return result; + } + } + + // + // Retrieve Previous Bar of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev Of Prev Bar Must be Bullish ... + result = ppBar.IsBullish(); + if (!result) + { + return result; + } + + // + double range = GetRange(); + double pRange = pBar.GetRange(); + double ppRange = ppBar.GetRange(); + + // + // Middle Bar must be Smaller than Ratio of other ... + result = + // + pRange < range * _middleRangeFactor && + pRange < ppRange * _middleRangeFactor + // + ; + if (!result) + { + return result; + } + + // + if (result && forceCheckStartBody) + { + // + result = ppBar.GetBody() > ppRange * _startBodyFactor; + if (!result) + { + return result; + } + } + + // + return result; + } + + // + // Contextual Patterns ... + + // + // Check Swing High ... + bool IsSwingHigh() + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + // Current Bar Must be Bearish ... + result = IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar Must be Bullish ... + result = pBar.IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev of Prev Bar Must be Bullish ... + result = ppBar.IsBullish(); + if (!result) + { + return result; + } + + // + // Check All Highs ... + result = + // + high < pBar.high && + pBar.high > ppBar.high + // + ; + + // + return result; + } + + // + // Check Swing Low ... + bool IsSwingLow() + { + // + bool result = false; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + // Current Bar Must be Bullish ... + result = IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar Must be Bearish ... + result = pBar.IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev of Prev Bar Must be Bearish ... + result = ppBar.IsBearish(); + if (!result) + { + return result; + } + + // + // Check All Lows ... + result = + // + low > pBar.low && + pBar.low < ppBar.low + // + ; + + // + return result; + } + + // + // Check Bullish FVG ... + bool HasBullishFVG( + double &upper, + double &lower, + bool forceMiddleBarCheck = true // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + // Current Bar Must be Bullish ... + result = IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar Must be Bullish ... + result = pBar.IsBullish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev of Prev Bar Must be Bullish ... + result = ppBar.IsBullish(); + if (!result) + { + return result; + } + + // + // Other Conditions ... + result = + // + low > ppBar.high + // + ; + + // + // Check Middle Bar Range ... + if (result && forceMiddleBarCheck) + { + // + result = + // + pBar.high > low && + pBar.low < ppBar.high + // + ; + + // + if (!result) + { + return result; + } + } + + // + if (result) + { + // + upper = low; + lower = ppBar.high; + } + + // + return result; + } + + // + // Check Bearish FVG ... + bool HasBearishFVG( + double &upper, + double &lower, + bool forceMiddleBarCheck = true // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + + // + // Validate Content and Ignore 0 Bar + // since it is not Completed ... + result = IsValid() && Index() > 0; + if (!result) + { + return result; + } + + // + // Current Bar Must be Bearish ... + result = IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev Bar ... + XOHCL pBar; + result = GetPreviousBar(pBar); + if (!result) + { + return result; + } + + // + // Prev Bar Must be Bearish ... + result = pBar.IsBearish(); + if (!result) + { + return result; + } + + // + // Retrieve Prev of Prev Bar ... + XOHCL ppBar; + result = pBar.GetPreviousBar(ppBar); + if (!result) + { + return result; + } + + // + // Prev of Prev Bar Must be Bearish ... + result = ppBar.IsBearish(); + if (!result) + { + return result; + } + + // + // Other Conditions ... + result = + // + high < ppBar.low + // + ; + + // + // Check Middle Bar Range ... + if (result && forceMiddleBarCheck) + { + // + result = + // + pBar.high > low && + pBar.low < ppBar.high + // + ; + + // + if (!result) + { + return result; + } + } + + // + if (result) + { + // + upper = ppBar.low; + lower = high; + } + + // + return result; + } + + // + // Find Support ... + bool HasSupport( + double &support, + datetime &at, + ENUM_X_PRICE type = X_PRICE_CLOSE, + int loopback = 21, + int tries = 100 // + ) + { + // + bool result = false; + + // + at = NULL; + support = 0; + + // + if (loopback < 0) + { + loopback = 21; + } + + // + if (tries < 0) + { + tries = 100; + } + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double price = GetPrice(type); + + // + for (int i = 1; i < tries; i++) + { + // + int length = loopback * i; + + // + int lowestIDX = FindLowestIndex( + length, + MODE_LOW // + ); + result = IsValidSize(lowestIDX); + if (!result) + { + break; + } + + // + XOHCL iLBar; + result = iLBar.Init( + symbol, + period, + lowestIDX // + ); + if (!result) + { + break; + } + + // + result = + // + price > iLBar.high + // + ; + if (result) + { + // + at = iLBar.time; + support = iLBar.high; + break; + } + } + + // + return result; + } + + // + // Find Resistance ... + bool HasResistance( + double &resistance, + datetime &at, + ENUM_X_PRICE type = X_PRICE_CLOSE, + int loopback = 21, + int tries = 100 // + ) + { + // + bool result = false; + + // + at = NULL; + resistance = 0; + + // + if (loopback < 0) + { + loopback = 21; + } + + // + if (tries < 0) + { + tries = 100; + } + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double price = GetPrice(type); + + // + for (int i = 1; i < tries; i++) + { + // + int length = loopback * i; + + // + int highestIDX = FindHighestIndex( + length, + MODE_LOW // + ); + result = IsValidSize(highestIDX); + if (!result) + { + break; + } + + // + XOHCL iHBar; + result = iHBar.Init( + symbol, + period, + highestIDX // + ); + if (!result) + { + break; + } + + // + result = + // + price < iHBar.high + // + ; + if (result) + { + // + at = iHBar.time; + resistance = iHBar.high; + break; + } + } + + // + return result; + } + + // + // Trend Detection ... + + // + // Find Bullish Trend ... + bool HasBullishTrend( + double &highSwings[], + datetime &highSwingTimes[], + double &lowSwings[], + datetime &lowSwingTimes[], + bool forceMethod2 = false, + int loopback = 3, + int tries = 3, + ENUM_X_PRICE type = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + Clean(lowSwings); + Clean(lowSwingTimes); + Clean(highSwings); + Clean(highSwingTimes); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double price = GetPrice(type); + + // + int lastIDX = Index(); + double lastH = 0; + double lastL = 0; + for (int i = 1; i < tries + 1; i++) + { + // + // Use Regular Method ... + if (!forceMethod2) + { + // + int iHIDX = FindSwing( + symbol, + period, + X_SWING_HIGH, + loopback, + lastIDX // + ); + result = IsValidIndex(iHIDX); + if (!result) + { + break; + } + + // + XOHCL iHBar; + result = iHBar.Init( + symbol, + period, + iHIDX // + ); + if (!result) + { + break; + } + + // + double iH = iHBar.high; + bool isIHAccepted = + // + iH > 0 && + ( + // + lastH == 0 + ? true + : iH < lastH + // + ) + // + ; + if (isIHAccepted) + { + // + Add( + iH, + highSwings // + ); + + // + Add( + iHBar.time, + highSwingTimes // + ); + + // + lastH = iH; + lastIDX = iHIDX; + } + + // + int iLIDX = FindSwing( + symbol, + period, + X_SWING_LOW, + loopback, + lastIDX // + ); + result = IsValidIndex(iLIDX); + if (!result) + { + break; + } + + // + XOHCL iLBar; + result = iLBar.Init( + symbol, + period, + iLIDX // + ); + if (!result) + { + break; + } + + // + double iL = iLBar.low; + bool isILAccepted = + // + iL > 0 && + ( + // + lastL == 0 + ? true + : iL < lastL + // + ) + // + ; + if (isILAccepted) + { + // + Add( + iL, + lowSwings // + ); + + // + Add( + iLBar.time, + lowSwingTimes // + ); + + // + lastL = iL; + lastIDX = iLIDX; + } + } + // + // Use Other MEthod ... + else + { + // + int length = i * loopback; + int start = + // + i == 1 + ? 1 + : length - loopback + // + ; + + // + int iHIDX = iHighest( + symbol, + period, + MODE_HIGH, + loopback, + start // + ); + result = IsValidIndex(iHIDX); + if (!result) + { + break; + } + + // + XOHCL iHBar; + result = iHBar.Init( + symbol, + period, + iHIDX // + ); + if (!result) + { + break; + } + + // + double iH = iHBar.high; + bool isIHAccepted = + // + iH > 0 && + ( + // + lastH == 0 + ? true + : iH < lastH + // + ) + // + ; + if (isIHAccepted) + { + // + Add( + iH, + highSwings // + ); + + // + Add( + iHBar.time, + highSwingTimes // + ); + + // + lastH = iH; + lastIDX = iHIDX; + } + + // + int iLIDX = iLowest( + symbol, + period, + MODE_LOW, + loopback, + start // + ); + result = IsValidIndex(iLIDX); + if (!result) + { + break; + } + + // + XOHCL iLBar; + result = iLBar.Init( + symbol, + period, + iLIDX // + ); + if (!result) + { + break; + } + + // + double iL = iLBar.low; + bool isILAccepted = + // + iL > 0 && + ( + // + lastL == 0 + ? true + : iL < lastL + // + ) + // + ; + if (isILAccepted) + { + // + Add( + iL, + lowSwings // + ); + + // + Add( + iLBar.time, + lowSwingTimes // + ); + + // + lastL = iL; + lastIDX = iLIDX; + } + } + } + + // + if (result) + { + // + result = + // + ArraySize(lowSwings) == tries && + ArraySize(highSwings) == tries + // + ; + } + + // + if (!result) + { + // + Clean(lowSwings); + Clean(lowSwingTimes); + Clean(highSwings); + Clean(highSwingTimes); + } + + // + return result; + } + + // + // Find Bearish Trend ... + bool HasBearishTrend( + double &highSwings[], + datetime &highSwingTimes[], + double &lowSwings[], + datetime &lowSwingTimes[], + bool forceMethod2 = false, + int loopback = 3, + int tries = 3, + ENUM_X_PRICE type = X_PRICE_CLOSE // + ) + { + // + bool result = false; + + // + Clean(lowSwings); + Clean(lowSwingTimes); + Clean(highSwings); + Clean(highSwingTimes); + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + double price = GetPrice(type); + + // + int lastIDX = Index(); + double lastH = 0; + double lastL = 0; + for (int i = 1; i < tries + 1; i++) + { + // + // Use Regular Method ... + if (!forceMethod2) + { + // + int iHIDX = FindSwing( + symbol, + period, + X_SWING_HIGH, + loopback, + lastIDX // + ); + result = IsValidIndex(iHIDX); + if (!result) + { + break; + } + + // + XOHCL iHBar; + result = iHBar.Init( + symbol, + period, + iHIDX // + ); + if (!result) + { + break; + } + + // + double iH = iHBar.high; + bool isIHAccepted = + // + iH > 0 && + ( + // + lastH == 0 + ? true + : iH > lastH + // + ) + // + ; + if (isIHAccepted) + { + // + Add( + iH, + highSwings // + ); + + // + Add( + iHBar.time, + highSwingTimes // + ); + + // + lastH = iH; + lastIDX = iHIDX; + } + + // + int iLIDX = FindSwing( + symbol, + period, + X_SWING_LOW, + loopback, + lastIDX // + ); + result = IsValidIndex(iLIDX); + if (!result) + { + break; + } + + // + XOHCL iLBar; + result = iLBar.Init( + symbol, + period, + iLIDX // + ); + if (!result) + { + break; + } + + // + double iL = iLBar.low; + bool isILAccepted = + // + iL > 0 && + ( + // + lastL == 0 + ? true + : iL > lastL + // + ) + // + ; + if (isILAccepted) + { + // + Add( + iL, + lowSwings // + ); + + // + Add( + iLBar.time, + lowSwingTimes // + ); + + // + lastL = iL; + lastIDX = iLIDX; + } + } + // + // Use Other MEthod ... + else + { + // + int length = i * loopback; + int start = + // + i == 1 + ? 1 + : length - loopback + // + ; + + // + int iHIDX = iHighest( + symbol, + period, + MODE_HIGH, + loopback, + start // + ); + result = IsValidIndex(iHIDX); + if (!result) + { + break; + } + + // + XOHCL iHBar; + result = iHBar.Init( + symbol, + period, + iHIDX // + ); + if (!result) + { + break; + } + + // + double iH = iHBar.high; + bool isIHAccepted = + // + iH > 0 && + ( + // + lastH == 0 + ? true + : iH > lastH + // + ) + // + ; + if (isIHAccepted) + { + // + Add( + iH, + highSwings // + ); + + // + Add( + iHBar.time, + highSwingTimes // + ); + + // + lastH = iH; + lastIDX = iHIDX; + } + + // + int iLIDX = iLowest( + symbol, + period, + MODE_LOW, + loopback, + start // + ); + result = IsValidIndex(iLIDX); + if (!result) + { + break; + } + + // + XOHCL iLBar; + result = iLBar.Init( + symbol, + period, + iLIDX // + ); + if (!result) + { + break; + } + + // + double iL = iLBar.low; + bool isILAccepted = + // + iL > 0 && + ( + // + lastL == 0 + ? true + : iL > lastL + // + ) + // + ; + if (isILAccepted) + { + // + Add( + iL, + lowSwings // + ); + + // + Add( + iLBar.time, + lowSwingTimes // + ); + + // + lastL = iL; + lastIDX = iLIDX; + } + } + } + + // + if (result) + { + // + result = + // + ArraySize(lowSwings) == tries && + ArraySize(highSwings) == tries + // + ; + } + + // + if (!result) + { + // + Clean(lowSwings); + Clean(lowSwingTimes); + Clean(highSwings); + Clean(highSwingTimes); + } + + // + return result; + } + + // + // Order Blocks ... + + // + // Supply and Demand ... + + // + // Other ... + // // Convert to String Representation ... string ToString() @@ -3251,7 +4450,8 @@ struct XSymbolParser // // Symbol Finder ... - string GetEURUSDSymbol() { + string GetEURUSDSymbol() + { // string result = NULL; @@ -3260,15 +4460,18 @@ struct XSymbolParser int symbolsCount = GetAllSymbols( symbols // ); - if (!IsValidSize(symbolsCount)) { + if (!IsValidSize(symbolsCount)) + { return result; } // - for (int i = 0; i < symbolsCount; i++) { + for (int i = 0; i < symbolsCount; i++) + { // string iSymbol = symbols[i]; - if (IsEURUSD(iSymbol)) { + if (IsEURUSD(iSymbol)) + { // result = iSymbol; break; @@ -3278,7 +4481,6 @@ struct XSymbolParser // return result; } - }; // @@ -6099,6 +7301,54 @@ double GetNormalizedValueMethod2( return result; } +// +void NormalizeBuffer( + double &source[], // Source Buffer + double &dest[], // Result Buffer + double upper = 100, // Upper Value to Normalize + double lower = -100, // Lower Value to Normalize + int size = -1, // Size Of Normalization + int digits = 5 // Digits for Result +) +{ + // + if (size <= 0) + { + size = ArraySize(source); + } + + // + bool asSeriesFlag = ArrayGetAsSeries(source); + + // + ArraySetAsSeries(source, false); + ArraySetAsSeries(dest, false); + + // + double min = ArrayMinimum(source, 0, size); + double max = ArrayMaximum(source, 0, size); + + // + for (int i = 0; i < size; i++) + { + // + double iNormal = lower + ((source[i] - min) / (max - min)) * (upper - lower); + + // + if (digits > 0) + { + iNormal = NormalizeDouble(iNormal, digits); + } + + // + dest[i] = iNormal; + } + + // + ArraySetAsSeries(source, asSeriesFlag); + ArraySetAsSeries(dest, asSeriesFlag); +} + // // Templates ... diff --git a/Libraries/x-saherelm.draw.lib.mq5 b/Libraries/x-saherelm.draw.lib.mq5 index b71f62a6..8a25d52d 100644 --- a/Libraries/x-saherelm.draw.lib.mq5 +++ b/Libraries/x-saherelm.draw.lib.mq5 @@ -980,10 +980,10 @@ bool DrawRectangle( const long chartID = 0, // chart's ID const string name = "Rectangle", // rectangle name const int subWindow = 0, // subwindow index - datetime time1 = 0, // first point time - double price1 = 0, // first point price - datetime time2 = 0, // second point time - double price2 = 0, // second point price + datetime time1 = 0, // down first point time + double price1 = 0, // down first point price + datetime time2 = 0, // up second point time + double price2 = 0, // up second point price const color clr = clrRed, // rectangle color const ENUM_LINE_STYLE style = STYLE_SOLID, // style of rectangle lines const int width = 1, // width of rectangle lines