diff --git a/MQLTestWorkspace/BKPS/Templates/x-saherelm.x121.provider.class.mq5 b/MQLTestWorkspace/BKPS/Templates/x-saherelm.x121.provider.class.mq5 new file mode 100644 index 0000000..b9ef47a --- /dev/null +++ b/MQLTestWorkspace/BKPS/Templates/x-saherelm.x121.provider.class.mq5 @@ -0,0 +1,1849 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Provider +// Description: X121 Signal Provider ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Classes/x-saherelm.xprovider.class.mq5" +#include "../Helpers/x-saherelm.x121.xman.helper.class.mq5" + +// +// Library ... +#include "../Libraries/x-saherelm.seriallizer.lib.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// Here we Have to Define an Input Structure Model +// for Provider Class to Handle Helpers Definitions ... +struct X121ProviderInputs +{ + // + // XMAN ... + XMANInputs xmanConfig; +}; + +// +// Model Market Sense based On Current Captured conditions ... +struct X121MarketConditions +{ + // + // Commonly Used Info ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + XCandleRemains barRemains; + + // + // Bar Index ... + int barIndex; + + // + // Check Current Market Condition has Signal or not ... + bool hasSignal; + + // + // If has any Signal, Models it's related info here ... + XSignal signal; + + // + // Support and Resistances ... + // if provides Signal ... + XOHCLSupRes supportResistances; + + // + // Change Price Steps ... + double momentumStep; + + // + XOHCL candles[]; + + // + // INDICATORS Market Sense ... + + // + // XMAN ... + XMANInfo xmanInfo; +}; + +// +#include "../Libraries/x-saherelm.x121.condition.parser.lib.mq5" + +// +// Notified a Signal was Appears ... +typedef void (*TOnSignalConditions)( + X121MarketConditions &info); + +// +// All Available Signal Types ... +enum ENUM_X121_SIGNAL_PROVIDERS +{ + NONE, // NONE ... + XTEST, // TEST ... + X786, // Hadi Khazaee Asl ... + X92, // Hadi Khazaee Asl ... +}; + +// +// END Definitions ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Base Class for All of our EA's ... +class XSCX121Provider : public XSCEABaseProvider +{ + // + // Public ... +public: + // + // Props ... + X121ProviderInputs providedConfig; + X121ProviderInputs currentConfig; + X121ProviderInputs cleanConfig; + + // + // Indicator Helper Classes Instance ... + + // + // XMAN ... + XSCXMANHelper *mXManHelper; + + // + // Pivot Points ... + + // + // Hull and SSL Pivot Points ... + double upZonePivots[]; + double downZonePivots[]; + + // + // Peaks and Vales Verifications Number ... + double peakPivots[]; + double valePivots[]; + + // + double cyclesHHPivots[]; + double cyclesLLPivots[]; + + // + double fibPivots[]; + + // + int pivotsSequentialCount; + + // + // Constructor ... + void XSCX121Provider( + string symbol, // Trading Symbol ... + ENUM_TIMEFRAMES period // Trading Time Frame ... + ) : XSCEABaseProvider(symbol, period) + { + // + mMinPivots = 200; + pivotsSequentialCount = 72; + + // + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCX121Provider() + { + // + // De construct Helpers ... + delete mXManHelper; + } + + // + virtual void PrepareTag() + { + mTag = "X121Provider((" + mSymbol + ")(" + ToString(mPeriod) + ")"; + } + + // + virtual bool Init() + { + // + bool result = false; + + // + // Instantiate all Indicators Helper Classes ... + + // + // XMAN ... + mXManHelper = new XSCXMANHelper( + mSymbol, + mPeriod); + result = mXManHelper.SetConfig(currentConfig.xmanConfig); + + // + return result; + } + + // + virtual int GetMaxLength() + { + // + int result = -1; + + // + result = MathMax(result, mXManHelper.GetMaxLength()); + + // + return result; + } + + // + virtual int GetCalculatedBars() + { + // + int result = -1; + + // + int mXManBars = mXManHelper.GetCalculatedBars(); + + // + int min = MathMin(1, mXManBars); + + // + int max = MathMax(1, mXManBars); + + // + result = min; + + // + return result; + } + + // + virtual void ProcessBuffers() + { + UpdatePivotPoints(); + } + + // + virtual bool ProcessTick(X121MarketConditions &conditions) + { + // + if (CanIgnoreTick()) + { + return false; + } + + // + return ProcessSignals(conditions); + } + + // + int GetMinPivots() + { + return mMinPivots; + } + + // + X121ProviderInputs GetConfig() + { + // + X121ProviderInputs result; + + // + result = currentConfig; + + // + return result; + } + + // + // Set Available Signallers ... + bool SetSignallers( + string &signallers[]) + { + // + bool result = false; + + // + result = ArraySize(signallers) > 0; + if (!result) + { + return result; + } + + // + Copy( + signallers, + mSignallers); + + // + return result; + } + + // + bool SetConfig(X121ProviderInputs &config) + { + // + bool result = false; + + // + PrepareConfig(config); + + // + result = Init(); + + // + return result; + } + + // + bool ResetDefaultConfig() + { + // + bool result = SetConfig(providedConfig); + + // + return result; + } + + // + bool ShowCleanConfig() + { + // + currentConfig = cleanConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool ShowDefaultConfig() + { + // + currentConfig = providedConfig; + + // + bool result = Init(); + + // + return result; + } + + // + bool IsAllowedSignaller( + ENUM_X121_SIGNAL_PROVIDERS provider // Signal Provider + ) + { + // + bool result = false; + + // + string providerStr = ToString(provider); + + // + result = Contains( + providerStr, + mSignallers); + + // + return result; + } + + // + // Generate Market Sense ... + X121MarketConditions GetMarketConditions( + int barIndex // Specified Bar Index + ) + { + // + X121MarketConditions result; + + // + // Fill Common Data ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barIndex = barIndex; + + // + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + result.barTime = barTime; + + // + int remainedCandle = barIndex > 0 + ? barIndex - 1 + : barIndex; + GetCandleRemainsTime( + result.barRemains, + mSymbol, + mPeriod, + remainedCandle); + + // + // Attach Candles Info in XOHCL Model to Conditions ... + int mLoopBackBars = mXManHelper.Loopback(); + XOHCL candles[]; + GetCandles( + candles, + mSymbol, + mPeriod, + 0, + mLoopBackBars); + Copy( + candles, + result.candles); + Clean(candles); + + // + result.xmanInfo = mXManHelper.GetInfo(barIndex); + + // + return result; + } + + // + bool GuardCheck(XGuard &guards[]) + { + // + bool result = false; + + // + Clean(guards); + + // + // Implement Guards Check ... + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // X786 ... + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + } + + // + result = ArraySize(guards) > 0; + + // + return result; + } + + // + // Add Specific On SignalConditions Event Handler ... + int AddOnSignalConditionEventHandler(TOnSignalConditions handler) + { + // + ArrayResize( + mSignalConditionsEventHandlers, + ArraySize(mSignalConditionsEventHandlers) + 1); + + // + int result = ArraySize(mSignalConditionsEventHandlers) - 1; + mSignalConditionsEventHandlers[result] = handler; + + // + return result; + } + + // + // Remove All On Signal Event Handler ... + void ReoveOnSignalEventHandlers() + { + // + ArrayFree(mSignalConditionsEventHandlers); + } + + // + // Notify a Signal Found on all Event Listeners ... + void NotifyOnSignalConditionsEvent(X121MarketConditions &info) + { + // + int listenerCount = ArraySize(mSignalConditionsEventHandlers); + if (listenerCount <= 0) + { + return; + } + + // + // Loop Through Listeners ... + for (int i = 0; i < listenerCount; i++) + { + // + TOnSignalConditions listener = mSignalConditionsEventHandlers[i]; + + // + listener(info); + } + } + + // + // PIVOTS ... + + // + // Start Pivots Scanning on Instance Creation ... + void ProccessPivotPoints() + { + // + if (mStartPivotScan) + { + return; + } + + // + mStartPivotScan = true; + + // + int scanSize = iBars( + mSymbol, + mPeriod) - + 500; + + // + for (int i = 1; i < scanSize; i++) + { + // + UpdatePivotPoints(i); + + // + int pivotsCount = CountPivots(); + if (pivotsCount >= mMinPivots) + { + break; + } + } + } + + // + // Count Current Pivots ... + int CountPivots() + { + // + int pivotSizes[]; + + // + int upZoneCount = ArraySize(upZonePivots); + if (upZoneCount > 0) + { + // + Add( + upZoneCount, + pivotSizes); + } + + // + int downZoneCount = ArraySize(downZonePivots); + if (downZoneCount > 0) + { + // + Add( + downZoneCount, + pivotSizes); + } + + // + int peaksCount = ArraySize(peakPivots); + if (peaksCount > 0) + { + // + Add( + peaksCount, + pivotSizes); + } + + // + int valesCount = ArraySize(valePivots); + if (valesCount > 0) + { + // + Add( + valesCount, + pivotSizes); + } + + // + int fibsCount = ArraySize(fibPivots); + if (fibsCount > 0) + { + // + Add( + fibsCount, + pivotSizes); + } + + // + int cyclesHHsCount = ArraySize(cyclesHHPivots); + if (cyclesHHsCount > 0) + { + // + Add( + cyclesHHsCount, + pivotSizes); + } + + // + int cyclesLLsCount = ArraySize(cyclesLLPivots); + if (cyclesLLsCount > 0) + { + // + Add( + cyclesHHsCount, + pivotSizes); + } + + // + int result = ArraySize(pivotSizes) > 0 + ? pivotSizes[ArrayMaximum(pivotSizes)] + : 0; + + // + return result; + } + + // + // Generate Exists Support and Resistance based on Given Price ... + XOHCLSupRes GenerateSupportAndResistance( + double price, // Specified Price + int count = 10 // Number of Pivots in Each Side + ) + { + // + XOHCLSupRes result; + + // + UpdatePivotPoints(0); + + // + double pivots[]; + FillPivotPoints(pivots); + + // + // Generate Support and Resistances ... + result = ExtractSupportAndResistance( + price, + pivots, + count); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // CCandle Timer ... + int mCTimerHandler; + + // + // Signal Event Handlers ... + TOnSignalConditions mSignalConditionsEventHandlers[]; + + // + // Make Provided Config in Clean Style ... + void PrepareConfig(X121ProviderInputs &config) + { + // + cleanConfig = config; + + // + // XMAN ... + cleanConfig.xmanConfig.showCandleTimer = false; + cleanConfig.xmanConfig.showCandles = false; + cleanConfig.xmanConfig.showHKCandles = false; + cleanConfig.xmanConfig.showPeaksAndVales = false; + cleanConfig.xmanConfig.showTrends = false; + cleanConfig.xmanConfig.fillTrends = false; + cleanConfig.xmanConfig.showLevels = false; + cleanConfig.xmanConfig.showConsolidations = false; + cleanConfig.xmanConfig.showRibbons = false; + cleanConfig.xmanConfig.showHull = false; + cleanConfig.xmanConfig.showSSLChannel = false; + cleanConfig.xmanConfig.showFibo1Levels = false; + cleanConfig.xmanConfig.showFibo2Levels = false; + cleanConfig.xmanConfig.showFibo3Levels = false; + + // + providedConfig = config; + currentConfig = config; + } + + // + void Calculate(int barIndex) + { + // + mXManHelper.Calculate(barIndex); + } + + // + int mMinPivots; + bool mStartPivotScan; + double mLastMomentumStep; + + // + // Find Required Pivots for Support and Resistance ... + void UpdatePivotPoints( + int barIndex = 0 // Specified Candle ... + ) + { + // + Calculate(barIndex); + + // + // Detect Peask and Vales Pivots ... + + // + // Detect Hull Pivots ... + // find Hull Trend Changes ... + int idx = 0; + + // + // Retrieve XMan Info ... + // since it's the only one Indicator which provides Data here ... + XMANInfo info = mXManHelper.GetInfo(barIndex); + + // + // Define some Variable to count Verified Sequences ... + int fib1Verified = 0; + int fib2Verified = 0; + int fib3Verified = 0; + int peakVerified = 0; + int valeVerified = 0; + int scHHVerified = 0; + int scLLVerified = 0; + int mcHHVerified = 0; + int mcLLVerified = 0; + int lcHHVerified = 0; + int lcLLVerified = 0; + int hcHHVerified = 0; + int hcLLVerified = 0; + + // + // Here we have to select Points to verify their Sequential repeats ... + + // + // Slect Fibonacci Values ... + double selectedFib1 = info.fibLevel1s[idx]; + double selectedFib2 = info.fibLevel2s[idx]; + double selectedFib3 = info.fibLevel3s[idx]; + + // + // Select Peaks and Vales ... + double selectedPeak = info.peaks[idx]; + double selectedVale = info.vales[idx]; + + // + // Select Cycles Highest Highs ... + double selectedSCHH = info.sHHs[idx]; + double selectedMCHH = info.mHHs[idx]; + double selectedLCHH = info.lHHs[idx]; + double selectedHCHH = info.hHHs[idx]; + + // + // Select Cycles Lowest Lows ... + double selectedSCLL = info.sLLs[idx]; + double selectedMCLL = info.mLLs[idx]; + double selectedLCLL = info.lLLs[idx]; + double selectedHCLL = info.hLLs[idx]; + + // + // Now we Have to Loop Bars Until Fillup Required + // Pivots or END available Bars ... + int startIndex = idx; + int endIndex = pivotsSequentialCount + idx + 1; + for (int i = startIndex; i < endIndex; i++) + { + // + int idx = i - startIndex; + + // + // Now We Have to Compare each Selected Value with indexed value ... + + // + // Peaks ... + if (selectedPeak == info.peaks[i]) + { + peakVerified++; + } + else + { + peakVerified = 0; + } + + // + // Vales ... + if (selectedVale == info.vales[i]) + { + valeVerified++; + } + else + { + valeVerified = 0; + } + + // + // Fibo 1 ... + if (selectedFib1 == info.fibLevel1s[i]) + { + fib1Verified++; + } + else + { + fib1Verified = 0; + } + + // + // Fibo 2 ... + if (selectedFib2 == info.fibLevel2s[i]) + { + fib2Verified++; + } + else + { + fib2Verified = 0; + } + + // + // Fibo 3 ... + if (selectedFib3 == info.fibLevel3s[i]) + { + fib3Verified++; + } + else + { + fib3Verified = 0; + } + + // + // SCHH ... + if (selectedSCHH == info.sHHs[i]) + { + scHHVerified++; + } + else + { + scHHVerified = 0; + } + + // + // SCLL ... + if (selectedSCLL == info.sLLs[i]) + { + scLLVerified++; + } + else + { + scLLVerified = 0; + } + + // + // MCHH ... + if (selectedMCHH == info.mHHs[i]) + { + mcHHVerified++; + } + else + { + mcHHVerified = 0; + } + + // + // MCLL ... + if (selectedMCLL == info.mLLs[i]) + { + mcLLVerified++; + } + else + { + mcLLVerified = 0; + } + + // + // LCHH ... + if (selectedLCHH == info.lHHs[i]) + { + lcHHVerified++; + } + else + { + lcHHVerified = 0; + } + + // + // LCLL ... + if (selectedLCLL == info.lLLs[i]) + { + lcLLVerified++; + } + else + { + lcLLVerified = 0; + } + + // + // HCHH ... + if (selectedHCHH == info.hHHs[i]) + { + hcHHVerified++; + } + else + { + hcHHVerified = 0; + } + + // + // HCLL ... + if (selectedHCLL == info.hLLs[i]) + { + hcLLVerified++; + } + else + { + hcLLVerified = 0; + } + } + + // + // Now we Have to check Verifications of each + // Selected Values and if their Passed Sequential Count + // we add them as Pivot Points ... + + // + // Peaks ... + if (peakVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedPeak, + peakPivots); + } + + // + // Vales ... + if (valeVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedVale, + valePivots); + } + + // + // Fib 1 ... + if (fib1Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib1, + fibPivots); + } + + // + // Fib 2 ... + if (fib2Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib2, + fibPivots); + } + + // + // Fib 3 ... + if (fib3Verified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedFib3, + fibPivots); + } + + // + // SCHH ... + if (scHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedSCHH, + cyclesHHPivots); + } + + // + // SCLL ... + if (scLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedSCLL, + cyclesLLPivots); + } + + // + // MCHH ... + if (mcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedMCHH, + cyclesHHPivots); + } + + // + // MCLL ... + if (mcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedMCLL, + cyclesLLPivots); + } + + // + // LCHH ... + if (lcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedLCHH, + cyclesHHPivots); + } + + // + // LCLL ... + if (lcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedLCLL, + cyclesLLPivots); + } + + // + // HCHH ... + if (hcHHVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedHCHH, + cyclesHHPivots); + } + + // + // HCLL ... + if (hcLLVerified >= pivotsSequentialCount) + { + // + AddIfNotExists( + selectedHCLL, + cyclesLLPivots); + } + } + + // + // Fill Pivot Points ... + void FillPivotPoints( + double &result[]) + { + // + Clean(result); + + // + int pCount = CountPivots(); + if (pCount <= 0) + { + return; + } + + // + AddsIfNotExists( + upZonePivots, + result); + + // + AddsIfNotExists( + downZonePivots, + result); + + // + AddsIfNotExists( + peakPivots, + result); + + // + AddsIfNotExists( + valePivots, + result); + + // + AddsIfNotExists( + fibPivots, + result); + + // + AddsIfNotExists( + cyclesHHPivots, + result); + + // + AddsIfNotExists( + cyclesLLPivots, + result); + } + + // + // Available Signallers ... + string mSignallers[]; + + // + // Here we are Capture Conditions and Check Signals ... + // The Signals Must be Unique for each providers ... + bool ProcessSignals(X121MarketConditions &conditions) + { + // + X121MarketConditions mConditions = GetMarketConditions(1); + + // + // BUY ... + + // + Clean(mConditions.signal); + bool hasLongSignal = HasLongSignal(mConditions); + if (hasLongSignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + // SELL ... + + // + Clean(mConditions.signal); + bool hasShortignal = HasShortSignal(mConditions); + if (hasShortignal) + { + // + NotifyOnSignalEvent( + mConditions.signal); + NotifyOnSignalConditionsEvent(mConditions); + mWaitUntilNewCandle = true; + + // + conditions = mConditions; + return true; + } + + // + return false; + } + + // + // Check has Long Signal on Each Strategies ... + bool HasLongSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + // TODO: Remove ... + double xTPPoint = 30; + double xSLPoint = 20; + + // + // Retrieve Entry Price ... + double entry = GetEntry( + mSymbol, + POSITION_TYPE_BUY); + + // + // Retrieve Pivot Points ... + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + entry, + pivots, + 15); + + // + // Cleaning Market Conditions Signal Structure ... + Clean(conditions.signal); + conditions.hasSignal = false; + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + IsTrendSwitchedToBullish(conditions) + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.mLLs[0]; + + // + conditions.signal.r2r = 0.75; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + + // // + // double supportFactor = ((MathAbs(entry - sl) / 2)); + // NormalizePrice( + // supportFactor, + // conditions.symbol); + + // // + // double supportVolume = 0.01; + + // // + // XSignal lSupport; + // Clean(lSupport); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_SELL; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry - supportFactor; + // lSupport.tp = entry - (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + + // // + // // Check Support and Resistance ... + + // // + // Clean(lSupport); + + // // + // supportVolume = 0.01; + // supportFactor = ((MathAbs(entry - sl) / 2.3)); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_SELL; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry - supportFactor; + // lSupport.tp = entry - (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + + // // + // // Check TP Calculate ... + + // // + // Clean(lSupport); + + // // + // supportVolume = 0.01; + // supportFactor = ((MathAbs(entry - sl) / 2.3)); + + // // + // lSupport.r2r = 1; + // lSupport.sl = entry; + // lSupport.volume = supportVolume; + // lSupport.mode = X_ORDER_MODE_STOP; + // lSupport.type = POSITION_TYPE_BUY; + // lSupport.riskAmount = supportVolume; + // lSupport.symbol = conditions.symbol; + // lSupport.entry = entry + supportFactor; + // lSupport.tp = entry + (2 * supportFactor); + + // // + // Add( + // lSupport, + // conditions.signal.supports); + } + } + + // + bool x92HasSignal = false; + bool canCheckX92 = IsAllowedSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + false + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.mLLs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + ; + + // + if (result) + { + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_BUY; + + // + conditions.hasSignal = true; + } + + // + return result; + } + + // + // Check has Short Signal on Each Strategies ... + bool HasShortSignal(X121MarketConditions &conditions) + { + // + bool result = false; + + // + // TODO: Remove this ... + double xTPPoint = 30; + double xSLPoint = 20; + + // + // Retrieve Entry Price ... + double entry = GetEntry( + mSymbol, + POSITION_TYPE_SELL); + + // + // Retrieve Pivot Points ... + double pivots[]; + FillPivotPoints(pivots); + XOHCLSupRes supRes = ExtractSupportAndResistance( + entry, + pivots, + 15); + + // + // Cleaning Market Conditions Signal Structure ... + Clean(conditions.signal); + conditions.hasSignal = false; + + // + // X786 ... + bool x786HasSignal = false; + bool canCheckX786 = IsAllowedSignaller(X786); + if (canCheckX786) + { + // + x786HasSignal = + // + false + // + ; + + // + if (x786HasSignal) + { + // + Add( + ToString(X786), + conditions.signal.providers); + + // + // double slPoint = xSLPoint; + // double slPrice = PointToPrice( + // conditions.symbol, + // slPoint); + // double sl = entry + slPrice; + + // // + // // TODO: Remove this to X121EA Class for Handling risk to reward and riskAmount and use risk amount as static volume + // // by access X121SignalProvider struture ... + // double tpPoint = xTPPoint; + // double tpPrice = PointToPrice( + // conditions.symbol, + // tpPoint); + // double tp = entry - tpPrice; + + // + double sl = conditions.xmanInfo.mHHs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; // tp; + + // + // conditions.signal.ignoreSL = false; + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + bool x92HasSignal = false; + bool canCheckX92 = IsAllowedSignaller(X92); + if (canCheckX92) + { + // + x92HasSignal = + // + false + // + // + ; + + // + if (x92HasSignal) + { + // + Add( + ToString(X92), + conditions.signal.providers); + + // + double sl = conditions.xmanInfo.mHHs[0]; + + // + conditions.signal.r2r = 1.5; + conditions.signal.riskAmount = 0.01; + conditions.signal.mode = X_ORDER_MODE_MARKET; + conditions.signal.entry = entry; + conditions.signal.sl = sl; + conditions.signal.tp = 0; + + // + conditions.signal.calculateTP = true; + conditions.signal.useRiskAmountAsVolume = true; + } + } + + // + result = + // + x786HasSignal + // + || + // + x92HasSignal + // + ; + + // + if (result) + { + // + conditions.supportResistances = supRes; + conditions.momentumStep = mLastMomentumStep; + + // + conditions.signal.symbol = mSymbol; + conditions.signal.period = mPeriod; + conditions.signal.type = POSITION_TYPE_SELL; + + // + conditions.hasSignal = true; + } + + // + return result; + } + + // + // SIGNALLER Tools ... + + // + double CalculateX786LognStop(const X121MarketConditions &conditions) + { + // + double result = 0; + + // + double val1 = conditions.xmanInfo.trends[0]; + double val2 = conditions.xmanInfo.sslcDowns[0]; + double val3 = conditions.xmanInfo.hullDowns[0]; + double val4 = conditions.xmanInfo.ribbon1s[0]; + double val5 = conditions.xmanInfo.ribbon2s[0]; + double val6 = conditions.xmanInfo.ribbon3s[0]; + double val7 = conditions.xmanInfo.ribbon4s[0]; + double val8 = conditions.xmanInfo.ribbon5s[0]; + double val9 = conditions.xmanInfo.ribbon6s[0]; + + // + double min = MathMin(val1, val2); + min = MathMin(min, val3); + min = MathMin(min, val4); + min = MathMin(min, val5); + min = MathMin(min, val6); + min = MathMin(min, val7); + min = MathMin(min, val8); + min = MathMin(min, val9); + + // + double max = MathMax(val1, val2); + max = MathMax(max, val3); + max = MathMax(max, val4); + max = MathMax(max, val5); + max = MathMax(max, val6); + max = MathMax(max, val7); + max = MathMax(max, val8); + max = MathMax(max, val9); + + // + return result; + } +}; + +// +// START Definitions ... +// + +// +// Model Signal Providers Definitions ... +struct X121SignalProvider +{ + // + // Provider use Which Symbol ... + string symbol; + + // + // Allowed Providers ... + string providers[]; + + // + // Provider use Which Time Frame ... + ENUM_TIMEFRAMES period; + + // + // Risk Amount Per Trades Related to Time Frames ... + // Percent of Available Balance ... + double riskAmount; + + // + // Use Provided Risk Amount as Static Volume ... + bool useRiskAmountAsStaticVolume; + + // + // Provider ... + XSCX121Provider *provider; +}; + +// +// END Definitions ... +// + +// +// START Usefull Functions ... +// + +// +// Add Specific Provider to List ... +void Add( + X121SignalProvider &item, // item want to add + X121SignalProvider &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Generate Identifier Tag ... +string GenerateTag(X121SignalProvider &descriptor) +{ + // + string result = ""; + + // + result = descriptor.symbol + "," + ToString(descriptor.period); + + // + return result; +} + +// +// Converts a Signal provider to String ... +string ToString(ENUM_X121_SIGNAL_PROVIDERS provider) +{ + return EnumToString(provider); +} + +// +// convert an String to Signal provider ... +ENUM_X121_SIGNAL_PROVIDERS ToProvider(string provider) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + if (ToString(NONE) == provider) + { + result = NONE; + } + else if (ToString(XTEST) == provider) + { + result = XTEST; + } + else if (ToString(X786) == provider) + { + result = X786; + } + else if (ToString(X92) == provider) + { + result = X92; + } + // else if (ToString(X110) == provider) + // { + // result = X110; + // } + // else if (ToString(X121) == provider) + // { + // result = X121; + // } + // else if (ToString(X128) == provider) + // { + // result = X128; + // } + + // + return result; +} + +// +// Extract Provider Type from Signal Commnet ... +ENUM_X121_SIGNAL_PROVIDERS ExtractPositionProvider(XPosition &position) +{ + // + ENUM_X121_SIGNAL_PROVIDERS result = NONE; + + // + string providerStr = + ExtractString( + position.comment, + XProviderToken + "(", + ")"); + if (StringLen(providerStr) <= 0) + { + return result; + } + + // + result = ToProvider(providerStr); + + // + return result; +} + +// +// List All Available Providers ... +void GetAllProviders( + ENUM_X121_SIGNAL_PROVIDERS &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + // XTEST ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = XTEST; + + // + // X786 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X786; + + // + // X92 ... + ArrayResize( + result, + ArraySize(result) + 1); + result[ArraySize(result) - 1] = X92; + + // // + // // X110 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X110; + + // // + // // X121 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X121; + + // // + // // X128 ... + // ArrayResize( + // result, + // ArraySize(result) + 1); + // result[ArraySize(result) - 1] = X128; +} + +// +// Lis All Available Providers ... +void GetAllProviders( + string &result[] // Hold Result ... +) +{ + // + Clean(result); + + // + ENUM_X121_SIGNAL_PROVIDERS providers[]; + GetAllProviders(providers); + int providersCount = ArraySize(providers); + if (providersCount <= 0) + { + return; + } + + // + for (int i = 0; i < providersCount; i++) + { + // + ENUM_X121_SIGNAL_PROVIDERS iProvider = providers[i]; + + // + Add( + ToString(iProvider), + result); + } +} + +// +// END Usefull Functions ... +// diff --git a/MQLTestWorkspace/BKPS/x-saherelm.common.lib.mq5 b/MQLTestWorkspace/BKPS/x-saherelm.common.lib.mq5 new file mode 100644 index 0000000..9660b89 --- /dev/null +++ b/MQLTestWorkspace/BKPS/x-saherelm.common.lib.mq5 @@ -0,0 +1,5037 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Common Library +// -------------------------------------- +// Name: XCommon +// Description: provide all commonly used functions ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Inputs ... +// + +// +// END Inputs ... +// + +// +// Include Models Library ... +#include "x-saherelm.models.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Detect is new Candle or not ... +bool IsNewCandle() +{ + // + bool result = false; + + // + static int barsOnChart = 0; + int currentBarsOnChart = Bars(_Symbol, _Period); + result = currentBarsOnChart > barsOnChart; + if (!result) + { + return result; + } + + // + barsOnChart = currentBarsOnChart; + result = true; + + // + return result; +} +bool IsNewCandle( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod // Trading Time Frame ... +) +{ + // + bool result = false; + + // + static string mChartTags[]; + static int mChartBars[]; + + // + string chTag = mSymbol + "," + ToString(mPeriod); + + // + int currChTagIdx = -1; + int chCountedBars = 0; + int currentBars = Bars(mSymbol, mPeriod); + + // + if (ArraySize(mChartTags) > 0) + { + // + for (int i = 0; i < ArraySize(mChartTags); i++) + { + // + string iTag = mChartTags[i]; + if (iTag != chTag) + { + continue; + } + + // + currChTagIdx = i; + break; + } + + // + if (currChTagIdx > -1) + { + chCountedBars = mChartBars[currChTagIdx]; + } + } + + // + result = currentBars > chCountedBars; + if (result) + { + // + if (currChTagIdx > -1) + { + // + mChartTags[currChTagIdx] = chTag; + mChartBars[currChTagIdx] = currentBars; + } + else + { + // + Add(chTag, mChartTags); + Add(currentBars, mChartBars); + } + } + + // + return result; +} + +// +double XNZ(double check, double val = 0) +{ + if (check == EMPTY_VALUE || check == 0) + { + return val; + } + else + { + return check; + } +} + +// +// Retrive Ask Price ... +double GetAsk() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_ASK); +} +double GetAsk( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_ASK); + + // + return result; +} + +// +// Retrieve Bid Price ... +double GetBid() +{ + return SymbolInfoDouble(_Symbol, SYMBOL_BID); +} +double GetBid( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_BID); + + // + return result; +} + +// +// Calculate and Retrieve Spread Price ... +double GetSpread() +{ + // + double ask = GetAsk(); + double bid = GetBid(); + double result = MathAbs(ask - bid); + + // + return result; +} +double GetSpread( + string symbol // selected symbol for calculations +) +{ + // + double ask = GetAsk(symbol); + double bid = GetBid(symbol); + double result = MathAbs(ask - bid); + + // + return result; +} + +// +// Get Points ... +double GetPoints() +{ + return _Point; +} +double GetPoints( + string symbol // selected symbol for calculations +) +{ + // + double result = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + return result; +} + +// +// Get Digits ... +int GetDigits() +{ + return _Digits; +} +int GetDigits( + string symbol // selected symbol for calculations +) +{ + // + int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + // + return result; +} + +// +// Get Signal Entry ... +double GetEntry( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk() : GetBid(); + result = NormalizePrice(result); + + // + return result; +} +double GetEntry( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetAsk(symbol) : GetBid(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Get Signal Exit ... +double GetExit( + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid() : GetAsk(); + result = NormalizePrice(result); + + // + return result; +} +double GetExit( + string symbol, // Specified Symbol + ENUM_POSITION_TYPE type // Get entry price for Which direction trade ... +) +{ + // + double result = 0; + + // + bool isLong = type == POSITION_TYPE_BUY; + result = isLong ? GetBid(symbol) : GetAsk(symbol); + result = NormalizePrice(result, symbol); + + // + return result; +} + +// +// Determine a Position type is Long or not ... +bool IsLong(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_BUY; + + // + return result; +} +bool IsLong(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_BUY; + + // + return result; +} + +// +// Determine a Position type is Short or not ... +bool IsShort(ENUM_POSITION_TYPE type) +{ + // + bool result = type == POSITION_TYPE_SELL; + + // + return result; +} +bool IsShort(ENUM_ORDER_TYPE type) +{ + // + bool result = type == ORDER_TYPE_SELL; + + // + return result; +} + +// +// Get 1 Pip in Price Value ... +double GetPipPrice() +{ + // + double result = _Point; + if (_Digits == 3 || _Digits == 5) + { + result *= 10; + } + + // + return result; +} +double GetPipPrice( + string symbol // selected symbol for calculations +) +{ + // + double symbolPoint = GetPoints(symbol); + int symbolDigits = GetDigits(symbol); + + // + double result = symbolPoint; + if (symbolDigits == 3 || symbolDigits == 5) + { + result *= 10; + } + + // + return result; +} + +// +// Converts Pips To Price ... +double PipsToPrice( + int pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + double pips // pips amount +) +{ + // + int digits = GetDigits(); + double pipValue = GetPipPrice(); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + int pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PipsToPrice( + string symbol, // selected symbol for calculation + double pips // pips amount +) +{ + // + int digits = GetDigits(symbol); + double pipValue = GetPipPrice(symbol); + double result = pips * pipValue; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Converts Price to Pips ... +double PriceToPips( + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(); + double pipPrice = GetPipPrice(); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} +double PriceToPips( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + int digits = GetDigits(symbol); + double pipPrice = GetPipPrice(symbol); + + // + double result = price / pipPrice; + + // + result = NormalizeDouble(result, digits); + + // + return result; +} + +// +// Convert Price to Point ... +double PriceToPoint( + double price // the price amount which required to calculate +) +{ + return PriceToPoint(_Symbol, price); +} +double PriceToPoint( + string symbol, // Selected Symbol + double price // the price amount which required to calculate +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = price / point; + + // + return result; +} + +// +// Converts Point to Price ... +double PointToPrice( + double points // Points Size +) +{ + return PointToPrice(_Symbol, points); +} +double PointToPrice( + string symbol, // Selected Symbol + double points // Points Size +) +{ + // + double result = 0; + + // + double point = GetPoints(symbol); + result = points * point; + + // + return result; +} + +// +// CANDLES ... + +// +// Validate Candle ... +bool IsValid( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + result = + // + candle.open > 0 && + candle.close > 0 && + candle.high > 0 && + candle.low > 0 + // + ; + + // + return result; +} + +// +// Get a Candle Body ... +double GetCandleBody( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.open - candle.close); + + // + return result; +} + +// +// Get a Candle Range ... +double GetCandleRange( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = MathAbs(candle.high - candle.low); + + // + return result; +} + +// +// Get a Candle Shadow ... +double GetCandleShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return 0; + } + + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + result = MathAbs(range - body); + + // + return result; +} + +// +// Retrieve High Shadow of Candle ... +double GetCandleHighShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double upPrice = MathMax(candle.open, candle.close); + + // + result = candle.high - upPrice; + + // + return result; +} + +// +// Retrieve Low Shadow of Candle ... +double GetCandleLowShadow( + XOHCL &candle // specified candle +) +{ + // + double result = 0; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + double downPrice = MathMin(candle.open, candle.close); + + // + result = downPrice - candle.low; + + // + return result; +} + +// +// Check a Candle is Base Candle for RTM or not ... +bool IsBaseCandle( + XOHCL &candle // specified candle +) +{ + // + double range = GetCandleRange(candle); + double body = GetCandleBody(candle); + + // + bool result = body > range; + + // + return result; +} + +// +// Check Candle Body Bigger Than it's Shadow ... +bool CandleHasStrongBody(XOHCL &candle) +{ + // + double bodySize = MathAbs(candle.open - candle.close); + double shadowSize = MathAbs(candle.high - candle.low) - bodySize; + + // + bool result = bodySize > (shadowSize * 1.5); + + // + return result; +} + +// +// Detect Doji Candle ... +bool IsDojiCandle( + XOHCL &candle, // Specified Candle + double detectFactor = 0.05 // Detect Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if ( + !isValid || + detectFactor <= 0 || + detectFactor > 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + // Calculate Candle Rate ... + double factor = range * detectFactor; + double shadowFactor = (1 - detectFactor) * range; + + // + result = + // + body > 0 && + range > 0 && + factor > 0 && + shadows > 0 && + body <= factor && + shadowFactor > 0 && + shadows >= shadowFactor + // + ; + + // + return result; +} + +// +// Detect Shadows of Specific Candles must be same .. +bool IsCrossShadowCandle( + XOHCL &candle, // Specified Candle + double smoothingFactor = 0.05 // Smoothing Factor +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid || + smoothingFactor <= 0 || + smoothingFactor >= 1) + { + return result; + } + + // + // Retrieve Candle Parts ... + double body = GetCandleBody(candle); + double range = GetCandleRange(candle); + double shadows = GetCandleShadow(candle); + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double upShadow = candle.high - upBody; + double downShadow = downBody - candle.low; + + // + // Calculate Candle Rate ... + double factor = range * smoothingFactor; + + // + result = + upShadow > 0 && + downShadow > 0 && + body > 0 && + range > 0 && + shadows > 0 && + ((upShadow == downShadow) || + MathAbs(upShadow - downShadow) <= factor); + + // + return result; +} + +// +// Detect a Candle Shadow Hunt Specific price or not ... +bool IsShadowHuntCandle( + XOHCL &candle, // Specified Candle + double price // Specified Price +) +{ + // + bool result = false; + + // + // Validate Args ... + bool isValid = IsValid(candle); + if (!isValid || price <= 0) + { + return result; + } + + // + double upBody = MathMax(candle.open, candle.close); + double downBody = MathMin(candle.open, candle.close); + + // + double hShadow = GetCandleHighShadow(candle); + double lShadow = GetCandleLowShadow(candle); + + // + double range = GetCandleRange(candle); + double factor = range * 0.3; + + // + bool isStrongHShadow = hShadow >= factor; + bool isStrongLShadow = lShadow >= factor; + + // + bool isPriceUp = + price >= candle.high || + price >= upBody; + + // + result = + // + isPriceUp + // + ? + // + isStrongHShadow && + (price == candle.high || + (price > upBody && price < candle.high)) + // + : + // + isStrongLShadow && + (price == candle.low || + (price < downBody && price > candle.low)) + // + ; + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBullishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open < candle.close; + + // + return result; +} +bool IsBullishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} +bool IsBullishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBullishCandle(candle); + + // + return result; +} + +// +// Check a Candle is Bullish or not ... +bool IsBearishCandle( + XOHCL &candle // specified candle +) +{ + // + bool result = false; + + // + bool isValid = IsValid(candle); + if (!isValid) + { + return result; + } + + // + result = candle.open > candle.close; + + // + return result; +} +bool IsBearishCandle( + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle(bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} +bool IsBearishCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // candle index +) +{ + // + bool result = false; + + // + XOHCL candle = GetCandle( + symbol, + mPeriod, + bar_index); + + // + result = IsBearishCandle(candle); + + // + return result; +} + +// +// Retrieve Applied Price at Specific Candle ... +double GetAppliedPrice( + XOHCL &candle, // specified candle + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + switch (source) + { + // + // Open ... + case PRICE_OPEN: + result = candle.open; + break; + + // + // High ... + case PRICE_HIGH: + result = candle.high; + break; + + // + // Low ... + case PRICE_LOW: + result = candle.low; + break; + + // + // Median ((High + Low) / 2) ... + case PRICE_MEDIAN: + result = (candle.high + candle.low) / 2; + break; + + // + // Typical ((High + Low + Close)/3) ... + case PRICE_TYPICAL: + result = (candle.high + candle.low + candle.close) / 3; + break; + + // + // Weighted ((High + Low + Close + Close)/4) ... + case PRICE_WEIGHTED: + result = (candle.high + candle.low + (candle.close * 2)) / 4; + break; + + // + // Close ... + default: + case PRICE_CLOSE: + result = candle.close; + break; + } + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To +) +{ + // + double result = EMPTY_VALUE; + + // + XOHCL candle = GetCandle(bar_index); + result = GetAppliedPrice(candle, source); + + // + return result; +} +double GetAppliedPrice( + int bar_index, // specify candle index + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + double result = 0; + + // + ENUM_APPLIED_PRICE mAppliedTo = To(mode); + result = GetAppliedPrice( + bar_index, + mAppliedTo); + + // + return result; +} + +// +template +double GetAppliedPrice(ENUM_APPLIED_PRICE tprice, T &open[], T &high[], T &low[], T &close[], int i) +{ + switch (tprice) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + } + return (0); +} + +// +// Converts ... +ENUM_APPLIED_PRICE To( + ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... +) +{ + // + ENUM_APPLIED_PRICE result = PRICE_CLOSE; + + // + switch (mode) + { + // + // High ... + case MODE_HIGH: + result = PRICE_HIGH; + break; + + // + // Open ... + case MODE_OPEN: + result = PRICE_OPEN; + break; + + // + // Low ... + case MODE_LOW: + result = PRICE_LOW; + break; + + // + // Close ... + // Default ... + case MODE_CLOSE: + default: + result = PRICE_CLOSE; + break; + } + + // + return result; +} + +// +// Retrieve a Candel Data ... +XOHCL GetCandle(int bar_index) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + double close = iClose(_Symbol, _Period, bar_index); + double low = iLow(_Symbol, _Period, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(_Symbol, mPeriod, bar_index); + double high = iHigh(_Symbol, mPeriod, bar_index); + double close = iClose(_Symbol, mPeriod, bar_index); + double low = iLow(_Symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} +XOHCL GetCandle( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + XOHCL result = {}; + + // + double open = iOpen(symbol, mPeriod, bar_index); + double high = iHigh(symbol, mPeriod, bar_index); + double close = iClose(symbol, mPeriod, bar_index); + double low = iLow(symbol, mPeriod, bar_index); + + // + result.low = low; + result.open = open; + result.high = high; + result.close = close; + + // + return result; +} + +// +// Get a Series Of Candles ... +bool GetCandles( + XOHCL &result[], // Hold Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mStart = 0, // Start Bar Index ... + int mCount = 1 // Specified Number of Candles ... +) +{ + // + bool mResult = false; + + // + if (mStart < 0) + { + mStart = 0; + } + + // + if (mCount <= 0) + { + mCount = 1; + } + + // + Clean(result); + + // + for (int i = mStart; i < mStart + mCount; i++) + { + // + XOHCL iC = GetCandle( + mSymbol, + mPeriod, + i); + + // + Add( + iC, + result); + } + + // + mResult = ArraySize(result) > 0; + + // + return mResult; +} + +// +// Retrieve a candle index in current timeframe inside another timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(_Symbol, _Period, bar_index); + result = iBarShift(_Symbol, destPeriod, barTime); + + // + return result; +} + +// +// Retrieve a symbol candle index in source time frame inside dest timeframe ... +int GetCandleBarIndex( + int bar_index, // Specify Candle index in current timeframe + string symbol, // Specify desired Symbol + ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe + ENUM_TIMEFRAMES destPeriod // Specify destination timeframe +) +{ + // + int result = -1; + + // + datetime barTime = iTime(symbol, sourcePeriod, bar_index); + result = iBarShift(symbol, destPeriod, barTime); + + // + return result; +} + +// +// Determines a cnadle is Swing High +// or Swing Low order block ... +ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(bar_index + 1); + candles[1] = GetCandle(bar_index + 2); + candles[2] = GetCandle(bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(mPeriod, bar_index + 1); + candles[1] = GetCandle(mPeriod, bar_index + 2); + candles[2] = GetCandle(mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} +ENUM_X_SWING_TYPE GetCandleSwing( + string symbol, // specify symbol + ENUM_TIMEFRAMES mPeriod, // specify timeframe + int bar_index // specify candle index +) +{ + // + ENUM_X_SWING_TYPE result = X_NO_SWING; + + // + // Reading Candle Models ... + XOHCL candles[3]; + candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); + candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); + candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); + + // + // Check Swing Start Candle has Strong Body ... + bool isStrongBodyCandle = CandleHasStrongBody(candles[2]); + if (!isStrongBodyCandle) + { + return result; + } + + // + // Check Swing Low Conditions ... + bool isSwingLowOrderBlock = + candles[2].low < candles[1].low && + candles[1].low < candles[0].low && + candles[2].low < candles[0].low; + if (isSwingLowOrderBlock) + { + result = X_SWING_LOW; + } + + // + // Check Swing High Conditions ... + bool isSwingHighOrderBlock = + candles[2].high > candles[1].high && + candles[1].high > candles[0].high && + candles[2].high > candles[0].high; + if (isSwingHighOrderBlock) + { + result = X_SWING_HIGH; + } + + // + return result; +} + +// +// Find Swing Points ... +int FindSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (StringLen(mSymbol) == 0 || (mode != MODE_HIGH && mode != MODE_LOW)) + { + return result; + } + + // + int current = bar_index; + int founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + + // + while (founded != current) + { + // + current = FindNextSwing( + mSymbol, + mPeriod, + mode, + mLength, + current + 1); + + // + founded = FindNextSwing( + mSymbol, + mPeriod, + mode, + (mLength * 2) + 1, + current - mLength); + } + + // + result = current; + + // + return result; +} + +// +// Find Next Swing ... +int FindNextSwing( + string mSymbol, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod, // Trading Period ... + ENUM_SERIESMODE mode, // Swing Based On Price mode ... + int mLength, // Loopback ... + int bar_index // BarIndex ... +) +{ + // + int result = -1; + + // + if (bar_index < 0) + { + mLength += bar_index; + bar_index = 0; + } + + // + result = mode == MODE_HIGH + ? iHighest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index) + : iLowest( + mSymbol, + mPeriod, + mode, + mLength, + bar_index); + + // + return result; +} + +// +// Retrieve Market Highest High ... +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iHigh( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + MODE_HIGH, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetHighestHigh( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iHighest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iHigh( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Retrieve Market Lowest Low ... +double GetLowestLow( + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + int mLength, // Which market Length use + int bar_index, // bar index + ENUM_SERIESMODE mode // Calculation mode +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + _Symbol, + _Period, + mode, + mLength, + bar_index); + + // + result = iLow( + _Symbol, + _Period, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + MODE_LOW, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} +double GetLowestLow( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES mPeriod, // Specified Period + ENUM_SERIESMODE mode, // Calculation mode + int mLength, // Which market Length use + int bar_index // bar index +) +{ + // + double result = -1; + + // + int rIdx = iLowest( + symbol, + mPeriod, + mode, + mLength, + bar_index); + + // + result = iLow( + symbol, + mPeriod, + rIdx); + + // + return result; +} + +// +// Find Support and Resistance for Specific Bar based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + int barIndex, // Bar Index ... + const double &pivots[], // Provided Pivot Points ... + int count = 3, // Number of Requireds ... + string mSymbol = NULL, // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL // Trading Period ... +) +{ + // + if (StringLen(mSymbol) == 0 || mSymbol == NULL) + { + mSymbol = _Symbol; + } + + // + if (mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + XOHCL cBar = GetCandle( + mSymbol, + mPeriod, + barIndex); + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > cBar.high) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < cBar.low) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find Support and Resistance for Specific Price based on provided Buffer ... +XOHCLSupRes ExtractSupportAndResistance( + double price, // Price ... + const double &pivots[], // Provided Pivot Points ... + int count = 3 // Number of Requireds ... +) +{ + // + XOHCLSupRes result; + Clean(result.res); + Clean(result.sup); + + // + if (price <= 0) + { + return result; + } + + // + int pivotsCount = ArraySize(pivots); + if (pivotsCount <= 0) + { + return result; + } + + // + if (count <= 0 || + count > pivotsCount - 1) + { + return result; + } + + // + double tmpR[]; + + // + double tmpS[]; + + // + // Extract Supports ... + // which prices is under low of candle ... + // + // Extract Resistance ... + // which prices is over high of candle ... + for (int i = 0; i < pivotsCount; i++) + { + // + double iFlat = pivots[i]; + + // + if (iFlat > price) + { + Add( + iFlat, + tmpR); + } + else if (iFlat < price) + { + Add( + iFlat, + tmpS); + } + } + + // + // Sorting Founded Resistance and Supports ... + + // + // Since Resistance Levels must be Increasing ... + ArraySort(tmpR); + + // + // Since Support Levels must be Decreasing ... + ArraySort(tmpS); + ArrayReverse(tmpS); + + // + // Fill Resistance ... + int tmpRCount = ArraySize(tmpR); + if (tmpRCount > 0) + { + // + if (tmpRCount < count) + { + // + ArrayCopy( + result.res, + tmpR); + } + else + { + // + ArrayCopy( + result.res, + tmpR, + 0, + 0, + count); + } + } + + // + // Fill Supports ... + int tmpSCount = ArraySize(tmpS); + if (tmpSCount > 0) + { + // + if (tmpSCount < count) + { + // + ArrayCopy( + result.sup, + tmpS); + } + else + { + // + ArrayCopy( + result.sup, + tmpS, + 0, + 0, + count); + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindLesserThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Biggest Lesser Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue < value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Find a Value less than Specified ... +double FindBiggerThanValue( + double value, // Specified Value ... + const double &source[], // Source ... + bool isDescend = false // Find Smallest Bigger Value ... +) +{ + // + double result = -1; + + // + int itemsCount = ArraySize(source); + if (itemsCount <= 0) + { + return result; + } + + // + // Make a Copy of source ... + double tmp[]; + + // + ArrayResize( + tmp, + ArraySize(source)); + + // + ArrayCopy( + tmp, + source); + + // + // Sort Temp Buffer ... + ArraySort(tmp); + if (!isDescend) + { + ArrayReverse(tmp); + } + + // + int tmpCount = ArraySize(tmp); + for (int i = 0; i < tmpCount; i++) + { + // + double iValue = tmp[i]; + + // + if (iValue > value) + { + // + result = iValue; + break; + } + } + + // + return result; +} + +// +// Calculate Fib Level ... +double GetFibonacciLevel( + double upPrice, + double downPrice, + double level, + int direction) +{ + // + double ling = upPrice - downPrice; + double pLevel = (ling / 100) * (level * 100); + + // + double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; + result = NormalizeDouble(result, _Digits); + + // + return result; +} + +// +// Check first Cross Over second at bar_index ... +bool IsCrossOver( + const double &first[], // the buffer which check crossing over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + !(first[bar_index + 1] > second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Over second at bar_index ... +bool IsOver( + const double &first[], // the buffer which check over second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] > second[bar_index] && + first[bar_index + 1] > second[bar_index + 1]; + + // + return result; +} + +// +// Check first Cross Under second at bar_index ... +bool IsCrossUnder( + const double &first[], // the buffer which check crossing under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + !(first[bar_index + 1] < second[bar_index + 1]); + + // + return result; +} + +// +// Check first is Under second at bar_index ... +bool IsUnder( + const double &first[], // the buffer which check under second buffer + const double &second[], // first buffer checks based on this buffer + const int bar_index // check crosses in specific index +) +{ + // + bool result = false; + + // + ArraySetAsSeries(first, true); + ArraySetAsSeries(second, true); + + // + // Validate Args ... + if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) + { + return result; + } + + // + result = first[bar_index] < second[bar_index] && + first[bar_index + 1] < second[bar_index + 1]; + + // + return result; +} + +// +// Calculate Slope of Specified Buffer at Specified Index ... +double GetSlope( + int from, // In Past Index ... + int to, // In Past Index ... + double &buffer[]) +{ + // + double result = 0; + + // + double toValue = buffer[to]; + double fromValue = buffer[from]; + double deltaValue = toValue - fromValue; + double deltaTime = from - to; + + // + result = deltaValue / deltaTime; + + // + return result; +} + +// +// Check if a Value Increasing in Loopback ... +bool IsIncreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue > fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue >= iValue; + + // + bool isIIncreasing = IsIncreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIIncreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Check if a Value Decreasing in Loopback ... +bool IsDecreasing( + int from, // Last Time Index + int to, // Fisr Tima Index + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + result = toValue < fromValue; + for (int i = to + 1; i <= from - 1; i++) + { + // + double iValue = buffer[i]; + bool isPassed = toValue <= iValue; + + // + bool isIDecreasing = IsDecreasing( + from, + i, + buffer); + + // + // Check Result ... + result = result && isPassed && isIDecreasing; + if (!result) + { + break; + } + } + + // + return result; +} + +// +// Get Max Value of Specific Loopback of a Buffer ... +double GetMaxValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result < iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Get Min Value of Specific Loopback of a Buffer ... +double GetMinValue( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback) + { + return result; + } + + // + // Loop Through LoopBack ... + for (int i = 0; i < mLoopback; i++) + { + // + double iValue = buffer[i]; + + // + result = + // + result == 0 || result > iValue + // + ? iValue + // + : result + // + ; + } + + // + return result; +} + +// +// Find Same Values in Array ... +void FindSameValueInBuffer( + double &result[], // Holds Result ... + double &source[], // Source ... + int verifications = 3 // Number of Consequence Repeat ... +) +{ + // + Clean(result); + + // + // TenkanSen Flats ... + int sourceCount = ArraySize(source); + if (sourceCount > verifications) + { + // + double mLast = 0; + int mVerified = 0; + for (int i = 0; i < sourceCount; i++) + { + // + double iVal = source[i]; + if (mLast == 0) + { + mLast = iVal; + } + else if (mLast == iVal) + { + mVerified++; + } + else + { + mLast = iVal; + mVerified = 0; + } + + // + if (iVal == mLast && mVerified >= verifications) + { + // + Add( + iVal, + result); + + // + mLast = 0; + mVerified = 0; + } + } + } +} + +// +bool IsInPeak( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue > lastValue + // + && + // + ( + firstValue > q1Value && + firstValue > halfValue) + // + ; + + // + return result; +} + +// +bool IsInVale( + int mLoopback, // loopback length + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + mLoopback < 2 || + ArraySize(buffer) < mLoopback + 1) + { + return result; + } + + // + int q1Length = mLoopback / 4; + int halfLength = mLoopback / 2; + int q2Length = halfLength + q1Length; + + // + double firstValue = buffer[1]; + double q1Value = buffer[q1Length]; + double q2Value = buffer[q2Length]; + double halfValue = buffer[halfLength]; + double lastValue = buffer[ArraySize(buffer) - 1]; + + // + // Peak ... + result = + // + firstValue < lastValue + // + && + // + ( + firstValue < q1Value && + firstValue < halfValue) + // + ; + + // + return result; +} + +// +// Check Sharp Happens or not ... +bool IsSharpChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check InCreased Sharp Happens or not ... +bool IsSharpIncreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpIncreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpIncreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +// Check Decreased Sharp Happens or not ... +bool IsSharpDecreasedChanged( + double fromValue, // Past Value + double toValue, // Present Value + double maxValue, // Max in Range Value + double minValue // Min in Range Value +) +{ + // + bool result = false; + + // + // This Used In Increased or Decreased Sharp Detection ... + bool isIncreased = toValue > fromValue; + + // + double toFromDelta = MathAbs(toValue - fromValue); + double minMaxDelta = maxValue - minValue; + + // + result = + !isIncreased && + toFromDelta >= (minMaxDelta / 3); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Index in Series + int to, // Present Index in Series + double &buffer[] // the Buffer which required to search +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + from <= to || + ArraySize(buffer) < from + 1) + { + return result; + } + + // + // Loop through Items ... + double toValue = buffer[to]; + double fromValue = buffer[from]; + + // + double minValue = GetMinValue( + ArraySize(buffer) - 1, + buffer); + double maxValue = GetMaxValue( + ArraySize(buffer) - 1, + buffer); + double minMaxDelta = maxValue - minValue; + + // + // Sharp Detection ... + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} +bool IsSharpDecreasedChanged( + int from, // Past Bar Index + int to, // Present Bar Index + ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To +) +{ + // + bool result = false; + + // + double toValue = GetAppliedPrice( + to, + appliedPrice); + double fromValue = GetAppliedPrice( + from, + appliedPrice); + + // + int hIdx = iHighest( + _Symbol, + _Period, + MODE_HIGH, + from, + to); + double maxValue = iHigh( + _Symbol, + _Period, + hIdx); + + // + int lIdx = iLowest( + _Symbol, + _Period, + MODE_LOW, + from, + to); + double minValue = iLow( + _Symbol, + _Period, + lIdx); + + // + result = IsSharpDecreasedChanged( + fromValue, + toValue, + maxValue, + minValue); + + // + return result; +} + +// +void Clean(int &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(ulong &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(string &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} +void Clean(double &buffer[]) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +bool GetLastItem( + double &item, // Holds Result + double &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} +bool GetLastItem( + datetime &item, // Holds Result + datetime &buffer[] // Specified Buffer +) +{ + // + bool result = false; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + item = buffer[bufferSize - 1]; + + // + result = true; + return result; +} + +// +void Add( + int item, // item want to add + int &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + ulong item, // item want to add + ulong &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + string item, // item want to add + string &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + double item, // item want to add + double &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + XOHCL &item, // item want to add + XOHCL &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} +void Add( + datetime &item, // item want to add + datetime &buffer[] // Destination buffer +) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// Add an Item to a Buffer if not Exists ... +void AddIfNotExists( + double value, + double &values[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int valuesCount = ArraySize(values); + if (valuesCount <= 0) + { + // + Add(value, + values); + } + else + { + // + bool isExists = false; + for (int i = 0; i < valuesCount; i++) + { + // + double iVal = values[i]; + + // + double diff = MathAbs(iVal - value); + + // + if (iVal == value || diff < smoothingValue) + { + // + isExists = true; + break; + } + } + + // + if (!isExists) + { + // + Add(value, + values); + } + } +} + +// +// Add a Buffers Child to another Buffer +// if it's not Contains them ... +void AddsIfNotExists( + double &source[], + double &dest[], + double smoothingPoint = 3) +{ + // + double smoothingValue = smoothingPoint * GetPoints(_Symbol); + + // + int sourceCount = ArraySize(source); + if (sourceCount <= 0) + { + return; + } + + // + for (int i = 0; i < sourceCount; i++) + { + // + double iSource = source[i]; + + // + AddIfNotExists( + iSource, + dest, + smoothingPoint); + } +} + +// +// Converts a Buffer to String Representation ... +string ToString( + const int &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const double &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const string &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator + +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +string ToString( + const datetime &buffer[], // Specified Buffer + string separator = ",", // Specified Separator + bool addIndex = false, // Specified Add Items Indexes or Not + string indexLabel = "i:", // Specified Index Label + string indexSeparator = ">" // Specified Index Separator +) +{ + // + string result = ""; + + // + int bufferSize = ArraySize(buffer); + if (bufferSize <= 0) + { + return result; + } + + // + for (int i = 0; i < bufferSize; i++) + { + // + if (addIndex) + { + // + if (StringLen(indexLabel) > 0) + { + result += indexLabel + " "; + } + + // + result += (string)i + " "; + + // + if (StringLen(indexSeparator) > 0) + { + result += indexSeparator + " "; + } + } + + // + string iItemString = (string)buffer[i]; + + // + result += iItemString; + + // + if (i < bufferSize - 1) + { + result += separator; + } + } + + // + return result; +} +template +string ToString(T value) +{ + return (string)value; +} + +// +// Converts String to boolean ... +bool ToBoolean(string value) +{ + // + bool result = false; + + // + if (StringLen(value) <= 0) + { + return result; + } + + // + StringToLower(value); + result = value == "true"; + + // + return result; +} + +// +// Search Array For Specific Item ... +template +int FindIndex( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + int result = -1; + + // + int count = ArraySize(buffer); + if (count <= 0) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + T iT = buffer[i]; + + // + if (iT == item) + { + // + result = i; + break; + } + } + + // + return result; +} + +template +bool Contains( + T item, // What is Search ... + T &buffer[] // Search in ... +) +{ + // + bool result = false; + + // + int idx = FindIndex( + item, + buffer); + result = idx > -1; + + // + return result; +} + +// +// Split an String Representation of an Array ... +void SplitContent( + string &result[], // Hold Result ... + string content, // Source ... + string separator = ",", // Separator ... + bool forceCleanResult = true // Clean Result ... +) +{ + // + if (forceCleanResult) + { + Clean(result); + } + + // + if (separator == NULL || StringLen(separator) == 0) + { + separator = ","; + } + + // + if (StringLen(content) == 0) + { + return; + } + + // + StringSplit( + content, + StringGetCharacter( + separator, + 0), + result); +} + +// +// Extract Data from String ... +string ExtractString( + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + string result = ""; + + // + // Validate String ... + if ( + StringLen(source) == 0 || + StringLen(endString) == 0 || + StringLen(startString) == 0) + { + return result; + } + + // + // Find Start String Position ... + int sPos = StringFind( + source, + startString); + if (sPos < 0) + { + return result; + } + + // + // Find End String Position after Start String ... + int searchEndFromPos = sPos + StringLen(startString); + int ePos = StringFind( + source, + endString, + searchEndFromPos); + if (ePos < 0) + { + return result; + } + + // + // Extract Data from Source ... + int dLength = ePos - searchEndFromPos; + result = StringSubstr( + source, + searchEndFromPos, + dLength); + + // + return result; +} + +// +// Extract an Array of Contents ... +int ExtractStrings( + string &result[], // Hold Result + const string source, // Source String used for Extracting + const string startString, // Expression Start String must be Unique + const string endString // Where to End Extraction, usually a Sign +) +{ + // + int mResult = 0; + + // + Clean(result); + + // + // Validate Args ... + int sourceLength = StringLen(source); + int startLength = StringLen(startString); + int endLength = StringLen(endString); + + // + int minRequiredLength = startLength + endLength; + + // + if ( + endLength <= 0 || + startLength <= 0 || + sourceLength <= 0 || + sourceLength < minRequiredLength) + { + return mResult; + } + + // + // Make a Copy of Source for Manipulating ... + string workStr = source; + + // + // Define a Loop ... + while (StringLen(workStr) > minRequiredLength) + { + // + // Find Item ... + string item = ExtractString( + workStr, + startString, + endString); + + // + // Breakout when couldn't find anymore item ... + int itemLength = StringLen(item); + if (itemLength <= 0) + { + break; + } + + // + // Prepare Item Source String for Replacing in Work String ... + string itemSource = startString + item + endString; + + // + // Add Item to Result Array ... + Add( + item, + result); + + // + // Replace Item Soure in Work String ... + StringReplace( + workStr, + itemSource, + ""); + } + + // + // Calculate Size of Array ... + mResult = ArraySize(result); + + // + return mResult; +} + +// +// Normalize a give Volume ... +double NormalizeVolume( + double volume, // desired volume to normalize + string symbol = NULL, // Specified Symbol for Normalization + int mLength = 2 // Length of Digits +) +{ + // + double result = volume; + + // + // Normalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + // Normalize Digits ... + int digits = GetDigits(symbol); + mLength = + mLength == 0 || mLength > digits + ? digits + : MathMin(mLength, digits); + + // + // Normalize Volume ... + result = NormalizeDouble(result, mLength); + + // + double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); + + // + // Validate Result ... + if (result > maxAvailableVolume) + { + result = maxAvailableVolume; + } + else if (result < minAvailableVolume) + { + result = minAvailableVolume; + } + + // + return result; +} + +// +// Normallize Price ... +double NormalizePrice( + double price, // desired Price for normalization + string symbol = NULL // Specified Symbol for Normalization +) +{ + // + double result = 0; + + // + // Mormalize Symbol ... + if (StringLen(symbol) == 0) + { + symbol = _Symbol; + } + + // + int digits = GetDigits(symbol); + result = NormalizeDouble(price, digits); + + // + return result; +} + +// +// Do All Normalization on Specific Signal ... +void NormalizeSignal(XSignal &signal) +{ + // + // ENTRY ... + if (signal.entry > 0) + { + signal.entry = NormalizePrice(signal.entry, signal.symbol); + } + + // + // TP ... + if (signal.tp > 0) + { + signal.tp = NormalizePrice(signal.tp, signal.symbol); + } + + // + // SL ... + if (signal.sl > 0) + { + signal.sl = NormalizePrice(signal.sl, signal.symbol); + } + + // + // VOLUME ... + if (signal.volume > 0) + { + signal.volume = NormalizeVolume(signal.volume, signal.symbol); + } +} + +// +// Check Expert Running in Testing Mode or not ... +bool IsRunningOnTestMode() +{ + // + bool result = false; + + // + // check programm mode ... + result = MQL5InfoInteger(MQL5_TESTING); + + // + return result; +} + +// +// Calculate Volume Weighted Moving Average ... +double iVWMA( + double price, + double volume, + int period, + int i, + int bars, + int instance = 0 // +) +{ +#define ¤ instance +#ifdef _averageInstances +#define _functionInstances _averageInstances +#else #define _functionInstances 1 +#endif + struct sVwmaArrayStruct + { + double price; + double volume; + double sump; + double sumv; + }; + static sVwmaArrayStruct m_array[][_functionInstances]; + static int m_arraySize = 0; + if (m_arraySize < bars) + { + int _res = ArrayResize(m_array, bars + 500); + if (_res <= bars) + return (0); + m_arraySize = _res; + } + + // + //--- + // + + if (volume == 0) + volume = 1; + m_array[i][¤].price = volume * price; + m_array[i][¤].volume = volume; + if (i > period) + { + m_array[i][¤].sump = m_array[i - 1][¤].sump + m_array[i][¤].price - m_array[i - period][¤].price; + m_array[i][¤].sumv = m_array[i - 1][¤].sumv + volume - m_array[i - period][¤].volume; + } + else + { + m_array[i][¤].sump = m_array[i][¤].price; + m_array[i][¤].sumv = m_array[i][¤].volume; + for (int k = 1; k < period && i >= k; k++) + { + m_array[i][¤].sump += m_array[i - k][¤].price; + m_array[i][¤].sumv += m_array[i - k][¤].volume; + } + } + return (m_array[i][¤].sump / m_array[i][¤].sumv); + + // + //--- + // + +#undef ¤ #undef _functionInstances +} + +// +// Date Time Manipulation Functions ... +// + +// +// Representation of Time Struct ... +// struct MqlDateTime +// { +// int year; // Year +// int mon; // Month +// int day; // Day +// int hour; // Hour +// int min; // Minutes +// int sec; // Seconds +// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) +// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) +// }; + +// +// Converts Time to Seconds ... +ulong TimeToSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = (ulong)time; + + // + return result; +} +ulong TimeToSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToSeconds(dTime); + + // + return result; +} + +// +// Converts Seconds To Time ... +datetime SecondsToTime( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime result = (datetime)seconds; + + // + return result; +} +MqlDateTime SecondsToStruct( + ulong seconds // Specify Seconds to Convert ... +) +{ + // + datetime dTime = SecondsToTime(seconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Converts Time to MilliSeconds ... +ulong TimeToMilliSeconds( + datetime time // Specify time to Convert ... +) +{ + // + ulong result = TimeToSeconds(time) * 1000; + + // + return result; +} +ulong TimeToMilliSeconds( + MqlDateTime &time // Specify time to Convert ... +) +{ + // + datetime dTime = StructToTime(time); + + // + ulong result = TimeToMilliSeconds(dTime); + + // + return result; +} + +// +// Converts MillisSeconds to Time ... +datetime MilliSecondsToTiem( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + ulong seconds = milliSeconds / 1000; + + // + datetime result = SecondsToTime(seconds); + + // + return result; +} +MqlDateTime MilliSecondsToStruct( + ulong milliSeconds // Specify MilliSeconds to Convert ... +) +{ + // + datetime dTime = MilliSecondsToTiem(milliSeconds); + + // + MqlDateTime result = {}; + TimeToStruct( + dTime, + result); + + // + return result; +} + +// +// Retrieve DateTime Structure ... +MqlDateTime GetCurrentTime() +{ + // + MqlDateTime result = {}; + + // + TimeCurrent(result); + + // + return result; +} + +// +// Retrieve Current Time as Seconds ... +ulong GetCurrentTimeAsSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Current Time as MilliSeconds ... +ulong GetCurrentTimeAsMilliSeconds() +{ + // + datetime time = TimeCurrent(); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +datetime GetCandleTime( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Validate and Normalize Args ... + + // + // Normalize Symbol ... + symbol = StringLen(symbol) == 0 + ? _Symbol + : symbol; + + // + // Normalize Period ... + period = period == NULL + ? _Period + : period; + + // + // Retrieve Bar Time ... + datetime result = iTime( + symbol, + period, + bar_index); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToSeconds(time); + + // + return result; +} + +// +// Retrieve Specified Candle Time ... +ulong GetCandleTimeAsMilliSeconds( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + // Retrieve Bar Time ... + datetime time = GetCandleTime( + symbol, + period, + bar_index); + + // + ulong result = TimeToMilliSeconds(time); + + // + return result; +} + +// +// Retrieve a Candle Time Structure ... +MqlDateTime GetCandleTimeStruct( + string symbol = "", // Specify Symbol + ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame + int bar_index = 0 // Specify Bar Index +) +{ + // + MqlDateTime result = {}; + + // + // Retrieve Bar Time ... + datetime barTime = GetCandleTime( + symbol, + period, + bar_index); + + // + // Convert to Structure ... + TimeToStruct(barTime, result); + + // + return result; +} + +// +// Retrieve Number of Candles in a Day ... +int GetDailyCandleCount(ENUM_TIMEFRAMES mPeriod) +{ + // + int seconds = PeriodSeconds(mPeriod); + + // + int daySeconds = 24 * 60 * 60; + + // + int result = daySeconds / seconds; + + // + return result; +} + +int GetDailyCandleCount() +{ + // + int result = GetDailyCandleCount(_Period); + + // + return result; +} + +// +// +// + +// +// Holds Month ... +static int xMonth = -1; + +// +// Holds Day Of Week ... +static int xDayOfWeek = -1; +static int xForWeekDay = -1; + +// +// Holds Day ... +static int xDay = -1; + +// +// Holds Hour ... +static int xHour = -1; + +// +// Reset Timing Variables ... +void ResetTiming() +{ + // + xHour = -1; + xDay = -1; + xDayOfWeek = -1; + xMonth = -1; +} + +// +// Detecting New Houre ... +bool IsNewHour() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.hour != xHour; + if (result) + { + xHour = timeStruct.hour; + } + + // + return result; +} + +// +// Detecting New Day ... +bool IsNewDay() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.day_of_year != xDay; + if (result) + { + xDay = timeStruct.day_of_year; + } + + // + return result; +} + +// +// Detecting New Week ... +bool IsNewWeek() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Week ... + // Since Week Starts From Monday in Forex World ... + // we Calculate Start of Week by 1-Monday ... + result = + xDayOfWeek == -1 && + xForWeekDay == -1 + ? true + : timeStruct.day_of_week == 1 && + timeStruct.day_of_year > xForWeekDay; + + // + xForWeekDay = timeStruct.day_of_year; + xDayOfWeek = timeStruct.day_of_week; + + // + return result; +} + +// +// Detecting End Of Week ... +bool IsWeekEnd() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check WeekEnd ... + // Since Week Starts From Monday in Forex World ... + // we Calculate End of Week by 5-Friday ... + result = + xDayOfWeek != -1 && + timeStruct.day_of_week == 5 && + timeStruct.hour == 23 && + timeStruct.min == 59 && + timeStruct.sec == 59; + + // + return result; +} + +// +// Detecting New Month ... +bool IsNewMonth() +{ + // + bool result = false; + + // + // Retrieve Current Time as Struct ... + MqlDateTime timeStruct = GetCurrentTime(); + + // + // Check Houre ... + result = timeStruct.mon != xMonth; + if (result) + { + xMonth = timeStruct.mon; + } + + // + return result; +} + +// +// Find Hindmost Time Frame ... +ENUM_TIMEFRAMES GetHindmostTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + result = PERIOD_H12; + break; + + // + case PERIOD_M20: + case PERIOD_M30: + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_D1; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Farest Time Frame ... +ENUM_TIMEFRAMES GetFarestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + case PERIOD_M30: + result = PERIOD_H4; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + case PERIOD_H4: + result = PERIOD_H12; + break; + + // + case PERIOD_H6: + case PERIOD_H8: + case PERIOD_H12: + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Medium Time Frame ... +ENUM_TIMEFRAMES GetMediestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_H1; + break; + + // + case PERIOD_M30: + result = PERIOD_H2; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Find Nearest Time Frame ... +ENUM_TIMEFRAMES GetNearestTimeFrame( + ENUM_TIMEFRAMES mPeriod // Specified Period +) +{ + // + ENUM_TIMEFRAMES result = NULL; + + // + // Normalize Period ... + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + switch (mPeriod) + { + // + case PERIOD_M1: + case PERIOD_M2: + case PERIOD_M3: + case PERIOD_M4: + result = PERIOD_M5; + break; + + // + case PERIOD_M5: + case PERIOD_M6: + case PERIOD_M10: + case PERIOD_M12: + result = PERIOD_M15; + break; + + // + case PERIOD_M15: + case PERIOD_M20: + result = PERIOD_M30; + break; + + // + case PERIOD_M30: + result = PERIOD_H1; + break; + + // + case PERIOD_H1: + case PERIOD_H2: + case PERIOD_H3: + result = PERIOD_H4; + break; + + // + case PERIOD_H4: + case PERIOD_H6: + case PERIOD_H8: + result = PERIOD_H12; + break; + + // + case PERIOD_H12: + result = PERIOD_D1; + break; + + // + case PERIOD_D1: + result = PERIOD_W1; + break; + + // + case PERIOD_W1: + result = PERIOD_MN1; + break; + + // + default: + result = PERIOD_MN1; + break; + } + + // + return result; +} + +// +// Get Specific Time Frame Start Candle Time ... +datetime GetPeriodStartTime( + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + datetime mTime = NULL // Specified Bar Time ... +) +{ + // + // Normalize Arg ... + + // + if ( + mSymbol == NULL || + StringLen(mSymbol) == 0) + { + mSymbol = _Symbol; + } + + // + if ( + mPeriod < 0 || + mPeriod == NULL) + { + mPeriod = _Period; + } + + // + if ( + mTime < 0 || + mTime == NULL) + { + mTime = TimeCurrent(); + } + + // + int barIndex = iBarShift( + mSymbol, + mPeriod, + mTime, + false); + + // + datetime result = iTime( + mSymbol, + mPeriod, + barIndex); + + // + return result; +} + +// +struct XCandleRemains +{ + // + int days; + int hours; + int minutes; + int seconds; +}; + +// +string ToString( + XCandleRemains &item, + string dayId = "d", + string hourId = "h", + string minuteId = "m", + string secondId = "s", + string idSeparator = ": ", + string separator = ", ", + bool ignoreZeroValues = true) +{ + // + string result = ""; + + // + // Days ... + if (!ignoreZeroValues || item.days > 0) + { + result += dayId + idSeparator + (string)item.days + separator; + } + + // + // Hours ... + if (!ignoreZeroValues || item.hours > 0) + { + // + string strHour = ToString(item.hours); + if (StringLen(strHour) == 1) + { + strHour = "0" + strHour; + } + + // + result += hourId + idSeparator + strHour + separator; + } + + // + // Minutes ... + if (!ignoreZeroValues || item.minutes > 0) + { + // + string strMinute = ToString(item.minutes); + if (StringLen(strMinute) == 1) + { + strMinute = "0" + strMinute; + } + + // + result += minuteId + idSeparator + strMinute + separator; + } + + // + // Seconds ... + if (!ignoreZeroValues || item.seconds > 0) + { + // + string strSec = ToString(item.seconds); + if (StringLen(strSec) == 1) + { + strSec = "0" + strSec; + } + + // + result += secondId + idSeparator + strSec; + } + + // + return result; +} + +// +// Retrieve Specific Candles Ramained Time ... +void GetCandleRemainsTime( + XCandleRemains &result, // Holds Result ... + string mSymbol = NULL, // Specified Symbol ... + ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... + int mBarIndex = 0 // Specified Bar Index ... +) +{ + // + int minuteSecoonds = 60; + int hourSeconds = minuteSecoonds * 60; + int daySeconds = 24 * hourSeconds; + + // + int periodSeconds = PeriodSeconds( + mPeriod); + datetime startTime = GetCandleTime( + mSymbol, + mPeriod, + mBarIndex); + + // + int secondsDiff = (int)startTime + periodSeconds - (int)TimeCurrent(); + + // + int days = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + // + int mWorkingSecondsDiff = secondsDiff; + if (mWorkingSecondsDiff > daySeconds) + { + // + days = mWorkingSecondsDiff / daySeconds; + mWorkingSecondsDiff -= days * daySeconds; + } + if (mWorkingSecondsDiff > hourSeconds) + { + // + hours = mWorkingSecondsDiff / hourSeconds; + mWorkingSecondsDiff -= hours * hourSeconds; + } + if (mWorkingSecondsDiff > minuteSecoonds) + { + // + minutes = mWorkingSecondsDiff / minuteSecoonds; + mWorkingSecondsDiff -= minutes * minuteSecoonds; + } + seconds = mWorkingSecondsDiff; + + // + result.days = days; + result.hours = hours; + result.minutes = minutes; + result.seconds = seconds; +} + +// +// Converts an String to TimeFrame ... +ENUM_TIMEFRAMES ToPeriod(string value) +{ + // + if (StringLen(value) == 0) + { + return _Period; + } + + // + StringTrimLeft(value); + StringTrimRight(value); + + // + ENUM_TIMEFRAMES result = _Period; + + // + if (value == "M1") + { + result = PERIOD_M1; + } + else if (value == "M2") + { + result = PERIOD_M2; + } + else if (value == "M3") + { + result = PERIOD_M3; + } + else if (value == "M4") + { + result = PERIOD_M4; + } + else if (value == "M5") + { + result = PERIOD_M5; + } + else if (value == "M6") + { + result = PERIOD_M6; + } + else if (value == "M10") + { + result = PERIOD_M10; + } + else if (value == "M12") + { + result = PERIOD_M12; + } + else if (value == "M15") + { + result = PERIOD_M15; + } + else if (value == "M20") + { + result = PERIOD_M20; + } + else if (value == "M30") + { + result = PERIOD_M30; + } + else if (value == "H1") + { + result = PERIOD_H1; + } + else if (value == "H2") + { + result = PERIOD_H2; + } + else if (value == "H3") + { + result = PERIOD_H3; + } + else if (value == "H4") + { + result = PERIOD_H4; + } + else if (value == "H6") + { + result = PERIOD_H6; + } + else if (value == "H8") + { + result = PERIOD_H8; + } + else if (value == "H12") + { + result = PERIOD_H12; + } + else if (value == "D1") + { + result = PERIOD_D1; + } + else if (value == "W1") + { + result = PERIOD_W1; + } + else if (value == "MN1") + { + result = PERIOD_MN1; + } + + // + return result; +} + +// +// Converts Period to String ... +string ToString(ENUM_TIMEFRAMES period) +{ + // + string result = ""; + + // + string mPStr = EnumToString(period); + + string mPStrParts[]; + int partsCount = StringSplit( + mPStr, + StringGetCharacter("_", 0), + mPStrParts); + if (partsCount <= 0) + { + return result; + } + + // + result = mPStrParts[1]; + + // + return result; +} + +// +// TYPES ... +// + +// +// Retrieve Specific Object Types Name ... +template +string GetTypeName(const T &t) +{ + return typename(T); +} + +// +// END Provided Functions ... +// diff --git a/MQLTestWorkspace/BKPS/x-saherelm.x121.condition.parser.lib.mq5 b/MQLTestWorkspace/BKPS/x-saherelm.x121.condition.parser.lib.mq5 new file mode 100644 index 0000000..61a4573 --- /dev/null +++ b/MQLTestWorkspace/BKPS/x-saherelm.x121.condition.parser.lib.mq5 @@ -0,0 +1,585 @@ +//////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 X12 Conditions Parser Library +// ----------------------------------------------------- +// Name: X121ConditionsParser +// Description: provides Market Conditions +// Parsing Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Libraries/x-saherelm.models.lib.mq5" +#include "../Classes/x-saherelm.x121.provider.class.mq5" + +// +// START Functions ... +// + +// +// MARKET Direction ... +// + +// +bool IsMarketStronglyBullish( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + ( + // + conditions.xmanInfo.isSCSwitchedToBullish || + conditions.xmanInfo.isMCSwitchedToBullish || + conditions.xmanInfo.isLCSwitchedToBullish || + conditions.xmanInfo.isHCSwitchedToBullish || + conditions.xmanInfo.isSSLCSwitchedToBullish || + conditions.xmanInfo.isHullSwitchedToBullish || + conditions.xmanInfo.isTrendSwitchedToBullish || + conditions.xmanInfo.isRibbonSwitchedToBullish + // + ) + // + && + // + ( + // + conditions.xmanInfo.isSSLCBullish && + conditions.xmanInfo.isHullBullish && + conditions.xmanInfo.isTrendBullish && + conditions.xmanInfo.isRibbonBullish + // + ) + // + ; + + // + return result; +} + +// +bool IsMarketStronglyBearish( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + ( + // + conditions.xmanInfo.isSCSwitchedToBearish || + conditions.xmanInfo.isMCSwitchedToBearish || + conditions.xmanInfo.isLCSwitchedToBearish || + conditions.xmanInfo.isHCSwitchedToBearish || + conditions.xmanInfo.isSSLCSwitchedToBearish || + conditions.xmanInfo.isHullSwitchedToBearish || + conditions.xmanInfo.isTrendSwitchedToBearish || + conditions.xmanInfo.isRibbonSwitchedToBearish + // + ) + // + && + // + ( + // + conditions.xmanInfo.isSSLCBearish && + conditions.xmanInfo.isHullBearish && + conditions.xmanInfo.isTrendBearish && + conditions.xmanInfo.isRibbonBearish + // + ) + // + ; + + // + return result; +} + +// +// PEASK and VALES ... +// + +// +// Check New Peaks Happens ... +bool IsNewPeak( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.peaks[0] != EMPTY_VALUE && + conditions.xmanInfo.peaks[0] != conditions.xmanInfo.peaks[1]; + + // + return result; +} + +// +// Check New Vales Happens ... +bool IsNewVale( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.vales[0] != EMPTY_VALUE && + conditions.xmanInfo.vales[0] != conditions.xmanInfo.vales[1]; + + // + return result; +} + +// +// Check New Peak Happens Under Last Peak ... +bool IsNewPeakUnderLast( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions) && + conditions.xmanInfo.peaks[0] < conditions.xmanInfo.peaks[1] + // + ; + + // + return result; +} + +// +// Check New Peak Happens Over Last Peak ... +bool IsNewPeakOverLast( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + IsNewPeak(conditions) && + conditions.xmanInfo.peaks[0] > conditions.xmanInfo.peaks[1] + // + ; + + // + return result; +} + +// +// Check New Vale Happens Under Last Vale ... +bool IsNewValeUnderLast( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions) && + conditions.xmanInfo.vales[0] < conditions.xmanInfo.vales[1] + // + ; + + // + return result; +} + +// +// Check New Vale Happens Over Last Vale ... +bool IsNewValeOverLast( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + IsNewVale(conditions) && + conditions.xmanInfo.vales[0] > conditions.xmanInfo.vales[1] + // + ; + + // + return result; +} + +// +// FIBONACCI ... +// + +// +// Check Finbonacci Increased ... +bool IsFiboIncreased( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[0] > conditions.xmanInfo.fibLevel1s[1] && + conditions.xmanInfo.fibLevel2s[0] > conditions.xmanInfo.fibLevel2s[1] && + conditions.xmanInfo.fibLevel3s[0] > conditions.xmanInfo.fibLevel3s[1] && + conditions.xmanInfo.fibLevel4s[0] > conditions.xmanInfo.fibLevel4s[1] && + conditions.xmanInfo.fibLevel5s[0] > conditions.xmanInfo.fibLevel5s[1] + // + ; + + // + return result; +} + +// +// Check Fibonacci Decreased ... +bool IsFiboDecreased( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[0] < conditions.xmanInfo.fibLevel1s[1] && + conditions.xmanInfo.fibLevel2s[0] < conditions.xmanInfo.fibLevel2s[1] && + conditions.xmanInfo.fibLevel3s[0] < conditions.xmanInfo.fibLevel3s[1] && + conditions.xmanInfo.fibLevel4s[0] < conditions.xmanInfo.fibLevel4s[1] && + conditions.xmanInfo.fibLevel5s[0] < conditions.xmanInfo.fibLevel5s[1] + // + ; + + // + return result; +} + +// +// Check Fibonacci Crossed ... +bool IsFiboCrossed( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.fibLevel1s[0] == conditions.xmanInfo.fibLevel2s[0] || + conditions.xmanInfo.fibLevel1s[0] == conditions.xmanInfo.fibLevel3s[0] || + conditions.xmanInfo.fibLevel1s[0] == conditions.xmanInfo.fibLevel4s[0] || + conditions.xmanInfo.fibLevel1s[0] == conditions.xmanInfo.fibLevel5s[0] || + conditions.xmanInfo.fibLevel2s[0] == conditions.xmanInfo.fibLevel3s[0] || + conditions.xmanInfo.fibLevel2s[0] == conditions.xmanInfo.fibLevel4s[0] || + conditions.xmanInfo.fibLevel2s[0] == conditions.xmanInfo.fibLevel5s[0] || + conditions.xmanInfo.fibLevel3s[0] == conditions.xmanInfo.fibLevel4s[0] || + conditions.xmanInfo.fibLevel3s[0] == conditions.xmanInfo.fibLevel5s[0] || + conditions.xmanInfo.fibLevel4s[0] == conditions.xmanInfo.fibLevel5s[0] + // + ; + + // + return result; +} + +// +// Check Fibonacci Section Changes ... +bool IsFiboSectionChanged( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + (IsNewPeakUnderLast(conditions) && + IsFiboDecreased(conditions)) + // + || + // + (IsNewValeOverLast(conditions) && + IsFiboIncreased(conditions)) + // + ; + + // + return result; +} + +// +// HULL Trend ... +// + +// +// Check Hull Trend Crosses with Fibo Levels ... + +// +// Fib 1 ... + +// +// Cross Over ... +bool IsHullCrossedOverFibo1( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[0] > conditions.xmanInfo.fibLevel1s[0] && + conditions.xmanInfo.hullDowns[1] <= conditions.xmanInfo.fibLevel1s[1] + // + ; + + // + return result; +} + +// +// Cross Under ... +bool IsHullCrossedUnderFibo1( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[0] < conditions.xmanInfo.fibLevel1s[0] && + conditions.xmanInfo.hullUps[1] >= conditions.xmanInfo.fibLevel1s[1] + // + ; + + // + return result; +} + +// +// Fib 2 ... + +// +// Cross Over ... +bool IsHullCrossedOverFibo2( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[0] > conditions.xmanInfo.fibLevel2s[0] && + conditions.xmanInfo.hullDowns[1] <= conditions.xmanInfo.fibLevel2s[1] + // + ; + + // + return result; +} + +// +// Cross Under ... +bool IsHullCrossedUnderFibo2( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[0] < conditions.xmanInfo.fibLevel2s[0] && + conditions.xmanInfo.hullUps[1] >= conditions.xmanInfo.fibLevel2s[1] + // + ; + + // + return result; +} + +// +// Fib 3 ... + +// +// Cross Over ... +bool IsHullCrossedOverFibo3( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[0] > conditions.xmanInfo.fibLevel3s[0] && + conditions.xmanInfo.hullDowns[1] <= conditions.xmanInfo.fibLevel3s[1] + // + ; + + // + return result; +} + +// +// Cross Under ... +bool IsHullCrossedUnderFibo3( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[0] < conditions.xmanInfo.fibLevel3s[0] && + conditions.xmanInfo.hullUps[1] >= conditions.xmanInfo.fibLevel3s[1] + // + ; + + // + return result; +} + +// +// Fib 4 ... + +// +// Cross Over ... +bool IsHullCrossedOverFibo4( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[0] > conditions.xmanInfo.fibLevel4s[0] && + conditions.xmanInfo.hullDowns[1] <= conditions.xmanInfo.fibLevel4s[1] + // + ; + + // + return result; +} + +// +// Cross Under ... +bool IsHullCrossedUnderFibo4( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[0] < conditions.xmanInfo.fibLevel4s[0] && + conditions.xmanInfo.hullUps[1] >= conditions.xmanInfo.fibLevel4s[1] + // + ; + + // + return result; +} + +// +// Fib 5 ... + +// +// Cross Over ... +bool IsHullCrossedOverFibo5( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullDowns[0] > conditions.xmanInfo.fibLevel5s[0] && + conditions.xmanInfo.hullDowns[1] <= conditions.xmanInfo.fibLevel5s[1] + // + ; + + // + return result; +} + +// +// Cross Under ... +bool IsHullCrossedUnderFibo5( + X121MarketConditions &conditions // Specified Conditions +) +{ + // + bool result = false; + + // + result = + // + conditions.xmanInfo.hullUps[0] < conditions.xmanInfo.fibLevel5s[0] && + conditions.xmanInfo.hullUps[1] >= conditions.xmanInfo.fibLevel5s[1] + // + ; + + // + return result; +} + +// +// END Functions ... +// diff --git a/MQLTestWorkspace/BKPS/x-saherelm.x121.xman.helper.class.mq5 b/MQLTestWorkspace/BKPS/x-saherelm.x121.xman.helper.class.mq5 new file mode 100644 index 0000000..4cd1589 --- /dev/null +++ b/MQLTestWorkspace/BKPS/x-saherelm.x121.xman.helper.class.mq5 @@ -0,0 +1,3419 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXMANHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// All Extractable Buffers ... +enum ENUM_XMAN_BUFFERS +{ + // + // Peaks and Vales ... + XMAN_PEAKS_LINE = 0, // Peaks + XMAN_VALES_LINE = 1, // Vales + XMAN_PEAKS_STATE_LINE = 69, // New Peak + XMAN_VALES_STATE_LINE = 70, // New Vales + // + // Fibonacci Retracement ... + XMAN_FIB_L1_LINE = 6, // Fibo Level 1 + XMAN_FIB_L2_LINE = 8, // Fibo Level 2 + XMAN_FIB_L3_LINE = 10, // Fibo Level 3 + XMAN_FIB_L4_LINE = 12, // Fibo Level 3 + XMAN_FIB_L5_LINE = 14, // Fibo Level 3 + // + // Period Cycles ... + // + // Short Cycle ... + XMAN_SC_HH_LINE = 16, // High + XMAN_SC_LL_LINE = 18, // Low + XMAN_SC_HH_STATE_LINE = 71, // High State + XMAN_SC_LL_STATE_LINE = 72, // Low State + // + // Medium ... + XMAN_MC_HH_LINE = 20, // High + XMAN_MC_LL_LINE = 22, // Low + XMAN_MC_HH_STATE_LINE = 73, // High State + XMAN_MC_LL_STATE_LINE = 74, // Low State + // + // Long ... + XMAN_LC_HH_LINE = 24, // High + XMAN_LC_LL_LINE = 26, // Low + XMAN_LC_HH_STATE_LINE = 75, // High State + XMAN_LC_LL_STATE_LINE = 76, // Low State + // + // Hind ... + XMAN_HC_HH_LINE = 28, // High + XMAN_HC_LL_LINE = 30, // Low + XMAN_HC_HH_STATE_LINE = 77, // High State + XMAN_HC_LL_STATE_LINE = 78, // Low State + // + // XSTR ... + XMAN_TREND_LINE = 34, // Trend Value + XMAN_TREND_STATE_LINE = 79, // Trend Direction + // + // XMRB ... + // + // RIBBON 1 _ HIGH ... + XMAN_RB1_LINE = 36, // Value + XMAN_RB1_STATE_LINE = 80, // State + // + // RIBBON 2 _ OPEN ... + XMAN_RB2_LINE = 38, // Value + XMAN_RB2_STATE_LINE = 81, // State + // + // RIBBON 3 _ CLOSE ... + XMAN_RB3_LINE = 40, // Value + XMAN_RB3_STATE_LINE = 82, // State + // + // RIBBON 4 _ MEDIAN ... + XMAN_RB4_LINE = 42, // Value + XMAN_RB4_STATE_LINE = 83, // State + // + // RIBBON 5 _ TYPICAL ... + XMAN_RB5_LINE = 44, // Value + XMAN_RB5_STATE_LINE = 84, // State + // + // RIBBON 6 _ LOW ... + XMAN_RB6_LINE = 46, // Value + XMAN_RB6_STATE_LINE = 85, // State + // + // XSSLC ... + XMAN_SSLC_UP_LINE = 48, // Up + XMAN_SSLC_DOWN_LINE = 50, // Down + // + // XHULL ... + XMAN_HULL_UP_LINE = 52, // Up + XMAN_HULL_DOWN_LINE = 54, // Down + XMAN_HULL_UP_STATE_LINE = 86, // Up State + XMAN_HULL_DOWN_STATE_LINE = 87, // Down State + // + // XHK ... + XMAN_HK_OPEN_LINE = 56, // Open + XMAN_HK_HIGH_LINE = 57, // High + XMAN_HK_LOW_LINE = 58, // Low + XMAN_HK_CLOSE_LINE = 59, // Close + XMAN_HK_STATE_LINE = 88, // State +}; + +// +// Define States On XMAN ... +enum ENUM_XMAN_STATES +{ + XMAN_STATE_BULLISH = 2, + XMAN_STATE_STRONG_BULLISH = 8, + XMAN_STATE_BEARISH = 3, + XMAN_STATE_STRONG_BEARISH = 9, + XMAN_STATE_NEUTURAL = 1, + XMAN_STATE_STRONG_NEUTURAL = 7, +}; + +// +// XPERIOD Calculation Method ... +// USED For Multiple Time Frames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, // Nothing + X_PERIOD_AUTO, // Auto Select + X_PERIOD_MANUALLY // Manually +}; + +// +enum ENUM_X_MA_METHOD +{ + X_MA_NOTHING, // Nothing + X_MA_SMA, // Simple + X_MA_EMA, // Expotential + X_MA_SMMA, // Smoothed Simple + X_MA_LWMA, // Linear Weighted + X_MA_AMA // Adaptive +}; + +// +// Model all required info as a Model for Instancing Helper Class ... +struct XMANInputs +{ + // + // Candle Timer ... + color candleTimerColor; // Text Color + ENUM_BASE_CORNER candleTimerCorner; // Text Position + + // + // Chart Style ... + color upColor; // Up Color + color downColor; // Down Color + color lineColor; // Line mode and Doji candlestick Color + color bearishColor; // Bullish Color + color bullishColor; // Bearish Color + color volumesColor; // Volumes Color + ENUM_CHART_MODE chartMode; // Chart Mode + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD l1Method; // How to Find Period + ENUM_TIMEFRAMES l1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD l2Method; // How to Find Period + ENUM_TIMEFRAMES l2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD l3Method; // How to Find Period + ENUM_TIMEFRAMES l3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD l4Method; // How to Find Period + ENUM_TIMEFRAMES l4Period; // Time Period + + // + // Fibonacci ... + double fiboLevel1; // Fibio 1st Level + double fiboLevel2; // Fibio 2st Level + double fiboLevel3; // Fibio 3rd Level + double fiboLevel4; // Fibio 4th Level + double fiboLevel5; // Fibio 5th Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE hhMode; // Highest High Calculation Method + ENUM_SERIESMODE llMode; // Lowest Low Calculation Method + + // + // Trend Detection + double trendMultiplier; // Multiplier + ENUM_APPLIED_PRICE trendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD ribbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double hullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE hullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE hullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD sslcMode; // How to Calculate + ENUM_APPLIED_PRICE sslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE sslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool showCandleTimer; // Show Candle Time + bool showCandles; // Show Candles + bool showHKCandles; // Draw Hiken Ashi Candle + bool showPeaksAndVales; // Show Peaks and Vales + bool showTrends; // Show Trends + bool fillTrends; // Fill Trends + bool showLevels; // Show Levels + bool showConsolidations; // Show Consolidations + bool showRibbons; // Show Ribbons + bool showHull; // Show Hull + bool showSSLChannel; // Show SSL Channel + bool showFibo1Levels; // Show Fibo 1st Level + bool showFibo2Levels; // Show Fibo 2nd Level + bool showFibo3Levels; // Show Fibo 3rd Level + bool showFibo4Levels; // Show Fibo 4th Level + bool showFibo5Levels; // Show Fibo 5th Level +}; + +// +// Model all Extractable Info as a Model for Market Analyzing ... +struct XMANInfo +{ + // + // COMMONS ... + + // + // Symbol ... + string symbol; + + // + // Period ... + ENUM_TIMEFRAMES period; + + // + // Bar Time ... + datetime barTime; + + // + // Bar Index ... + int barIndex; + + // + // SPECIALS ... + + // + // Buffers ... + + // + // Peaks and Vales ... + double peaks[]; + double peaksStates[]; + double vales[]; + double valesStates[]; + + // + // Fibonacci ... + double fibLevel1s[]; + double fibLevel2s[]; + double fibLevel3s[]; + double fibLevel4s[]; + double fibLevel5s[]; + + // + // Cycles ... + + // + // Short ... + double sHHs[]; + double sHHStates[]; + double sLLs[]; + double sLLStates[]; + + // + // Medium ... + double mHHs[]; + double mHHStates[]; + double mLLs[]; + double mLLStates[]; + + // + // Long ... + double lHHs[]; + double lHHStates[]; + double lLLs[]; + double lLLStates[]; + + // + // Hind ... + double hHHs[]; + double hHHStates[]; + double hLLs[]; + double hLLStates[]; + + // + // Trends ... + double trends[]; + double trendStates[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1s[]; + double ribbon1States[]; + + // + // 2 _ Open ... + double ribbon2s[]; + double ribbon2States[]; + + // + // 3 _ Close ... + double ribbon3s[]; + double ribbon3States[]; + + // + // 4 _ Median ... + double ribbon4s[]; + double ribbon4States[]; + + // + // 5 _ Typical ... + double ribbon5s[]; + double ribbon5States[]; + + // + // 6 _ Low ... + double ribbon6s[]; + double ribbon6States[]; + + // + // SSL Channel ... + double sslcUps[]; + double sslcDowns[]; + + // + // Hull Trend ... + double hullUps[]; + double hullUpStates[]; + double hullDowns[]; + double hullDownStates[]; + + // + // Hiken Ashi ... + double hkOpens[]; + double hkHighs[]; + double hkLows[]; + double hkCloses[]; + double hkStates[]; + + // + // Conditions ... + + // + // Peaks and Vales ... + bool isNewPeak; + bool isNewVale; + + // + // Trend ... + bool isTrendBullish; + bool isTrendSwitchedToBullish; + bool isTrendBearish; + bool isTrendSwitchedToBearish; + bool isTrendNeutural; + bool isTrendSwitchedToNeutural; + + // + // SSL Channel ... + bool isSSLCBullish; + bool isSSLCSwitchedToBullish; + bool isSSLCBearish; + bool isSSLCSwitchedToBearish; + bool isSSLCNeutural; + bool isSSLCSwitchedToNeutural; + + // + // Hull Trend ... + + // + bool isHullBullish; + bool isHullUpBullish; + bool isHullDownBullish; + bool isHullSwitchedToBullish; + + // + bool isHullBearish; + bool isHullUpBearish; + bool isHullDownBearish; + bool isHullSwitchedToBearish; + + // + bool isHullNeutural; + bool isHullUpNeutural; + bool isHullDownNeutural; + bool isHullSwitchedToNeutural; + + // + // HK ... + bool isHKBullish; + bool isHKBearish; + + // + // Market Cycles ... + + // + // Short ... + + // + bool isSCBullish; + bool isSCHBullish; + bool isSCLBullish; + bool isSCSwitchedToBullish; + bool isSCHSwitchedToBullish; + bool isSCLSwitchedToBullish; + + // + bool isSCBearish; + bool isSCHBearish; + bool isSCLBearish; + bool isSCSwitchedToBearish; + bool isSCHSwitchedToBearish; + bool isSCLSwitchedToBearish; + + // + bool isSCNeutural; + bool isSCHNeutural; + bool isSCLNeutural; + bool isSCSwitchedToNeutural; + bool isSCHSwitchedToNeutural; + bool isSCLSwitchedToNeutural; + + // + // Medium ... + + // + bool isMCBullish; + bool isMCHBullish; + bool isMCLBullish; + bool isMCSwitchedToBullish; + bool isMCHSwitchedToBullish; + bool isMCLSwitchedToBullish; + + // + bool isMCBearish; + bool isMCHBearish; + bool isMCLBearish; + bool isMCSwitchedToBearish; + bool isMCHSwitchedToBearish; + bool isMCLSwitchedToBearish; + + // + bool isMCNeutural; + bool isMCHNeutural; + bool isMCLNeutural; + bool isMCSwitchedToNeutural; + bool isMCHSwitchedToNeutural; + bool isMCLSwitchedToNeutural; + + // + // Long ... + + // + bool isLCBullish; + bool isLCHBullish; + bool isLCLBullish; + bool isLCSwitchedToBullish; + bool isLCHSwitchedToBullish; + bool isLCLSwitchedToBullish; + + // + bool isLCBearish; + bool isLCHBearish; + bool isLCLBearish; + bool isLCSwitchedToBearish; + bool isLCHSwitchedToBearish; + bool isLCLSwitchedToBearish; + + // + bool isLCNeutural; + bool isLCHNeutural; + bool isLCLNeutural; + bool isLCSwitchedToNeutural; + bool isLCHSwitchedToNeutural; + bool isLCLSwitchedToNeutural; + + // + // Hind ... + + // + bool isHCBullish; + bool isHCHBullish; + bool isHCLBullish; + bool isHCSwitchedToBullish; + bool isHCHSwitchedToBullish; + bool isHCLSwitchedToBullish; + + // + bool isHCBearish; + bool isHCHBearish; + bool isHCLBearish; + bool isHCSwitchedToBearish; + bool isHCHSwitchedToBearish; + bool isHCLSwitchedToBearish; + + // + bool isHCNeutural; + bool isHCHNeutural; + bool isHCLNeutural; + bool isHCSwitchedToNeutural; + bool isHCHSwitchedToNeutural; + bool isHCLSwitchedToNeutural; + + // + // Ribbons ... + + // + // R1 ... + + // + bool isRibbon1Bullish; + bool isRibbon2Bullish; + bool isRibbon3Bullish; + bool isRibbon4Bullish; + bool isRibbon5Bullish; + bool isRibbon6Bullish; + + // + bool isRibbon1Bearish; + bool isRibbon2Bearish; + bool isRibbon3Bearish; + bool isRibbon4Bearish; + bool isRibbon5Bearish; + bool isRibbon6Bearish; + + // + bool isRibbon1Neutural; + bool isRibbon2Neutural; + bool isRibbon3Neutural; + bool isRibbon4Neutural; + bool isRibbon5Neutural; + bool isRibbon6Neutural; + + // + bool isRibbonBullish; + bool isRibbonSwitchedToBullish; + + // + bool isRibbonBearish; + bool isRibbonSwitchedToBearish; + + // + bool isRibbonNeutural; + bool isRibbonSwitchedToNeutural; +}; + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include "../Libraries/x-saherelm.common.lib.mq5" +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +class XSCXMANHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Peaks and Vales ... + double peaksBuffer[]; + double peaksStateBuffer[]; + double valesBuffer[]; + double valesStateBuffer[]; + + // + // Fibonacci ... + double fibLevel1Buffer[]; + double fibLevel2Buffer[]; + double fibLevel3Buffer[]; + double fibLevel4Buffer[]; + double fibLevel5Buffer[]; + + // + // Cycles ... + + // + // Short ... + double sHHBuffer[]; + double sHHStateBuffer[]; + double sLLBuffer[]; + double sLLStateBuffer[]; + + // + // Medium ... + double mHHBuffer[]; + double mHHStateBuffer[]; + double mLLBuffer[]; + double mLLStateBuffer[]; + + // + // Long ... + double lHHBuffer[]; + double lHHStateBuffer[]; + double lLLBuffer[]; + double lLLStateBuffer[]; + + // + // Hind ... + double hHHBuffer[]; + double hHHStateBuffer[]; + double hLLBuffer[]; + double hLLStateBuffer[]; + + // + // Trends ... + double trendBuffer[]; + double trendStateBuffer[]; + + // + // Ribbons ... + + // + // 1 _ High ... + double ribbon1Buffer[]; + double ribbon1StateBuffer[]; + + // + // 2 _ Open ... + double ribbon2Buffer[]; + double ribbon2StateBuffer[]; + + // + // 3 _ Close ... + double ribbon3Buffer[]; + double ribbon3StateBuffer[]; + + // + // 4 _ Median ... + double ribbon4Buffer[]; + double ribbon4StateBuffer[]; + + // + // 5 _ Typical ... + double ribbon5Buffer[]; + double ribbon5StateBuffer[]; + + // + // 6 _ Low ... + double ribbon6Buffer[]; + double ribbon6StateBuffer[]; + + // + // SSL Channel ... + double sslUpBuffer[]; + double sslDownBuffer[]; + + // + // Hull Trend ... + double hullUpBuffer[]; + double hullUpStateBuffer[]; + double hullDownBuffer[]; + double hullDownStateBuffer[]; + + // + // Hiken Ashi ... + double hkOpenBuffer[]; + double hkHighBuffer[]; + double hkLowBuffer[]; + double hkCloseBuffer[]; + double hkStateBuffer[]; + + // + // Constructor ... + void XSCXMANHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) : XSCBaseHelper(symbol, period) + { + PrepareTag(); + } + + // + // Deconstructor ... + void ~XSCXMANHelper() + { + } + + // + // START Properties ... + // + + // + // END Properties ... + // + + // + // START Provided Functions ... + // + + // + // Prepare Tag ... + virtual void PrepareTag() + { + mTag = "XMAN" + GetTagPrefix(); + } + + // + virtual int GetMaxLength() + { + // + int result = 1; + + // + result = 1; + + // + return result; + } + + // + // Initial Indicator Handler ... + bool Init() + { + // + bool result = false; + + // + // Validate Args ... + result = + // + // L1 ... + // Short Cycle ... + ( + // + mL1Method == X_PERIOD_AUTO + ? mL1Period == NULL + : mL1Period != NULL && mL1Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L2 ... + // Medium Cycle ... + ( + // + mL2Method == X_PERIOD_AUTO + ? mL2Period == NULL + : mL2Period != NULL && mL2Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L3 ... + // Long Cycle ... + ( + // + mL3Method == X_PERIOD_AUTO + ? mL3Period == NULL + : mL3Period != NULL && mL3Method != X_PERIOD_NOTHING + // + ) + // + && + // + // L4 ... + // Hind Cycle ... + ( + // + mL4Method == X_PERIOD_AUTO + ? mL4Period == NULL + : mL4Period != NULL && mL4Method != X_PERIOD_NOTHING + // + ) + // + && + // + // Validate Ribbon ... + ( + // + mRibbonMode != X_MA_NOTHING + // + ) + // + ; + if (!result) + { + return false; + } + + // + // Initialize Handler ... + mHandler = iCustom( + // + mSymbol, + mPeriod, + "x-saherelm.x121.xman", + // + // Inputs ... + // + // Candle Timer ... + "", + // + mCandleTimerColor, // Text Color + mCandleTimerCorner, // Text Position + // + // Chart Style ... + // "", + // + mUpColor, // Up Color + mDownColor, // Down Color + mLineColor, // Line mode and Doji candlestick Color + mBearishColor, // Bullish Color + mBullishColor, // Bearish Color + mVolumesColor, // Volumes Color + mChartMode, // Chart Mode + // + // Market Cycles ... + // "", + // + // Level 1 ... + "", + // + mL1Method, // How to Find Period + mL1Period, // Time Period + // + // Level 2 ... + "", + // + mL2Method, // How to Find Period + mL2Period, // Time Period + // + // Level 3 ... + "", + // + mL3Method, // How to Find Period + mL3Period, // Time Period + // + // Level 4 ... + "", + // + mL4Method, // How to Find Period + mL4Period, // Time Period + // + // Fibonacci ... + "", + // + mFiboLevel1, // Fibio 1st Level + mFiboLevel2, // Fibio 2st Level + mFiboLevel3, // Fibio 3rd Level + mFiboLevel4, // Fibio 4th Level + mFiboLevel5, // Fibio 5th Level + // + // Boundary Detection Modes ... + "", + // + mHHMode, // Highest High Calculation Method + mLLMode, // Lowest Low Calculation Method + // + // Trend Detection + "", + // + mTrendMultiplier, // Multiplier + mTrendPriceAppliedTo, // Applied To + // + // Ribbon Detection ... + "", + // + mRibbonMode, // How to Calculate + // + // Hull Trend Detection ... + "", + // + mHullDivisor, // Divisor (Speed) + mHullUpAppliedTo, // Up Zone Applied to + mHullDownAppliedTo, // Down Zone Applied to + // + // SSL Channel Detection ... + "", + // + mSslcMode, // How to Calculate + mSslcUpAppliedTo, // Up Applied To + mSslcDownAppliedTo, // Down Applied To + // + // Presentation ... + "", + // + mShowCandleTimer, // Show Candle Timer + mShowCandles, // Show Candles + mShowHKCandles, // Draw Hiken Ashi Candle + mShowPeaksAndVales, // Show Peaks and Vales + mShowTrends, // Show Trends + mSillTrends, // Fill Trends + mShowLevels, // Show Levels + mShowConsolidations, // Show Consolidations + mShowRibbons, // Show Ribbons + mShowHull, // Show Hull + mShowSSLChannel, // Show SSL Channel + mShowFibo1Levels, // Show Fibo 1st Level + mShowFibo2Levels, // Show Fibo 2nd Level + mShowFibo3Levels, // Show Fibo 3rd Level + mShowFibo4Levels, // Show Fibo 4th Level + mShowFibo5Levels // Show Fibo 5th Level + // + ); + result = mHandler != INVALID_HANDLE; + + // + return result; + } + + // + // Retrieve Current Config ... + XMANInputs GetConfig() + { + // + XMANInputs result; + + // + result.candleTimerColor = mCandleTimerColor; + result.candleTimerCorner = mCandleTimerCorner; + result.upColor = mUpColor; + result.downColor = mDownColor; + result.lineColor = mLineColor; + result.bearishColor = mBearishColor; + result.bullishColor = mBullishColor; + result.volumesColor = mVolumesColor; + result.chartMode = mChartMode; + result.l1Method = mL1Method; + result.l1Period = mL1Period; + result.l2Method = mL2Method; + result.l2Period = mL2Period; + result.l3Method = mL3Method; + result.l3Period = mL3Period; + result.l4Method = mL4Method; + result.l4Period = mL4Period; + result.fiboLevel1 = mFiboLevel1; + result.fiboLevel2 = mFiboLevel2; + result.fiboLevel3 = mFiboLevel3; + result.fiboLevel4 = mFiboLevel4; + result.fiboLevel5 = mFiboLevel5; + result.hhMode = mHHMode; + result.llMode = mLLMode; + result.trendMultiplier = mTrendMultiplier; + result.trendPriceAppliedTo = mTrendPriceAppliedTo; + result.ribbonMode = mRibbonMode; + result.hullDivisor = mHullDivisor; + result.hullUpAppliedTo = mHullUpAppliedTo; + result.hullDownAppliedTo = mHullDownAppliedTo; + result.sslcMode = mSslcMode; + result.sslcUpAppliedTo = mSslcUpAppliedTo; + result.sslcDownAppliedTo = mSslcDownAppliedTo; + result.showCandleTimer = mShowCandleTimer; + result.showCandles = mShowCandles; + result.showHKCandles = mShowHKCandles; + result.showPeaksAndVales = mShowPeaksAndVales; + result.showTrends = mShowTrends; + result.fillTrends = mSillTrends; + result.showLevels = mShowLevels; + result.showConsolidations = mShowConsolidations; + result.showRibbons = mShowRibbons; + result.showHull = mShowHull; + result.showSSLChannel = mShowSSLChannel; + result.showFibo1Levels = mShowFibo1Levels; + result.showFibo2Levels = mShowFibo2Levels; + result.showFibo3Levels = mShowFibo3Levels; + result.showFibo4Levels = mShowFibo4Levels; + result.showFibo5Levels = mShowFibo5Levels; + + // + return result; + } + + // + // Set Config ... + bool SetConfig(XMANInputs &config) + { + // + bool result = false; + + // + mCandleTimerColor = config.candleTimerColor; + mCandleTimerCorner = config.candleTimerCorner; + mUpColor = config.upColor; + mDownColor = config.downColor; + mLineColor = config.lineColor; + mBearishColor = config.bearishColor; + mBullishColor = config.bullishColor; + mVolumesColor = config.volumesColor; + mChartMode = config.chartMode; + mL1Method = config.l1Method; + mL1Period = config.l1Period; + mL2Method = config.l2Method; + mL2Period = config.l2Period; + mL3Method = config.l3Method; + mL3Period = config.l3Period; + mL4Method = config.l4Method; + mL4Period = config.l4Period; + mFiboLevel1 = config.fiboLevel1; + mFiboLevel2 = config.fiboLevel2; + mFiboLevel3 = config.fiboLevel3; + mFiboLevel4 = config.fiboLevel4; + mFiboLevel5 = config.fiboLevel5; + mHHMode = config.hhMode; + mLLMode = config.llMode; + mTrendMultiplier = config.trendMultiplier; + mTrendPriceAppliedTo = config.trendPriceAppliedTo; + mRibbonMode = config.ribbonMode; + mHullDivisor = config.hullDivisor; + mHullUpAppliedTo = config.hullUpAppliedTo; + mHullDownAppliedTo = config.hullDownAppliedTo; + mSslcMode = config.sslcMode; + mSslcUpAppliedTo = config.sslcUpAppliedTo; + mSslcDownAppliedTo = config.sslcDownAppliedTo; + mShowCandleTimer = config.showCandleTimer; + mShowCandles = config.showCandles; + mShowHKCandles = config.showHKCandles; + mShowPeaksAndVales = config.showPeaksAndVales; + mShowTrends = config.showTrends; + mSillTrends = config.fillTrends; + mShowLevels = config.showLevels; + mShowConsolidations = config.showConsolidations; + mShowRibbons = config.showRibbons; + mShowHull = config.showHull; + mShowSSLChannel = config.showSSLChannel; + mShowFibo1Levels = config.showFibo1Levels; + mShowFibo2Levels = config.showFibo2Levels; + mShowFibo3Levels = config.showFibo3Levels; + mShowFibo4Levels = config.showFibo4Levels; + mShowFibo5Levels = config.showFibo5Levels; + + // + result = Init(); + + // + return result; + } + + // + // Reading Buffers based on Given Bar Index ... + virtual void Calculate( + int barIndex // Given Bar Index + ) + { + // + // Peaks ... + ArraySetAsSeries(peaksBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_LINE, + barIndex, + mLoopbackBars, + peaksBuffer); + + // + // Peaks State ... + ArraySetAsSeries(peaksStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_PEAKS_STATE_LINE, + barIndex, + mLoopbackBars, + peaksStateBuffer); + + // + // Vales ... + ArraySetAsSeries(valesBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_LINE, + barIndex, + mLoopbackBars, + valesBuffer); + + // + // Vales State ... + ArraySetAsSeries(valesStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_VALES_STATE_LINE, + barIndex, + mLoopbackBars, + valesStateBuffer); + + // + // Fibo 1 ... + ArraySetAsSeries(fibLevel1Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L1_LINE, + barIndex, + mLoopbackBars, + fibLevel1Buffer); + + // + // Fibo 2 ... + ArraySetAsSeries(fibLevel2Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L2_LINE, + barIndex, + mLoopbackBars, + fibLevel2Buffer); + + // + // Fibo 3 ... + ArraySetAsSeries(fibLevel3Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L3_LINE, + barIndex, + mLoopbackBars, + fibLevel3Buffer); + + // + // Fibo 4 ... + ArraySetAsSeries(fibLevel4Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L4_LINE, + barIndex, + mLoopbackBars, + fibLevel4Buffer); + + // + // Fibo 5 ... + ArraySetAsSeries(fibLevel5Buffer, true); + CopyBuffer( + mHandler, + XMAN_FIB_L5_LINE, + barIndex, + mLoopbackBars, + fibLevel5Buffer); + + // + // Cycles ... + + // + // Short ... + + // + // High ... + ArraySetAsSeries(sHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_LINE, + barIndex, + mLoopbackBars, + sHHBuffer); + + // + // High State ... + ArraySetAsSeries(sHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + sHHStateBuffer); + + // + // High ... + ArraySetAsSeries(sLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_LINE, + barIndex, + mLoopbackBars, + sLLBuffer); + + // + // High State ... + ArraySetAsSeries(sLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_SC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + sLLStateBuffer); + + // + // Medium ... + + // + // High ... + ArraySetAsSeries(mHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_LINE, + barIndex, + mLoopbackBars, + mHHBuffer); + + // + // High State ... + ArraySetAsSeries(mHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + mHHStateBuffer); + + // + // High ... + ArraySetAsSeries(mLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_LINE, + barIndex, + mLoopbackBars, + mLLBuffer); + + // + // High State ... + ArraySetAsSeries(mLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_MC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + mLLStateBuffer); + + // + // Long ... + + // + // High ... + ArraySetAsSeries(lHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_LINE, + barIndex, + mLoopbackBars, + lHHBuffer); + + // + // High State ... + ArraySetAsSeries(lHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + lHHStateBuffer); + + // + // High ... + ArraySetAsSeries(lLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_LINE, + barIndex, + mLoopbackBars, + lLLBuffer); + + // + // High State ... + ArraySetAsSeries(lLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_LC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + lLLStateBuffer); + + // + // Hind ... + + // + // High ... + ArraySetAsSeries(hHHBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_LINE, + barIndex, + mLoopbackBars, + hHHBuffer); + + // + // High State ... + ArraySetAsSeries(hHHStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_HH_STATE_LINE, + barIndex, + mLoopbackBars, + hHHStateBuffer); + + // + // High ... + ArraySetAsSeries(hLLBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_LINE, + barIndex, + mLoopbackBars, + hLLBuffer); + + // + // High State ... + ArraySetAsSeries(hLLStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HC_LL_STATE_LINE, + barIndex, + mLoopbackBars, + hLLStateBuffer); + + // + // Trend ... + + // + // Trend ... + ArraySetAsSeries(trendBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_LINE, + barIndex, + mLoopbackBars, + trendBuffer); + + // + // Trend State ... + ArraySetAsSeries(trendStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_TREND_STATE_LINE, + barIndex, + mLoopbackBars, + trendStateBuffer); + + // + // Ribbons ... + + // + // 1 ... + + // + // R1 ... + ArraySetAsSeries(ribbon1Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_LINE, + barIndex, + mLoopbackBars, + ribbon1Buffer); + + // + // R1 State ... + ArraySetAsSeries(ribbon1StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB1_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon1StateBuffer); + + // + // 2 ... + + // + // R2 ... + ArraySetAsSeries(ribbon2Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_LINE, + barIndex, + mLoopbackBars, + ribbon2Buffer); + + // + // R2 State ... + ArraySetAsSeries(ribbon2StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB2_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon2StateBuffer); + + // + // 3 ... + + // + // R3 ... + ArraySetAsSeries(ribbon3Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_LINE, + barIndex, + mLoopbackBars, + ribbon3Buffer); + + // + // R3 State ... + ArraySetAsSeries(ribbon3StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB3_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon3StateBuffer); + + // + // 4 ... + + // + // R4 ... + ArraySetAsSeries(ribbon4Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_LINE, + barIndex, + mLoopbackBars, + ribbon4Buffer); + + // + // R4 State ... + ArraySetAsSeries(ribbon4StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB4_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon4StateBuffer); + + // + // 5 ... + + // + // R5 ... + ArraySetAsSeries(ribbon5Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_LINE, + barIndex, + mLoopbackBars, + ribbon5Buffer); + + // + // R5 State ... + ArraySetAsSeries(ribbon5StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB5_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon5StateBuffer); + + // + // 6 ... + + // + // R6 ... + ArraySetAsSeries(ribbon6Buffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_LINE, + barIndex, + mLoopbackBars, + ribbon6Buffer); + + // + // R6 State ... + ArraySetAsSeries(ribbon6StateBuffer, true); + CopyBuffer( + mHandler, + XMAN_RB6_STATE_LINE, + barIndex, + mLoopbackBars, + ribbon6StateBuffer); + + // + // SSL Channel ... + + // + // UP ... + ArraySetAsSeries(sslUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_UP_LINE, + barIndex, + mLoopbackBars, + sslUpBuffer); + + // + // DOWN ... + ArraySetAsSeries(sslDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_SSLC_DOWN_LINE, + barIndex, + mLoopbackBars, + sslDownBuffer); + + // + // HULL Trend ... + + // + // UP ... + ArraySetAsSeries(hullUpBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_LINE, + barIndex, + mLoopbackBars, + hullUpBuffer); + + // + // UP State ... + ArraySetAsSeries(hullUpStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_UP_STATE_LINE, + barIndex, + mLoopbackBars, + hullUpStateBuffer); + + // + // DOWN ... + ArraySetAsSeries(hullDownBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_LINE, + barIndex, + mLoopbackBars, + hullDownBuffer); + + // + // DOWN State ... + ArraySetAsSeries(hullDownStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HULL_DOWN_STATE_LINE, + barIndex, + mLoopbackBars, + hullDownStateBuffer); + + // + // Hiken Ashi ... + + // + // Open ... + ArraySetAsSeries(hkOpenBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_OPEN_LINE, + barIndex, + mLoopbackBars, + hkOpenBuffer); + + // + // High ... + ArraySetAsSeries(hkHighBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_HIGH_LINE, + barIndex, + mLoopbackBars, + hkHighBuffer); + + // + // Low ... + ArraySetAsSeries(hkLowBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_LOW_LINE, + barIndex, + mLoopbackBars, + hkLowBuffer); + + // + // Close ... + ArraySetAsSeries(hkCloseBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_CLOSE_LINE, + barIndex, + mLoopbackBars, + hkCloseBuffer); + + // + // Close ... + ArraySetAsSeries(hkStateBuffer, true); + CopyBuffer( + mHandler, + XMAN_HK_STATE_LINE, + barIndex, + mLoopbackBars, + hkStateBuffer); + } + + // + // Retrieve Info at Specific Bar Index ... + XMANInfo GetInfo( + int barIndex // Given Bar Index + ) + { + // + XMANInfo result; + + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + // Do Calculations ... + Calculate(barIndex); + + // + // Generate Candle Time ... + datetime barTime = GetCandleTime( + mSymbol, + mPeriod, + barIndex); + + // + // Fill Result ... + result.symbol = mSymbol; + result.period = mPeriod; + result.barTime = barTime; + result.barIndex = barIndex; + + // + // Buffers ... + + // + Copy(peaksBuffer, + result.peaks); + Copy(peaksStateBuffer, + result.peaksStates); + Copy(valesBuffer, + result.vales); + Copy(valesStateBuffer, + result.valesStates); + + // + Copy(fibLevel1Buffer, + result.fibLevel1s); + Copy(fibLevel2Buffer, + result.fibLevel2s); + Copy(fibLevel3Buffer, + result.fibLevel3s); + Copy(fibLevel4Buffer, + result.fibLevel4s); + Copy(fibLevel5Buffer, + result.fibLevel5s); + + // + Copy(sHHBuffer, + result.sHHs); + Copy(sHHStateBuffer, + result.sHHStates); + Copy(sLLBuffer, + result.sLLs); + Copy(sLLStateBuffer, + result.sLLStates); + + // + Copy(mHHBuffer, + result.mHHs); + Copy(mHHStateBuffer, + result.mHHStates); + Copy(mLLBuffer, + result.mLLs); + Copy(mLLStateBuffer, + result.mLLStates); + + // + Copy(lHHBuffer, + result.lHHs); + Copy(lHHStateBuffer, + result.lHHStates); + Copy(lLLBuffer, + result.lLLs); + Copy(lLLStateBuffer, + result.lLLStates); + + // + Copy(hHHBuffer, + result.hHHs); + Copy(hHHStateBuffer, + result.hHHStates); + Copy(hLLBuffer, + result.hLLs); + Copy(hLLStateBuffer, + result.hLLStates); + + // + Copy(trendBuffer, + result.trends); + Copy(trendStateBuffer, + result.trendStates); + + // + Copy(ribbon1Buffer, + result.ribbon1s); + Copy(ribbon1StateBuffer, + result.ribbon1States); + + // + Copy(ribbon2Buffer, + result.ribbon2s); + Copy(ribbon2StateBuffer, + result.ribbon2States); + + // + Copy(ribbon3Buffer, + result.ribbon3s); + Copy(ribbon3StateBuffer, + result.ribbon3States); + + // + Copy(ribbon4Buffer, + result.ribbon4s); + Copy(ribbon4StateBuffer, + result.ribbon4States); + + // + Copy(ribbon5Buffer, + result.ribbon5s); + Copy(ribbon5StateBuffer, + result.ribbon5States); + + // + Copy(ribbon6Buffer, + result.ribbon6s); + Copy(ribbon6StateBuffer, + result.ribbon6States); + + // + Copy(sslUpBuffer, + result.sslcUps); + Copy(sslDownBuffer, + result.sslcDowns); + + // + Copy(hullUpBuffer, + result.hullUps); + Copy(hullUpStateBuffer, + result.hullUpStates); + Copy(hullDownBuffer, + result.hullDowns); + Copy(hullDownStateBuffer, + result.hullDownStates); + + // + Copy(hkOpenBuffer, + result.hkOpens); + Copy(hkHighBuffer, + result.hkHighs); + Copy(hkLowBuffer, + result.hkLows); + Copy(hkCloseBuffer, + result.hkCloses); + Copy(hkStateBuffer, + result.hkStates); + + // + int idx = 0; + + // + // Conditions ... + bool isNewPeak = + // + peaksStateBuffer[idx] != EMPTY_VALUE + // + ; + bool isNewVale = + // + valesStateBuffer[idx] != EMPTY_VALUE + // + ; + + // + // XSTR ... + + // + // Reading Temp ... + ENUM_XMAN_STATES trendState = (ENUM_XMAN_STATES)trendStateBuffer[idx]; + ENUM_XMAN_STATES trendStatePrev = (ENUM_XMAN_STATES)trendStateBuffer[idx + 1]; + + // + bool isTrendBullish = + // + trendState == XMAN_STATE_BULLISH + // + ; + + // + bool isTrendPrevBullish = + // + trendStatePrev == XMAN_STATE_BULLISH + // + ; + + // + bool isTrendSwitchedToBullish = + // + isTrendBullish && + !isTrendPrevBullish + // + ; + + // + bool isTrendBearish = + // + trendState == XMAN_STATE_BEARISH + // + ; + + // + bool isTrendPrevBearish = + // + trendStatePrev == XMAN_STATE_BEARISH + // + ; + + // + bool isTrendSwitchedToBearish = + // + isTrendBearish && + !isTrendPrevBearish + // + ; + + // + bool isTrendNeutural = + // + !isTrendBullish && + !isTrendBearish + // + ; + + // + bool isTrendPrevNeutural = + // + !isTrendPrevBullish && + !isTrendPrevBearish + // + ; + + // + bool isTrendSwitchedToNeutural = + // + isTrendNeutural && + !isTrendPrevNeutural + // + ; + + // + // XSSLC ... + + // + bool isSSLCBullish = + // + sslUpBuffer[idx] > sslDownBuffer[idx] + // + ; + + // + bool isSSLPrevBullish = + // + sslUpBuffer[idx + 1] > sslDownBuffer[idx + 1] + // + ; + + // + bool isSSLCSwitchedToBullish = + // + isSSLCBullish && + !isSSLPrevBullish + // + ; + + // + bool isSSLCBearish = + // + sslUpBuffer[idx] < sslDownBuffer[idx] + // + ; + + // + bool isSSLPrevBearish = + // + sslUpBuffer[idx + 1] < sslDownBuffer[idx + 1] + // + ; + + // + bool isSSLCSwitchedToBearish = + // + isSSLCBearish && + !isSSLPrevBearish + // + ; + + // + bool isSSLCNeutural = + // + !isSSLCBullish && + !isSSLCBearish + // + ; + + // + bool isSSLPrevNeutural = + // + !isSSLPrevBullish && + !isSSLPrevBearish + // + ; + + // + bool isSSLCSwitchedToNeutural = + // + isSSLCNeutural && + !isSSLPrevNeutural + // + ; + + // + // XHULL ... + + // + bool isHullUpBullish = + // + hullUpStateBuffer[idx] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullUpPrevBullish = + // + hullUpStateBuffer[idx + 1] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullDownBullish = + // + hullDownStateBuffer[idx] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullDownPrevBullish = + // + hullDownStateBuffer[idx + 1] == XMAN_STATE_BULLISH + // + ; + + // + bool isHullBullish = + // + isHullUpBullish && + isHullDownBullish + // + ; + + // + bool isHullPrevBullish = + // + isHullUpPrevBullish && + isHullDownPrevBullish + // + ; + + // + bool isHullSwitchedToBullish = + // + isHullBullish && + !isHullPrevBullish + // + ; + + // + bool isHullUpBearish = + // + hullUpStateBuffer[idx] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullUpPrevBearish = + // + hullUpStateBuffer[idx + 1] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullDownBearish = + // + hullDownStateBuffer[idx] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullDownPrevBearish = + // + hullDownStateBuffer[idx + 1] == XMAN_STATE_BEARISH + // + ; + + // + bool isHullBearish = + // + isHullUpBearish && + isHullDownBearish + // + ; + + // + bool isHullPrevBearish = + // + isHullUpPrevBearish && + isHullDownPrevBearish + // + ; + + // + bool isHullSwitchedToBearish = + // + isHullBearish && + !isHullPrevBearish + // + ; + + // + bool isHullUpNeutural = + // + !isHullUpBullish && + !isHullUpBearish + // + ; + + // + bool isHullUpPrevNeutural = + // + !isHullUpPrevBullish && + !isHullUpPrevBearish + // + ; + + // + bool isHullDownNeutural = + // + !isHullDownBullish && + !isHullDownBearish + // + ; + + // + bool isHullDownPrevNeutural = + // + !isHullDownPrevBullish && + !isHullDownPrevBearish + // + ; + + // + bool isHullNeutural = + // + isHullUpNeutural && + isHullDownNeutural + // + ; + + // + bool isHullPrevNeutural = + // + isHullUpPrevNeutural && + isHullDownPrevNeutural + // + ; + + // + bool isHullSwitchedToNeutural = + // + isHullNeutural && + !isHullPrevNeutural + // + ; + + // + // XHK ... + + // + // Hiken Ashi ... + bool isHKBullish = + // + hkStateBuffer[idx] == XMAN_STATE_BULLISH + // + ; + bool isHKBearish = + // + hkStateBuffer[idx] == XMAN_STATE_BEARISH + // + ; + + // + // Cycles ... + + // + // Level 1 ... + + // + ENUM_XMAN_STATES scHState = (ENUM_XMAN_STATES)sHHStateBuffer[idx]; + ENUM_XMAN_STATES scHStatePrev = (ENUM_XMAN_STATES)sHHStateBuffer[idx + 1]; + ENUM_XMAN_STATES scLState = (ENUM_XMAN_STATES)sLLStateBuffer[idx]; + ENUM_XMAN_STATES scLStatePrev = (ENUM_XMAN_STATES)sLLStateBuffer[idx + 1]; + + // + // Bullish ... + + // + bool isSCHBullish = scHState == XMAN_STATE_BULLISH; + bool isSCHPrevBullish = scHStatePrev == XMAN_STATE_BULLISH; + + // + bool isSCLBullish = scLState == XMAN_STATE_BULLISH; + bool isSCLPrevBullish = scLStatePrev == XMAN_STATE_BULLISH; + + // + bool isSCBullish = + isSCHBullish && + isSCLBullish; + + // + bool isSCPrevBullish = + isSCHPrevBullish && + isSCLPrevBullish; + + // + bool isSCHSwitchedToBullish = + isSCHBullish && + !isSCHPrevBullish; + + // + bool isSCLSwitchedToBullish = + isSCLBullish && + !isSCLPrevBullish; + + // + bool isSCSwitchedToBullish = + isSCBullish && + !isSCPrevBullish; + + // + // Bearish ... + + // + bool isSCHBearish = scHState == XMAN_STATE_BEARISH; + bool isSCHPrevBearish = scHStatePrev == XMAN_STATE_BEARISH; + + // + bool isSCLBearish = scLState == XMAN_STATE_BEARISH; + bool isSCLPrevBearish = scLStatePrev == XMAN_STATE_BEARISH; + + // + bool isSCBearish = + isSCHBearish && + isSCLBearish; + + // + bool isSCPrevBearish = + isSCHPrevBearish && + isSCLPrevBearish; + + // + bool isSCHSwitchedToBearish = + isSCHBearish && + !isSCHPrevBearish; + + // + bool isSCLSwitchedToBearish = + isSCLBearish && + !isSCLPrevBearish; + + // + bool isSCSwitchedToBearish = + isSCBearish && + !isSCPrevBearish; + + // + // Neutural ... + + // + bool isSCHNeutural = + !isSCHBullish && + !isSCHBearish; + + // + bool isSCHPrevNeutural = + !isSCHPrevBullish && + !isSCHPrevBearish; + + // + bool isSCLNeutural = + !isSCLBullish && + !isSCLBearish; + + // + bool isSCLPrevNeutural = + !isSCLPrevBullish && + !isSCLPrevBearish; + + // + bool isSCNeutural = + isSCHNeutural && + isSCLNeutural; + + // + bool isSCPrevNeutural = + isSCHPrevNeutural && + isSCLPrevNeutural; + + // + bool isSCHSwitchedToNeutural = + isSCHNeutural && + !isSCHPrevNeutural; + + // + bool isSCLSwitchedToNeutural = + isSCLNeutural && + !isSCLPrevNeutural; + + // + bool isSCSwitchedToNeutural = + isSCNeutural && + !isSCPrevNeutural; + + // + // Level 2 ... + + // + ENUM_XMAN_STATES mcHState = (ENUM_XMAN_STATES)mHHStateBuffer[idx]; + ENUM_XMAN_STATES mcHStatePrev = (ENUM_XMAN_STATES)mHHStateBuffer[idx + 1]; + ENUM_XMAN_STATES mcLState = (ENUM_XMAN_STATES)mLLStateBuffer[idx]; + ENUM_XMAN_STATES mcLStatePrev = (ENUM_XMAN_STATES)mLLStateBuffer[idx + 1]; + + // + // Bullish ... + + // + bool isMCHBullish = mcHState == XMAN_STATE_BULLISH; + bool isMCHPrevBullish = mcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isMCLBullish = mcLState == XMAN_STATE_BULLISH; + bool isMCLPrevBullish = mcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isMCBullish = + isMCHBullish && + isMCLBullish; + + // + bool isMCPrevBullish = + isMCHPrevBullish && + isMCLPrevBullish; + + // + bool isMCHSwitchedToBullish = + isMCHBullish && + !isMCHPrevBullish; + + // + bool isMCLSwitchedToBullish = + isMCLBullish && + !isMCLPrevBullish; + + // + bool isMCSwitchedToBullish = + isMCBullish && + !isMCPrevBullish; + + // + // Bearish ... + + // + bool isMCHBearish = mcHState == XMAN_STATE_BEARISH; + bool isMCHPrevBearish = mcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isMCLBearish = mcLState == XMAN_STATE_BEARISH; + bool isMCLPrevBearish = mcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isMCBearish = + isMCHBearish && + isMCLBearish; + + // + bool isMCPrevBearish = + isMCHPrevBearish && + isMCLPrevBearish; + + // + bool isMCHSwitchedToBearish = + isMCHBearish && + !isMCHPrevBearish; + + // + bool isMCLSwitchedToBearish = + isMCLBearish && + !isMCLPrevBearish; + + // + bool isMCSwitchedToBearish = + isMCBearish && + !isMCPrevBearish; + + // + // Neutural ... + + // + bool isMCHNeutural = + !isMCHBullish && + !isMCHBearish; + + // + bool isMCHPrevNeutural = + !isMCHPrevBullish && + !isMCHPrevBearish; + + // + bool isMCLNeutural = + !isMCLBullish && + !isMCLBearish; + + // + bool isMCLPrevNeutural = + !isMCLPrevBullish && + !isMCLPrevBearish; + + // + bool isMCNeutural = + isMCHNeutural && + isMCLNeutural; + + // + bool isMCPrevNeutural = + isMCHPrevNeutural && + isMCLPrevNeutural; + + // + bool isMCHSwitchedToNeutural = + isMCHNeutural && + !isMCHPrevNeutural; + + // + bool isMCLSwitchedToNeutural = + isMCLNeutural && + !isMCLPrevNeutural; + + // + bool isMCSwitchedToNeutural = + isMCNeutural && + !isMCPrevNeutural; + + // + // Level 3 ... + + // + ENUM_XMAN_STATES lcHState = (ENUM_XMAN_STATES)lHHStateBuffer[idx]; + ENUM_XMAN_STATES lcHStatePrev = (ENUM_XMAN_STATES)lHHStateBuffer[idx + 1]; + ENUM_XMAN_STATES lcLState = (ENUM_XMAN_STATES)lLLStateBuffer[idx]; + ENUM_XMAN_STATES lcLStatePrev = (ENUM_XMAN_STATES)lLLStateBuffer[idx + 1]; + + // + // Bullish ... + + // + bool isLCHBullish = lcHState == XMAN_STATE_BULLISH; + bool isLCHPrevBullish = lcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isLCLBullish = lcLState == XMAN_STATE_BULLISH; + bool isLCLPrevBullish = lcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isLCBullish = + isLCHBullish && + isLCLBullish; + + // + bool isLCPrevBullish = + isLCHPrevBullish && + isLCLPrevBullish; + + // + bool isLCHSwitchedToBullish = + isLCHBullish && + !isLCHPrevBullish; + + // + bool isLCLSwitchedToBullish = + isLCLBullish && + !isLCLPrevBullish; + + // + bool isLCSwitchedToBullish = + isLCBullish && + !isLCPrevBullish; + + // + // Bearish ... + + // + bool isLCHBearish = lcHState == XMAN_STATE_BEARISH; + bool isLCHPrevBearish = lcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isLCLBearish = lcLState == XMAN_STATE_BEARISH; + bool isLCLPrevBearish = lcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isLCBearish = + isLCHBearish && + isLCLBearish; + + // + bool isLCPrevBearish = + isLCHPrevBearish && + isLCLPrevBearish; + + // + bool isLCHSwitchedToBearish = + isLCHBearish && + !isLCHPrevBearish; + + // + bool isLCLSwitchedToBearish = + isLCLBearish && + !isLCLPrevBearish; + + // + bool isLCSwitchedToBearish = + isLCBearish && + !isLCPrevBearish; + + // + // Neutural ... + + // + bool isLCHNeutural = + !isLCHBullish && + !isLCHBearish; + + // + bool isLCHPrevNeutural = + !isLCHPrevBullish && + !isLCHPrevBearish; + + // + bool isLCLNeutural = + !isLCLBullish && + !isLCLBearish; + + // + bool isLCLPrevNeutural = + !isLCLPrevBullish && + !isLCLPrevBearish; + + // + bool isLCNeutural = + isLCHNeutural && + isLCLNeutural; + + // + bool isLCPrevNeutural = + isLCHPrevNeutural && + isLCLPrevNeutural; + + // + bool isLCHSwitchedToNeutural = + isLCHNeutural && + !isLCHPrevNeutural; + + // + bool isLCLSwitchedToNeutural = + isLCLNeutural && + !isLCLPrevNeutural; + + // + bool isLCSwitchedToNeutural = + isLCNeutural && + !isLCPrevNeutural; + + // + // Level 4 ... + + // + ENUM_XMAN_STATES hcHState = (ENUM_XMAN_STATES)hHHStateBuffer[idx]; + ENUM_XMAN_STATES hcHStatePrev = (ENUM_XMAN_STATES)hHHStateBuffer[idx + 1]; + ENUM_XMAN_STATES hcLState = (ENUM_XMAN_STATES)hLLStateBuffer[idx]; + ENUM_XMAN_STATES hcLStatePrev = (ENUM_XMAN_STATES)hLLStateBuffer[idx + 1]; + + // + // Bullish ... + + // + bool isHCHBullish = hcHState == XMAN_STATE_BULLISH; + bool isHCHPrevBullish = hcHStatePrev == XMAN_STATE_BULLISH; + + // + bool isHCLBullish = hcLState == XMAN_STATE_BULLISH; + bool isHCLPrevBullish = hcLStatePrev == XMAN_STATE_BULLISH; + + // + bool isHCBullish = + isHCHBullish && + isHCLBullish; + + // + bool isHCPrevBullish = + isHCHPrevBullish && + isHCLPrevBullish; + + // + bool isHCHSwitchedToBullish = + isHCHBullish && + !isHCHPrevBullish; + + // + bool isHCLSwitchedToBullish = + isHCLBullish && + !isHCLPrevBullish; + + // + bool isHCSwitchedToBullish = + isHCBullish && + !isHCPrevBullish; + + // + // Bearish ... + + // + bool isHCHBearish = hcHState == XMAN_STATE_BEARISH; + bool isHCHPrevBearish = hcHStatePrev == XMAN_STATE_BEARISH; + + // + bool isHCLBearish = hcLState == XMAN_STATE_BEARISH; + bool isHCLPrevBearish = hcLStatePrev == XMAN_STATE_BEARISH; + + // + bool isHCBearish = + isHCHBearish && + isHCLBearish; + + // + bool isHCPrevBearish = + isHCHPrevBearish && + isHCLPrevBearish; + + // + bool isHCHSwitchedToBearish = + isHCHBearish && + !isHCHPrevBearish; + + // + bool isHCLSwitchedToBearish = + isHCLBearish && + !isHCLPrevBearish; + + // + bool isHCSwitchedToBearish = + isHCBearish && + !isHCPrevBearish; + + // + // Neutural ... + + // + bool isHCHNeutural = + !isHCHBullish && + !isHCHBearish; + + // + bool isHCHPrevNeutural = + !isHCHPrevBullish && + !isHCHPrevBearish; + + // + bool isHCLNeutural = + !isHCLBullish && + !isHCLBearish; + + // + bool isHCLPrevNeutural = + !isHCLPrevBullish && + !isHCLPrevBearish; + + // + bool isHCNeutural = + isHCHNeutural && + isHCLNeutural; + + // + bool isHCPrevNeutural = + isHCHPrevNeutural && + isHCLPrevNeutural; + + // + bool isHCHSwitchedToNeutural = + isHCHNeutural && + !isHCHPrevNeutural; + + // + bool isHCLSwitchedToNeutural = + isHCLNeutural && + !isHCLPrevNeutural; + + // + bool isHCSwitchedToNeutural = + isHCNeutural && + !isHCPrevNeutural; + + // + // Ribbons ... + + // + // R1 ... + ENUM_XMAN_STATES r1State = (ENUM_XMAN_STATES)ribbon1StateBuffer[idx]; + ENUM_XMAN_STATES r1StatePrev = (ENUM_XMAN_STATES)ribbon1StateBuffer[idx + 1]; + + // + // R2 ... + ENUM_XMAN_STATES r2State = (ENUM_XMAN_STATES)ribbon2StateBuffer[idx]; + ENUM_XMAN_STATES r2StatePrev = (ENUM_XMAN_STATES)ribbon2StateBuffer[idx + 1]; + + // + // R3 ... + ENUM_XMAN_STATES r3State = (ENUM_XMAN_STATES)ribbon3StateBuffer[idx]; + ENUM_XMAN_STATES r3StatePrev = (ENUM_XMAN_STATES)ribbon3StateBuffer[idx + 1]; + + // + // R4 ... + ENUM_XMAN_STATES r4State = (ENUM_XMAN_STATES)ribbon4StateBuffer[idx]; + ENUM_XMAN_STATES r4StatePrev = (ENUM_XMAN_STATES)ribbon4StateBuffer[idx + 1]; + + // + // R5 ... + ENUM_XMAN_STATES r5State = (ENUM_XMAN_STATES)ribbon5StateBuffer[idx]; + ENUM_XMAN_STATES r5StatePrev = (ENUM_XMAN_STATES)ribbon5StateBuffer[idx + 1]; + + // + // R6 ... + ENUM_XMAN_STATES r6State = (ENUM_XMAN_STATES)ribbon6StateBuffer[idx]; + ENUM_XMAN_STATES r6StatePrev = (ENUM_XMAN_STATES)ribbon6StateBuffer[idx + 1]; + + // + // Bullish ... + + // + bool isRibbon1Bullish = r1State == XMAN_STATE_BULLISH; + bool isRibbon2Bullish = r2State == XMAN_STATE_BULLISH; + bool isRibbon3Bullish = r3State == XMAN_STATE_BULLISH; + bool isRibbon4Bullish = r4State == XMAN_STATE_BULLISH; + bool isRibbon5Bullish = r5State == XMAN_STATE_BULLISH; + bool isRibbon6Bullish = r6State == XMAN_STATE_BULLISH; + + // + bool isRibbon1PrevBullish = r1StatePrev == XMAN_STATE_BULLISH; + bool isRibbon2PrevBullish = r2StatePrev == XMAN_STATE_BULLISH; + bool isRibbon3PrevBullish = r3StatePrev == XMAN_STATE_BULLISH; + bool isRibbon4PrevBullish = r4StatePrev == XMAN_STATE_BULLISH; + bool isRibbon5PrevBullish = r5StatePrev == XMAN_STATE_BULLISH; + bool isRibbon6PrevBullish = r6StatePrev == XMAN_STATE_BULLISH; + + // + // Bearish ... + + // + bool isRibbon1Bearish = r1State == XMAN_STATE_BEARISH; + bool isRibbon2Bearish = r2State == XMAN_STATE_BEARISH; + bool isRibbon3Bearish = r3State == XMAN_STATE_BEARISH; + bool isRibbon4Bearish = r4State == XMAN_STATE_BEARISH; + bool isRibbon5Bearish = r5State == XMAN_STATE_BEARISH; + bool isRibbon6Bearish = r6State == XMAN_STATE_BEARISH; + + // + bool isRibbon1PrevBearish = r1StatePrev == XMAN_STATE_BEARISH; + bool isRibbon2PrevBearish = r2StatePrev == XMAN_STATE_BEARISH; + bool isRibbon3PrevBearish = r3StatePrev == XMAN_STATE_BEARISH; + bool isRibbon4PrevBearish = r4StatePrev == XMAN_STATE_BEARISH; + bool isRibbon5PrevBearish = r5StatePrev == XMAN_STATE_BEARISH; + bool isRibbon6PrevBearish = r6StatePrev == XMAN_STATE_BEARISH; + + // + // Neutural ... + + // + bool isRibbon1Neutural = + !isRibbon1Bullish && + !isRibbon1Bearish; + + // + bool isRibbon2Neutural = + !isRibbon2Bullish && + !isRibbon2Bearish; + + // + bool isRibbon3Neutural = + !isRibbon3Bullish && + !isRibbon3Bearish; + + // + bool isRibbon4Neutural = + !isRibbon4Bullish && + !isRibbon4Bearish; + + // + bool isRibbon5Neutural = + !isRibbon5Bullish && + !isRibbon5Bearish; + + // + bool isRibbon6Neutural = + !isRibbon6Bullish && + !isRibbon6Bearish; + + // + bool isRibbon1PrevNeutural = + !isRibbon1PrevBullish && + !isRibbon1PrevBearish; + + // + bool isRibbon2PrevNeutural = + !isRibbon2PrevBullish && + !isRibbon2PrevBearish; + + // + bool isRibbon3PrevNeutural = + !isRibbon3PrevBullish && + !isRibbon3PrevBearish; + + // + bool isRibbon4PrevNeutural = + !isRibbon4PrevBullish && + !isRibbon4PrevBearish; + + // + bool isRibbon5PrevNeutural = + !isRibbon5PrevBullish && + !isRibbon5PrevBearish; + + // + bool isRibbon6PrevNeutural = + !isRibbon6PrevBullish && + !isRibbon6PrevBearish; + + // + // All Ribbons ... + + // + bool isRibbonBullish = + isRibbon1Bullish && + isRibbon2Bullish && + isRibbon3Bullish && + isRibbon4Bullish && + isRibbon5Bullish && + isRibbon6Bullish; + // + bool isRibbonPrevBullish = + isRibbon1PrevBullish && + isRibbon2PrevBullish && + isRibbon3PrevBullish && + isRibbon4PrevBullish && + isRibbon5PrevBullish && + isRibbon6PrevBullish; + + // + bool isRibbonSwitchedToBullish = + isRibbonBullish && + !isRibbonPrevBullish; + + // + bool isRibbonBearish = + isRibbon1Bearish && + isRibbon2Bearish && + isRibbon3Bearish && + isRibbon4Bearish && + isRibbon5Bearish && + isRibbon6Bearish; + + // + bool isRibbonPrevBearish = + isRibbon1PrevBearish && + isRibbon2PrevBearish && + isRibbon3PrevBearish && + isRibbon4PrevBearish && + isRibbon5PrevBearish && + isRibbon6PrevBearish; + + // + bool isRibbonSwitchedToBearish = + isRibbonBearish && + !isRibbonPrevBearish; + + // + bool isRibbonNeutural = + isRibbon1Neutural && + isRibbon2Neutural && + isRibbon3Neutural && + isRibbon4Neutural && + isRibbon5Neutural && + isRibbon6Neutural; + + // + bool isRibbonPrevNeutural = + isRibbon1PrevNeutural && + isRibbon2PrevNeutural && + isRibbon3PrevNeutural && + isRibbon4PrevNeutural && + isRibbon5PrevNeutural && + isRibbon6PrevNeutural; + + // + bool isRibbonSwitchedToNeutural = + isRibbonNeutural && + !isRibbonPrevNeutural; + + // + result.isNewPeak = isNewPeak; + result.isNewVale = isNewVale; + result.isTrendBullish = isTrendBullish; + result.isTrendSwitchedToBullish = isTrendSwitchedToBullish; + result.isTrendBearish = isTrendBearish; + result.isTrendSwitchedToBearish = isTrendSwitchedToBearish; + result.isTrendNeutural = isTrendNeutural; + result.isTrendSwitchedToNeutural = isTrendSwitchedToNeutural; + result.isSSLCBullish = isSSLCBullish; + result.isSSLCSwitchedToBullish = isSSLCSwitchedToBullish; + result.isSSLCBearish = isSSLCBearish; + result.isSSLCSwitchedToBearish = isSSLCSwitchedToBearish; + result.isSSLCNeutural = isSSLCNeutural; + result.isSSLCSwitchedToNeutural = isSSLCSwitchedToNeutural; + result.isHullBullish = isHullBullish; + result.isHullUpBullish = isHullUpBullish; + result.isHullDownBullish = isHullDownBullish; + result.isHullSwitchedToBullish = isHullSwitchedToBullish; + result.isHullBearish = isHullBearish; + result.isHullUpBearish = isHullUpBearish; + result.isHullDownBearish = isHullDownBearish; + result.isHullSwitchedToBearish = isHullSwitchedToBearish; + result.isHullNeutural = isHullNeutural; + result.isHullUpNeutural = isHullUpNeutural; + result.isHullDownNeutural = isHullDownNeutural; + result.isHullSwitchedToNeutural = isHullSwitchedToNeutural; + result.isHKBullish = isHKBullish; + result.isHKBearish = isHKBearish; + result.isSCBullish = isSCBullish; + result.isSCHBullish = isSCHBullish; + result.isSCLBullish = isSCLBullish; + result.isSCSwitchedToBullish = isSCSwitchedToBullish; + result.isSCHSwitchedToBullish = isSCHSwitchedToBullish; + result.isSCLSwitchedToBullish = isSCLSwitchedToBullish; + result.isSCBearish = isSCBearish; + result.isSCHBearish = isSCHBearish; + result.isSCLBearish = isSCLBearish; + result.isSCSwitchedToBearish = isSCSwitchedToBearish; + result.isSCHSwitchedToBearish = isSCHSwitchedToBearish; + result.isSCLSwitchedToBearish = isSCLSwitchedToBearish; + result.isSCNeutural = isSCNeutural; + result.isSCHNeutural = isSCHNeutural; + result.isSCLNeutural = isSCLNeutural; + result.isSCSwitchedToNeutural = isSCSwitchedToNeutural; + result.isSCHSwitchedToNeutural = isSCHSwitchedToNeutural; + result.isSCLSwitchedToNeutural = isSCLSwitchedToNeutural; + result.isMCBullish = isMCBullish; + result.isMCHBullish = isMCHBullish; + result.isMCLBullish = isMCLBullish; + result.isMCSwitchedToBullish = isMCSwitchedToBullish; + result.isMCHSwitchedToBullish = isMCHSwitchedToBullish; + result.isMCLSwitchedToBullish = isMCLSwitchedToBullish; + result.isMCBearish = isMCBearish; + result.isMCHBearish = isMCHBearish; + result.isMCLBearish = isMCLBearish; + result.isMCSwitchedToBearish = isMCSwitchedToBearish; + result.isMCHSwitchedToBearish = isMCHSwitchedToBearish; + result.isMCLSwitchedToBearish = isMCLSwitchedToBearish; + result.isMCNeutural = isMCNeutural; + result.isMCHNeutural = isMCHNeutural; + result.isMCLNeutural = isMCLNeutural; + result.isMCSwitchedToNeutural = isMCSwitchedToNeutural; + result.isMCHSwitchedToNeutural = isMCHSwitchedToNeutural; + result.isMCLSwitchedToNeutural = isMCLSwitchedToNeutural; + result.isLCBullish = isLCBullish; + result.isLCHBullish = isLCHBullish; + result.isLCLBullish = isLCLBullish; + result.isLCSwitchedToBullish = isLCSwitchedToBullish; + result.isLCHSwitchedToBullish = isLCHSwitchedToBullish; + result.isLCLSwitchedToBullish = isLCLSwitchedToBullish; + result.isLCBearish = isLCBearish; + result.isLCHBearish = isLCHBearish; + result.isLCLBearish = isLCLBearish; + result.isLCSwitchedToBearish = isLCSwitchedToBearish; + result.isLCHSwitchedToBearish = isLCHSwitchedToBearish; + result.isLCLSwitchedToBearish = isLCLSwitchedToBearish; + result.isLCNeutural = isLCNeutural; + result.isLCHNeutural = isLCHNeutural; + result.isLCLNeutural = isLCLNeutural; + result.isLCSwitchedToNeutural = isLCSwitchedToNeutural; + result.isLCHSwitchedToNeutural = isLCHSwitchedToNeutural; + result.isLCLSwitchedToNeutural = isLCLSwitchedToNeutural; + result.isHCBullish = isHCBullish; + result.isHCHBullish = isHCHBullish; + result.isHCLBullish = isHCLBullish; + result.isHCSwitchedToBullish = isHCSwitchedToBullish; + result.isHCHSwitchedToBullish = isHCHSwitchedToBullish; + result.isHCLSwitchedToBullish = isHCLSwitchedToBullish; + result.isHCBearish = isHCBearish; + result.isHCHBearish = isHCHBearish; + result.isHCLBearish = isHCLBearish; + result.isHCSwitchedToBearish = isHCSwitchedToBearish; + result.isHCHSwitchedToBearish = isHCHSwitchedToBearish; + result.isHCLSwitchedToBearish = isHCLSwitchedToBearish; + result.isHCNeutural = isHCNeutural; + result.isHCHNeutural = isHCHNeutural; + result.isHCLNeutural = isHCLNeutural; + result.isHCSwitchedToNeutural = isHCSwitchedToNeutural; + result.isHCHSwitchedToNeutural = isHCHSwitchedToNeutural; + result.isHCLSwitchedToNeutural = isHCLSwitchedToNeutural; + result.isRibbon1Bullish = isRibbon1Bullish; + result.isRibbon2Bullish = isRibbon2Bullish; + result.isRibbon3Bullish = isRibbon3Bullish; + result.isRibbon4Bullish = isRibbon4Bullish; + result.isRibbon5Bullish = isRibbon5Bullish; + result.isRibbon6Bullish = isRibbon6Bullish; + result.isRibbon1Bearish = isRibbon1Bearish; + result.isRibbon2Bearish = isRibbon2Bearish; + result.isRibbon3Bearish = isRibbon3Bearish; + result.isRibbon4Bearish = isRibbon4Bearish; + result.isRibbon5Bearish = isRibbon5Bearish; + result.isRibbon6Bearish = isRibbon6Bearish; + result.isRibbon1Neutural = isRibbon1Neutural; + result.isRibbon2Neutural = isRibbon2Neutural; + result.isRibbon3Neutural = isRibbon3Neutural; + result.isRibbon4Neutural = isRibbon4Neutural; + result.isRibbon5Neutural = isRibbon5Neutural; + result.isRibbon6Neutural = isRibbon6Neutural; + result.isRibbonBullish = isRibbonBullish; + result.isRibbonSwitchedToBullish = isRibbonSwitchedToBullish; + result.isRibbonBearish = isRibbonBearish; + result.isRibbonSwitchedToBearish = isRibbonSwitchedToBearish; + result.isRibbonNeutural = isRibbonNeutural; + result.isRibbonSwitchedToNeutural = isRibbonSwitchedToNeutural; + + // + return result; + } + + // + // TOOLS ... + + // + bool IsValesTrendBearish( + int count = 10 // Number of Values Processed + ) + { + // + bool result = false; + + // + int calculatedVales = 0; + int verifier = 0; + + // + int availableBars = Bars( + mSymbol, + mPeriod); + + // + for (int i = 1; i < availableBars - 2; i++) + { + // + // Update Buffers ... + Calculate(i); + + // + // Check New Vale Happens ... + bool isNewVale = + // + valesBuffer[0] != valesBuffer[1] + // + ; + if (!isNewVale) + { + continue; + } + + // + // Check New Vale is Over last or Under Last ... + bool isOverLastVale = + // + valesBuffer[0] > valesBuffer[1] + // + ; + + // + // Set Verifier Value based On New Vale State ... + if (isOverLastVale) + { + verifier++; + } + else + { + verifier--; + } + + // + // Increase Number of Calculated Vales ... + calculatedVales++; + + // + // Break when Calculating required Vales ... + if (calculatedVales >= count) + { + break; + } + } + + // + result = verifier < 0; + + // + return result; + } + + // + bool IsValesTrendBullish( + int count = 10 // Number of Values Processed + ) + { + // + bool result = false; + + // + int calculatedVales = 0; + int verifier = 0; + + // + int availableBars = Bars( + mSymbol, + mPeriod); + + // + for (int i = 1; i < availableBars - 2; i++) + { + // + // Update Buffers ... + Calculate(i); + + // + // Check New Vale Happens ... + bool isNewVale = + // + valesBuffer[0] != valesBuffer[1] + // + ; + if (!isNewVale) + { + continue; + } + + // + // Check New Vale is Over last or Under Last ... + bool isOverLastVale = + // + valesBuffer[0] > valesBuffer[1] + // + ; + + // + // Set Verifier Value based On New Vale State ... + if (isOverLastVale) + { + verifier++; + } + else + { + verifier--; + } + + // + // Increase Number of Calculated Vales ... + calculatedVales++; + + // + // Break when Calculating required Vales ... + if (calculatedVales >= count) + { + break; + } + } + + // + result = verifier > 0; + + // + return result; + } + + // + bool IsPeaksTrendBearish( + int count = 10 // Number of Peaks Processed + ) + { + // + bool result = false; + + // + int calculatedPeaks = 0; + int verifier = 0; + + // + int availableBars = Bars( + mSymbol, + mPeriod); + + // + for (int i = 1; i < availableBars - 2; i++) + { + // + // Update Buffers ... + Calculate(i); + + // + // Check New Peak Happens ... + bool isNewPeak = + // + peaksBuffer[0] != peaksBuffer[1] + // + ; + if (!isNewPeak) + { + continue; + } + + // + // Check New Peak is Over last or Under Last ... + bool isOverLastPeak = + // + peaksBuffer[0] > peaksBuffer[1] + // + ; + + // + // Set Verifier Value based On New Peak State ... + if (isOverLastPeak) + { + verifier++; + } + else + { + verifier--; + } + + // + // Increase Number of Calculated Peaks ... + calculatedPeaks++; + + // + // Break when Calculating required Peaks ... + if (calculatedPeaks >= count) + { + break; + } + } + + // + result = verifier < 0; + + // + return result; + } + + // + bool IsPeaksTrendBullish( + int count = 10 // Number of Peaks Processed + ) + { + // + bool result = false; + + // + int calculatedPeaks = 0; + int verifier = 0; + + // + int availableBars = Bars( + mSymbol, + mPeriod); + + // + for (int i = 1; i < availableBars - 2; i++) + { + // + // Update Buffers ... + Calculate(i); + + // + // Check New Peak Happens ... + bool isNewPeak = + // + peaksBuffer[0] != peaksBuffer[1] + // + ; + if (!isNewPeak) + { + continue; + } + + // + // Check New Peak is Over last or Under Last ... + bool isOverLastPeak = + // + peaksBuffer[0] > peaksBuffer[1] + // + ; + + // + // Set Verifier Value based On New Peak State ... + if (isOverLastPeak) + { + verifier++; + } + else + { + verifier--; + } + + // + // Increase Number of Calculated Peaks ... + calculatedPeaks++; + + // + // Break when Calculating required Peaks ... + if (calculatedPeaks >= count) + { + break; + } + } + + // + result = verifier > 0; + + // + return result; + } + + // + // Protcted ... +protected: + // + // Private ... +private: + // + // Inputs ... + + // + // Candle Timer ... + color mCandleTimerColor; // Text Color + ENUM_BASE_CORNER mCandleTimerCorner; // Text Position + + // + // Chart Style ... + color mUpColor; // Up Color + color mDownColor; // Down Color + color mLineColor; // Line mode and Doji candlestick Color + color mBearishColor; // Bullish Color + color mBullishColor; // Bearish Color + color mVolumesColor; // Volumes Color + ENUM_CHART_MODE mChartMode; // Chart Mode + + // + // Market Cycles ... + + // + // Level 1 ... + ENUM_X_PERIOD_METHOD mL1Method; // How to Find Period + ENUM_TIMEFRAMES mL1Period; // Time Period + + // + // Level 2 ... + ENUM_X_PERIOD_METHOD mL2Method; // How to Find Period + ENUM_TIMEFRAMES mL2Period; // Time Period + + // + // Level 3 ... + ENUM_X_PERIOD_METHOD mL3Method; // How to Find Period + ENUM_TIMEFRAMES mL3Period; // Time Period + + // + // Level 4 ... + ENUM_X_PERIOD_METHOD mL4Method; // How to Find Period + ENUM_TIMEFRAMES mL4Period; // Time Period + + // + // Fibonacci ... + double mFiboLevel1; // Fibio 1st Level + double mFiboLevel2; // Fibio 2st Level + double mFiboLevel3; // Fibio 3rd Level + double mFiboLevel4; // Fibio 4th Level + double mFiboLevel5; // Fibio 5th Level + + // + // Boundary Detection Modes ... + ENUM_SERIESMODE mHHMode; // Highest High Calculation Method + ENUM_SERIESMODE mLLMode; // Lowest Low Calculation Method + + // + // Trend Detection + double mTrendMultiplier; // Multiplier + ENUM_APPLIED_PRICE mTrendPriceAppliedTo; // Applied To + + // + // Ribbon Detection ... + ENUM_X_MA_METHOD mRibbonMode; // How to Calculate + + // + // Hull Trend Detection ... + double mHullDivisor; // Divisor (Speed) + ENUM_APPLIED_PRICE mHullUpAppliedTo; // Up Zone Applied to + ENUM_APPLIED_PRICE mHullDownAppliedTo; // Down Zone Applied to + + // + // SSL Channel Detection ... + ENUM_X_MA_METHOD mSslcMode; // How to Calculate + ENUM_APPLIED_PRICE mSslcUpAppliedTo; // Up Applied To + ENUM_APPLIED_PRICE mSslcDownAppliedTo; // Down Applied To + + // + // Presentation ... + bool mShowCandleTimer; // Show Candle Time + bool mShowCandles; // Show Candles + bool mShowHKCandles; // Draw Hiken Ashi Candle + bool mShowPeaksAndVales; // Show Peaks and Vales + bool mShowTrends; // Show Trends + bool mSillTrends; // Fill Trends + bool mShowLevels; // Show Levels + bool mShowConsolidations; // Show Consolidations + bool mShowRibbons; // Show Ribbons + bool mShowHull; // Show Hull + bool mShowSSLChannel; // Show SSL Channel + bool mShowFibo1Levels; // Show Fibo 1st Level + bool mShowFibo2Levels; // Show Fibo 2nd Level + bool mShowFibo3Levels; // Show Fibo 3rd Level + bool mShowFibo4Levels; // Show Fibo 4th Level + bool mShowFibo5Levels; // Show Fibo 5th Level +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +//