From 87f09d72f66f5e750042cb56531e90e09cd51c80 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 1 Feb 2024 23:38:22 +0330 Subject: [PATCH] backup Projects ... add supports for wait until next candle to xAU5 ... fix XCTimer Initialization on EU and AU 5 ... --- BKP/Main/Experts/x-saherelm.xtest.ea.mq5 | 572 -- BKP/Projects.7z | Bin 0 -> 206198 bytes .../x-saherelm.class.lib.mq5 | 0 Classes/x-saherelm.nn.lib.mq5 | 258 + Classes/x-saherelm.provider.lib.mq5 | 4430 ++++++++++ Experts/x-saherelm.xau5.ea.mq5 | 395 + .../x-saherelm.xama.indicator.helper.lib.mq5 | 607 ++ ...x-saherelm.xchlh.oscillator.helper.lib.mq5 | 1032 +++ ...x-saherelm.xchma.oscillator.helper.lib.mq5 | 2229 +++++ .../x-saherelm.xfi.oscillator.helper.lib.mq5 | 358 + .../x-saherelm.xlh.indicator.helper.lib.mq5 | 668 ++ .../x-saherelm.xobd.indicator.helper.lib.mq5 | 249 + .../x-saherelm.xrsi.oscillator.helper.lib.mq5 | 433 + .../x-saherelm.xtd.oscillator.helper.lib.mq5 | 931 ++ .../x-saherelm.xtm.indicator.helper.lib.mq5 | 598 ++ .../x-saherelm.xts.oscillator.helper.lib.mq5 | 1179 +++ Indicators/x-saherelm.xama.indicator.mq5 | 353 + Indicators/x-saherelm.xchlh.oscillator.mq5 | 753 ++ Indicators/x-saherelm.xchma.oscillator.mq5 | 1153 +++ Indicators/x-saherelm.xctimer.indicator.mq5 | 206 + Indicators/x-saherelm.xfi.oscillator.mq5 | 317 + Indicators/x-saherelm.xlh.indicator.mq5 | 346 + Indicators/x-saherelm.xobd.indicator.mq5 | 390 + Indicators/x-saherelm.xrsi.oscillator.mq5 | 397 + Indicators/x-saherelm.xtd.oscillator.mq5 | 465 + Indicators/x-saherelm.xtm.indicator.mq5 | 349 + Indicators/x-saherelm.xts.oscillator.mq5 | 558 ++ .../x-saherelm.alert.lib.mq5 | 0 .../x-saherelm.common.lib.mq5 | 0 .../x-saherelm.draw.lib.mq5 | 0 .../x-saherelm.http.lib.mq5 | 0 .../x-saherelm.log.lib.mq5 | 0 .../x-saherelm.models.lib.mq5 | 0 Projects/XEU5/Experts/x-saherelm.xeu5.ea.mq5 | 8 +- ...-saherelm.xeu5.provider.indicators.lib.mq5 | 2 +- .../x-saherelm.xeu5.provider.lib.mq5 | 2 +- ...-saherelm.xau5.provider.indicators.lib.mq5 | 7744 +++++++++++++++++ .../x-saherelm.xau5.provider.inputs.lib.mq5 | 283 + Providers/x-saherelm.xau5.provider.lib.mq5 | 1373 +++ 39 files changed, 28060 insertions(+), 578 deletions(-) delete mode 100644 BKP/Main/Experts/x-saherelm.xtest.ea.mq5 create mode 100644 BKP/Projects.7z rename {BKP/Main/Classes => Classes}/x-saherelm.class.lib.mq5 (100%) create mode 100644 Classes/x-saherelm.nn.lib.mq5 create mode 100644 Classes/x-saherelm.provider.lib.mq5 create mode 100644 Experts/x-saherelm.xau5.ea.mq5 create mode 100644 Helpers/x-saherelm.xama.indicator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 create mode 100644 Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 create mode 100644 Indicators/x-saherelm.xama.indicator.mq5 create mode 100644 Indicators/x-saherelm.xchlh.oscillator.mq5 create mode 100644 Indicators/x-saherelm.xchma.oscillator.mq5 create mode 100644 Indicators/x-saherelm.xctimer.indicator.mq5 create mode 100644 Indicators/x-saherelm.xfi.oscillator.mq5 create mode 100644 Indicators/x-saherelm.xlh.indicator.mq5 create mode 100644 Indicators/x-saherelm.xobd.indicator.mq5 create mode 100644 Indicators/x-saherelm.xrsi.oscillator.mq5 create mode 100644 Indicators/x-saherelm.xtd.oscillator.mq5 create mode 100644 Indicators/x-saherelm.xtm.indicator.mq5 create mode 100644 Indicators/x-saherelm.xts.oscillator.mq5 rename {BKP/Main/Libraries => Libraries}/x-saherelm.alert.lib.mq5 (100%) rename {BKP/Main/Libraries => Libraries}/x-saherelm.common.lib.mq5 (100%) rename {BKP/Main/Libraries => Libraries}/x-saherelm.draw.lib.mq5 (100%) rename {BKP/Main/Libraries => Libraries}/x-saherelm.http.lib.mq5 (100%) rename {BKP/Main/Libraries => Libraries}/x-saherelm.log.lib.mq5 (100%) rename {BKP/Main/Libraries => Libraries}/x-saherelm.models.lib.mq5 (100%) create mode 100644 Providers/x-saherelm.xau5.provider.indicators.lib.mq5 create mode 100644 Providers/x-saherelm.xau5.provider.inputs.lib.mq5 create mode 100644 Providers/x-saherelm.xau5.provider.lib.mq5 diff --git a/BKP/Main/Experts/x-saherelm.xtest.ea.mq5 b/BKP/Main/Experts/x-saherelm.xtest.ea.mq5 deleted file mode 100644 index cf246c7c..00000000 --- a/BKP/Main/Experts/x-saherelm.xtest.ea.mq5 +++ /dev/null @@ -1,572 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Expert Advisor -// ---------------------------------------- -// Name: XAUUSD -// Description: this is an expert controller -// advisors which provides a mechanism for use them ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://saherelm.ir" -#property version "1.00" -#property description "SaherElm XTEST EA" -#property strict - -// -#include - -// -// START Inputs ... -// -// -input group "Commons"; - -// -input double staticVolume = 0.01; // Static Volume - -// -// FAST ... -input int fastLength = 9; // Fast Ma Length -input ENUM_MA_METHOD fastMethod = MODE_SMA; // fast Ma Method -input ENUM_APPLIED_PRICE fastAppliedTo = PRICE_CLOSE; // fast Ma Applied To - -// -// SLOW ... -input int slowLength = 18; // Slow Ma Length -input ENUM_MA_METHOD slowMethod = MODE_SMA; // slow Ma Method -input ENUM_APPLIED_PRICE slowAppliedTo = PRICE_CLOSE; // slow Ma Applied To -// -// END Inputs ... -// - -// -// START Including Providers ... -// - -// -// Logger Library ... -#include "../Libraries/x-saherelm.log.lib.mq5" - -// -// Common Library ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Alert Library ... -#include "../Libraries/x-saherelm.alert.lib.mq5" - -// -// Draw Library ... -#include "../Libraries/x-saherelm.draw.lib.mq5" - -// -// END Including Providers ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -ulong magicNumber = 169405612; - -// -int xMAFastHandler = INVALID_HANDLE; -double xMAFastBuffer[]; - -// -int xMASlowHandler = INVALID_HANDLE; -double xMASlowBuffer[]; - -// -int ticksCount; -int signalTicksCount; - -// -CPositionInfo mPositionInfo; -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Event Handlers ... -// - -// -// Initialization ... -int OnInit() -{ - // - logTag = "XTESTEA"; - drawPrefix = logTag; - alertPrefix = logTag; - - // - // Apply default Chart Style for EA ... - ApplyChartStyle(); - - // - // Reset Timings ... - ResetTiming(); - - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Define Handlers ... - if (!DefineHandlers()) - { - return INIT_FAILED; - } - - // - // Init Succeed ... - return INIT_SUCCEEDED; -} - -// -// DeInitialization ... -void OnDeinit(const int reason) -{ - // - // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function - // REASON_REMOVE 1 Program removed from a chart - // REASON_RECOMPILE 2 Program recompiled - // REASON_CHARTCHANGE 3 A symbol or a chart period is changed - // REASON_CHARTCLOSE 4 Chart closed - // REASON_PARAMETERS 5 Inputs changed by a user - // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings - // REASON_TEMPLATE 7 Another chart template applied - // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value - // REASON_CLOSE 9 Terminal closed - - // - // Here we can handle De Initialization Reasons ... - ReleaseHandlers(); -} - -// -// On Tick Handler ... -void OnTick() -{ - // - if (!IsNewCandle()) - { - ticksCount++; - } - - // - HandleTick(); -} - -// -// Handle Trade Events ... -void OnTrade() -{ -} - -// -// END Event Handlers ... -// - -// -// START Functions ... -// - -// -// Validate Input Args for Initialization ... -bool ValidateInputs() -{ - // - bool result = false; - - // - // Validate Args ... - - // - // Validate XTEST Provider Inputs ... - result = true; - if (!result) - { - return false; - } - - // - // Logging State ... - string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; - LogMessage(message); - - // - return result; -} - -bool DefineHandlers() -{ - // - bool result = true; - - // - // FAST ... - xMAFastHandler = iMA( - _Symbol, - _Period, - fastLength, - 0, - fastMethod, - fastAppliedTo); - - // - if (xMAFastHandler == INVALID_HANDLE) - { - // - result = false; - return result; - } - - // - // SLOW ... - xMASlowHandler = iMA( - _Symbol, - _Period, - slowLength, - 0, - fastMethod, - fastAppliedTo); - - // - if (xMASlowHandler == INVALID_HANDLE) - { - // - result = false; - return result; - } - - // - return result; -} - -void ReadBuffers(int bar_index) -{ - // - // Reading Fast Buffer ... - int readedFastItems = CopyBuffer( - xMAFastHandler, - 0, - bar_index, - 5, - xMAFastBuffer); - - // - // Reading Slow Buffer ... - int readedSlowItems = CopyBuffer( - xMASlowHandler, - 0, - bar_index, - 5, - xMASlowBuffer); -} - -void ReleaseHandlers() -{ - // - IndicatorRelease(xMAFastHandler); - IndicatorRelease(xMASlowHandler); -} - -void HandleTick() -{ - // - HandleControlState(); - - // - ReadBuffers(1); - - // - XOHCL cl0 = GetCandle(0); - XOHCL cl1 = GetCandle(1); - XOHCL cl2 = GetCandle(2); - - // - bool hasLong = - // - // Base Condition ... - ( - // - xMAFastBuffer[0] > xMASlowBuffer[0] - // - && - // - xMAFastBuffer[1] > xMASlowBuffer[1] - // - && - // - xMAFastBuffer[2] > xMASlowBuffer[2] - // - ) - // - && - // - cl1.close > cl2.close - // - && - // - cl0.close > cl1.close - // - ; - if (hasLong && signalTicksCount < 3) - { - // - signalTicksCount++; - - // - if (signalTicksCount == 3) - { - // - signalTicksCount = 0; - - // - double entry = GetEntry(X_SIGNAL_LONG); - double sl = GetLowestLow(3, 0); - double tp = entry + (150 * _Point); - double volume = staticVolume; - - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.tp = tp; - request.sl = sl; - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = ORDER_TYPE_BUY; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - string signalType = EnumToString(request.type); - - // - bool isExecuted = OrderSend( - request, - result); - if (!isExecuted) - { - // - string errMsg = GetErrorDescription(GetLastError()); - LogMessage("Signal " + signalType + " Execution Failed: " + errMsg); - } - else - { - LogMessage("Signal " + signalType + " Executed Successfully ..."); - } - } - } - - // - bool hasShort = - // - // Base Condition ... - ( - // - xMAFastBuffer[0] < xMASlowBuffer[0] - // - && - // - xMAFastBuffer[1] < xMASlowBuffer[1] - // - && - // - xMAFastBuffer[2] < xMASlowBuffer[2] - // - ) - // - && - // - cl1.close < cl2.close - // - && - // - cl0.close < cl1.close - // - ; - if (hasShort && signalTicksCount < 3) - { - // - signalTicksCount++; - - // - if (signalTicksCount == 3) - { - // - signalTicksCount = 0; - - // - double entry = GetEntry(X_SIGNAL_SHORT); - double sl = GetHighestHigh(3, 0); - double tp = entry - (150 * _Point); - double volume = staticVolume; - - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.tp = tp; - request.sl = sl; - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = ORDER_TYPE_SELL; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - string signalType = EnumToString(request.type); - - // - bool isExecuted = OrderSend( - request, - result); - if (!isExecuted) - { - // - string errMsg = GetErrorDescription(GetLastError()); - LogMessage("Signal " + signalType + " Execution Failed: " + errMsg); - } - else - { - LogMessage("Signal " + signalType + " Executed Successfully ..."); - } - } - } -} - -void HandleControlState() -{ - // - int count = PositionsTotal(); - if (count <= 0) - { - return; - } - - // - double totalProfit = 0; - - // - // Loop through Positions ... - for (int index = count - 1; index >= 0; index--) - { - // - int isSelected = mPositionInfo.SelectByIndex(index); - if (!isSelected) - { - continue; - } - - // - string symbol = mPositionInfo.Symbol(); - if (symbol != _Symbol) - { - continue; - } - - // - ulong pMagic = mPositionInfo.Magic(); - if (pMagic != magicNumber) - { - continue; - } - - // - double pProfit = mPositionInfo.Profit(); - totalProfit += pProfit; - } - - // - // Handle Hedging Positions ... - if (count > 1 && totalProfit > 0) - { - // - // Loop through Positions and Close All of Them ... - for (int index = count - 1; index >= 0; index--) - { - // - int isSelected = mPositionInfo.SelectByIndex(index); - if (!isSelected) - { - continue; - } - - // - string symbol = mPositionInfo.Symbol(); - if (symbol != _Symbol) - { - continue; - } - - // - ulong pMagic = mPositionInfo.Magic(); - if (pMagic != magicNumber) - { - continue; - } - - // - ulong ticket = mPositionInfo.Ticket(); - double volume = mPositionInfo.Volume(); - ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); - - // - double entry = GetEntry(pType == POSITION_TYPE_BUY ? X_SIGNAL_SHORT : X_SIGNAL_LONG); - - // - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = pType == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - - // - bool isExecuted = OrderSend( - request, - result); - } - } -} -// -// END Functions ... -// diff --git a/BKP/Projects.7z b/BKP/Projects.7z new file mode 100644 index 0000000000000000000000000000000000000000..fd63b493f87768948412837131d01a4753caa2fb GIT binary patch literal 206198 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Ðh$wQ2$5 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

B}(j&J7ih>d9!cz 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 literal 0 HcmV?d00001 diff --git a/BKP/Main/Classes/x-saherelm.class.lib.mq5 b/Classes/x-saherelm.class.lib.mq5 similarity index 100% rename from BKP/Main/Classes/x-saherelm.class.lib.mq5 rename to Classes/x-saherelm.class.lib.mq5 diff --git a/Classes/x-saherelm.nn.lib.mq5 b/Classes/x-saherelm.nn.lib.mq5 new file mode 100644 index 00000000..8fa40f53 --- /dev/null +++ b/Classes/x-saherelm.nn.lib.mq5 @@ -0,0 +1,258 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 NN Class Library +// ---------------------------------------- +// Name: XNNClass +// Description: provides all classes for implementing +// Neural Network ... +// +// +// 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 Global Definitions: Variables, Properties and etc ... +// +class XCNNBase +{ + // + // Public Definitions ... +public: + // + // Constructor ... + void XCNNBase( + int nodes = 10, // Number of Input Nodes + double starterWeight = 0.5, // start weight for each input + double coEfficient = 0.1, // COEfficient Multiplier + double upperRange = 1, // Upper Normal Range Value + double lowerRange = -1, // Lower Normal Range Value + double learningRates = 0.1 // Back Propagation Learning Rate + ) { + // + mNodes = nodes; + mUpperRange = upperRange; + mLowerRange = lowerRange; + mCoEfficient = coEfficient; + mLearningRates = learningRates; + mStarterWeight = starterWeight; + + // + ReConstructWeights(); + } + + // + // Deconstructor ... + void ~XCNNBase() {} + + // + // Protected Definitions ... + void NormalizeInputs(double &inputs[], double &result[]) + { + // + ArrayFree(result); + ArrayResize(result, 1); + + // + // Validate inputs ... + if (ArraySize(inputs) != mNodes) + { + return; + } + + // + // Prepare Result ... + ArrayResize(result, mNodes); + + // + // Calculating min and max range value ... + double minRangeValue = inputs[ArrayMinimum(inputs)]; + double maxRangeValue = inputs[ArrayMaximum(inputs)]; + + // + // Loop through Inputs nd Normalize them ... + for (int i = 0; i < mNodes; i++) + { + // + double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange; + result[i] = normalValue; + } + } + + // + // Hyperbolic Tangent Activation Function ... + double TanHActivationFunction(double weightedInputs) + { + // + double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs)); + return result; + } + + // + // Calculate Weighted Inputs ... + double CalculateWeightedInputs( + double &inputs[], + bool applyCOEfficient = true) + { + // + double result = 0; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) + { + // + result = -1; + return result; + } + + // + for (int i = 0; i < mNodes; i++) + { + result += inputs[i] * mWeights[i]; + } + + // + // Multiply if required ... + if (applyCOEfficient) + { + result *= mCoEfficient; + } + + // + return result; + } + + // + // Calculate Hidden Layers ... + virtual double CalculateHiddenLayer(double &inputs[]) + { + // + // this is Default Activation Function which used ... + // you can override this by writing your own ... + double totalWeightedInputs = CalculateWeightedInputs(inputs); + double result = TanHActivationFunction(totalWeightedInputs); + + // + return result; + } + + // + // Calculate Output Layers ... + double CalculateOutputLayer(double &inputs[]) + { + // + double result = -1; + + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return result; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return result; + } + + // + double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs); + + // + result = 1 * hiddenLayerResult; + + // + return result; + } + + // + // Basck Propaggation Learning ... + void BackPropagation( + double &inputs[], + double &outputs, + double targetOutput + ) { + // + // Validate Inputs ... + if (ArraySize(inputs) != mNodes) { + return; + } + + // + double normalizedInputs[]; + NormalizeInputs(inputs, normalizedInputs); + if (ArraySize(normalizedInputs) != mNodes) { + return; + } + + // + double error = targetOutput - outputs; + double derivative = 1 - MathPow(outputs, 2); + + // + for (int i = 0; i < mNodes; i++) { + // + double gradient = error * derivative * inputs[i]; + mWeights[i] = mLearningRates * gradient; + } + } + +protected: + // + // Private Definitions ... +private: + // + // Number of Input Nodes ... + int mNodes; + + // + // Specify Upper range of Normal Values ... + double mUpperRange; + + // + // Specify Lower range of Normal Values ... + double mLowerRange; + + // + // Starter Weight for each input node ... + double mStarterWeight; + + // + // double Input Node Weights ... + double mWeights[]; + + // + // CoEfficient is a multiplyer for weighted inputs ... + double mCoEfficient; + + // + // Back Propagation Learning Rates ... + double mLearningRates; + + // + // ReConstruct Weights ... + void ReConstructWeights() { + // + ArrayFree(mWeights); + ArrayResize(mWeights, mNodes); + + // + for (int i = 0; i< mNodes; i++) { + mWeights[i] = mStarterWeight; + } + } +} +// +// END Global Definitions: Variables, Properties and etc ... +// diff --git a/Classes/x-saherelm.provider.lib.mq5 b/Classes/x-saherelm.provider.lib.mq5 new file mode 100644 index 00000000..765544c7 --- /dev/null +++ b/Classes/x-saherelm.provider.lib.mq5 @@ -0,0 +1,4430 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XProvider +// Description: provides all indicators based provider classes for use ... +// +// +// 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 Define Enums ... +// + +// +enum ENUM_X_SIGNAL_PROVIDERS +{ + // + // XSP Expert Support Mechanism ... + XSP, + // + // XTD ... + XTD, + // + // XTAM ... + XTAM, + // + // XSI ... + XSI, + // + // XTSFI ... + XTSFI, + // + // XOBDLH ... + XOBDLH, + // + // XCHMACC ... + XCHMACC, + // + // XCHMACMN ... + XCHMAMN, + // + // XCHMACMX ... + XCHMAMX, +}; + +// +// Represent Market Conditions ... +struct XMarketConditions +{ + // + // XTM ... + bool isXTMPeak; + bool isXTMVale; + bool isXTMBullish; + bool isXTMBearish; + bool isXTMNeutural; + bool isXTMEndBullish; + bool isXTMEndBearish; + bool isXTMStartBullish; + bool isXTMStartBearish; + bool isXTMEndBullishByNeutural; + bool isXTMEndBearishByNeutural; + bool isXTMStartBullishAfterNeutural; + bool isXTMStartBearishAfterNeutural; + + // + // XAMA ... + bool isXAMAPeak; + bool isXAMAVale; + bool isXAMABullish; + bool isXAMABearish; + bool isXAMANeutural; + bool isXAMAEndBullish; + bool isXAMAEndBearish; + bool isXAMAStartBullish; + bool isXAMAStartBearish; + bool isXAMAEndBullishByNeutural; + bool isXAMAEndBearishByNeutural; + bool isXAMAStartBullishAfterNeutural; + bool isXAMAStartBearishAfterNeutural; + + // + // XLH ... + bool isXLHHHIncreased; + bool isXLHHHDecreased; + bool isXLHLLIncreased; + bool isXLHLLDecreased; + bool isXLHLowAttachedLL; + bool isXLHHighAttachedHH; + bool isXLHHHSameInLength; + bool isXLHLLSameInLength; + bool isXLHPriceOverSignal; + bool isXLHPriceUnderSignal; + bool isXLHPriceInSignalRange; + bool isXLHPriceCrossedOverSignal; + bool isXLHPriceCrossedUnderSignal; + + // + // XTD ... + bool isXTDSignalPeak; + bool isXTDSignalVale; + bool isXTDBullishPeak; + bool isXTDBullishVale; + bool isXTDBearishPeak; + bool isXTDBearishVale; + bool isXTDBullOverBear; + bool isXTDBullUnderBear; + bool isXTDSignalOverBear; + bool isXTDSignalUnderBear; + bool isXTDBullCrossedOverBear; + bool isXTDBullCrossedUnderBear; + bool isXTDSignalCrossedOverBear; + bool isXTDSignalCrossedUnderBear; + + // + // XFI ... + bool isXFIPeak; + bool isXFIVale; + bool isXFICrossedOverZero; + bool isXFIOverZero; + bool isXFICrossedUnderZero; + bool isXFIUnderZero; + + // + // XTS ... + bool isXTSAllSame; + bool isXTSCurrentMin; + bool isXTSCurrentMax; + bool isXTSCurrentOverFarest; + bool isXTSCurrentOverNearest; + bool isXTSCurrentOverMediest; + bool isXTSCurrentUnderFarest; + bool isXTSCurrentUnderNearest; + bool isXTSCurrentUnderMediest; + bool isXTSCurrentCrossedOverFarest; + bool isXTSCurrentCrossedOverNearest; + bool isXTSCurrentCrossedOverMediest; + bool isXTSCurrentCrossedUnderFarest; + bool isXTSCurrentCrossedUnderNearest; + bool isXTSCurrentCrossedUnderMediest; + + // + // XRSI ... + bool isXRSIPeak; + bool isXRSIVale; + bool isXRSICrossedOverLongExit; + bool isXRSICrossedOverLongEntry; + bool isXRSICrossedUnderShortExit; + bool isXRSICrossedUnderShortEntry; + + // + // XOBD ... + bool isXOBDSwingLow; + bool isXOBDSwingHigh; + + // + // XCHLH ... + // + bool isXCHLHSameHHs; + bool isXCHLHSameLLs; + // + bool isXCHLHSCMCHHSame; + bool isXCHLHSCMCLLSame; + // + bool isXCHLHSCLCHHSame; + bool isXCHLHSCLCLLSame; + // + bool isXCHLHMCLCHHSame; + bool isXCHLHMCLCLLSame; + // + bool isXCHLHMCOnTopOfLC; + bool isXCHLHMCInBottomOfLC; + + // + // XCHMA ... + // + bool isXCHMASCOverMax; + bool isXCHMASCOverMin; + bool isXCHMASCUnderMax; + bool isXCHMASCUnderMin; + // + bool isXCHMASCCrossedOverMax; + bool isXCHMASCCrossedUnderMax; + bool isXCHMASCCrossedOverMin; + bool isXCHMASCCrossedUnderMin; + // + bool isXCHMASCPeak; + bool isXCHMASCVale; + bool isXCHMASCTrendsUp; + bool isXCHMASCTrendsDown; + bool isXCHMASCFastOverSlow; + bool isXCHMASCFastUnderSlow; + bool isXCHMASCFastCrossedOverSlow; + bool isXCHMASCFastCrossedUnderSlow; + // + bool isXCHMAMCPeak; + bool isXCHMAMCVale; + bool isXCHMAMCTrendsUp; + bool isXCHMAMCTrendsDown; + bool isXCHMAMCFastOverSlow; + bool isXCHMAMCFastUnderSlow; + bool isXCHMAMCFastCrossedOverSlow; + bool isXCHMAMCFastCrossedUnderSlow; + // + bool isXCHMALCPeak; + bool isXCHMALCVale; + bool isXCHMALCTrendsUp; + bool isXCHMALCTrendsDown; + bool isXCHMALCFastOverSlow; + bool isXCHMALCFastUnderSlow; + bool isXCHMALCFastCrossedOverSlow; + bool isXCHMALCFastCrossedUnderSlow; +}; + +// +// END Define Enums ... +// + +// +// START Includes Requirements ... +// + +// +// Includes Classes ... +#include "x-saherelm.class.lib.mq5" + +// +// Includes all Indicator's Helpers ... +#include "../Helpers/x-saherelm.xlh.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xtm.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xama.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xobd.indicator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xts.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5" +#include "../Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5" + +// +// END Includes Requirements ... +// + +// +class XCPriver : public XCBase +{ + // + // Public ... +public: + // + // Constructor ... + XCPriver( + // + // Common Requirements ... + string xSymbol, // Which Symbol is Used + ENUM_TIMEFRAMES xPeriod, // Which Period is Used + // + // Signallers Requirements ... + // + // XTD ... + bool xTDEnableSignaller, // Enable Signaller + bool xTDAllowLongSignals, // Allow Long Signals + bool xTDAllowShortSignals, // Allow Short Signals + // + // XTAM ... + bool xTAMEnableSignaller, // Enable Signaller + bool xTAMAllowLongSignals, // Allow Long Signals + bool xTAMAllowShortSignals, // Allow Short Signals + // + // XSI ... + bool xSIEnableSignaller, // Enable Signaller + bool xSIAllowLongSignals, // Allow Long Signals + bool xSIAllowShortSignals, // Allow Short Signals + // + // XTSFI ... + bool XTSFIEnableSignaller, // Enable Signaller + bool XTSFIAllowLongSignals, // Allow Long Signals + bool XTSFIAllowShortSignals, // Allow Short Signals + // + // XOBDLH ... + bool xOBDLHEnableSignaller, // Enable Signaller + bool xOBDLHAllowLongSignals, // Allow Long Signals + bool xOBDLHAllowShortSignals, // Allow Short Signals + // + // XCHMACC ... + bool xCHMACCEnableSignaller, // Enable Signaller + bool xCHMACCAllowLongSignals, // Allow Long Signals + bool xCHMACCAllowShortSignals, // Allow Short Signals + // + // XCHMAMX ... + bool xCHMACMXEnableSignaller, // Enable Signaller + bool xCHMACMXAllowLongSignals, // Allow Long Signals + bool xCHMACMXAllowShortSignals, // Allow Short Signals + // + // XCHMAMN ... + bool xCHMACMNEnableSignaller, // Enable Signaller + bool xCHMACMNAllowLongSignals, // Allow Long Signals + bool xCHMACMNAllowShortSignals // Allow Short Signals + // + ) + { + // + // XTD ... + mXTDEnableSignaller = xTDEnableSignaller; + mXTDAllowLongSignals = xTDAllowLongSignals; + mXTDAllowShortSignals = xTDAllowShortSignals; + + // + // XTAM ... + mXTAMEnableSignaller = xTAMEnableSignaller; + mXTAMAllowLongSignals = xTAMAllowLongSignals; + mXTAMAllowShortSignals = xTAMAllowShortSignals; + + // + // XSI ... + mXSIEnableSignaller = xSIEnableSignaller; + mXSIAllowLongSignals = xSIAllowLongSignals; + mXSIAllowShortSignals = xSIAllowShortSignals; + + // + // XTSFI ... + mXTSFIEnableSignaller = XTSFIEnableSignaller; + mXTSFIAllowLongSignals = XTSFIAllowLongSignals; + mXTSFIAllowShortSignals = XTSFIAllowShortSignals; + + // + // XOBDLH ... + mXOBDLHEnableSignaller = xOBDLHEnableSignaller; + mXOBDLHAllowLongSignals = xOBDLHAllowLongSignals; + mXOBDLHAllowShortSignals = xOBDLHAllowShortSignals; + + // + // XCHMACC ... + mXCHMACCEnableSignaller = xCHMACCEnableSignaller; + mXCHMACCAllowLongSignals = xCHMACCAllowLongSignals; + mXCHMACCAllowShortSignals = xCHMACCAllowShortSignals; + + // + // XCHMAMX ... + mXCHMAMXEnableSignaller = xCHMACMXEnableSignaller; + mXCHMAMXAllowLongSignals = xCHMACMXAllowLongSignals; + mXCHMAMXAllowShortSignals = xCHMACMXAllowShortSignals; + + // + // XCHMAMN ... + mXCHMAMNEnableSignaller = xCHMACMNEnableSignaller; + mXCHMAMNAllowLongSignals = xCHMACMNAllowLongSignals; + mXCHMAMNAllowShortSignals = xCHMACMNAllowShortSignals; + } + + // + // Deconstructor ... + ~XCPriver() {} + + // + // START Common Functions ... + // + + // + // Read All Globally Required Conditions ... + void ReadConditions() + { + // + ClearConditions(); + + // + mXConditions = GenerateMarketConditions(1); + } + + // + // Cleanup Conditions ... + void ClearConditions() + { + // + XMarketConditions mConditions = {}; + + // + mXConditions = mConditions; + } + + // + // Generate Merket Conditions for Specified Bar Index ... + XMarketConditions GenerateMarketConditions( + int bar_index = 1 // Specified Bar Index ... + ) + { + // + XMarketConditions mConditions = {}; + + // + // XTM ... + mConditions.isXTMPeak = XTMIsPeak(bar_index); + mConditions.isXTMVale = XTMIsVale(bar_index); + mConditions.isXTMBullish = XTMIsBullish(bar_index); + mConditions.isXTMBearish = XTMIsBearish(bar_index); + mConditions.isXTMNeutural = XTMIsNeutural(bar_index); + mConditions.isXTMEndBullish = XTMIsEndBullish(bar_index); + mConditions.isXTMEndBearish = XTMIsEndBearish(bar_index); + mConditions.isXTMStartBullish = XTMIsStartBullish(bar_index); + mConditions.isXTMStartBearish = XTMIsStartBearish(bar_index); + mConditions.isXTMEndBullishByNeutural = XTMIsEndBullishByNeutural(bar_index); + mConditions.isXTMEndBearishByNeutural = XTMIsEndBearishByNeutural(bar_index); + mConditions.isXTMStartBullishAfterNeutural = XTMIsStartBullishAfterNeutural(bar_index); + mConditions.isXTMStartBearishAfterNeutural = XTMIsStartBearishAfterNeutural(bar_index); + + // + // XAMA ... + mConditions.isXAMAPeak = XAMAIsPeak(bar_index); + mConditions.isXAMAVale = XAMAIsVale(bar_index); + mConditions.isXAMABullish = XAMAIsBullish(bar_index); + mConditions.isXAMABearish = XAMAIsBearish(bar_index); + mConditions.isXAMANeutural = XAMAIsNeutural(bar_index); + mConditions.isXAMAEndBullish = XAMAIsEndBullish(bar_index); + mConditions.isXAMAEndBearish = XAMAIsEndBearish(bar_index); + mConditions.isXAMAStartBullish = XAMAIsStartBullish(bar_index); + mConditions.isXAMAStartBearish = XAMAIsStartBearish(bar_index); + mConditions.isXAMAEndBullishByNeutural = XAMAIsEndBullishByNeutural(bar_index); + mConditions.isXAMAEndBearishByNeutural = XAMAIsEndBearishByNeutural(bar_index); + mConditions.isXAMAStartBullishAfterNeutural = XAMAIsStartBullishAfterNeutural(bar_index); + mConditions.isXAMAStartBearishAfterNeutural = XAMAIsStartBearishAfterNeutural(bar_index); + + // + // XLH ... + mConditions.isXLHHHIncreased = XLHIsHHIncreased(bar_index); + mConditions.isXLHHHDecreased = XLHIsHHDecreased(bar_index); + mConditions.isXLHLLIncreased = XLHIsLLIncreased(bar_index); + mConditions.isXLHLLDecreased = XLHIsLLDecreased(bar_index); + mConditions.isXLHLowAttachedLL = XLHIsLowAttachedLL(bar_index); + mConditions.isXLHHighAttachedHH = XLHIsHighAttachedHH(bar_index); + mConditions.isXLHHHSameInLength = XLHIsHHSameInLength(bar_index); + mConditions.isXLHLLSameInLength = XLHIsLLSameInLength(bar_index); + mConditions.isXLHPriceOverSignal = XLHIsPriceOverSignal(bar_index); + mConditions.isXLHPriceUnderSignal = XLHIsPriceUnderSignal(bar_index); + mConditions.isXLHPriceInSignalRange = XLHIsPriceInSignalRange(bar_index); + mConditions.isXLHPriceCrossedOverSignal = XLHIsPriceCrossedOverSignal(bar_index); + mConditions.isXLHPriceCrossedUnderSignal = XLHIsPriceCrossedUnderSignal(bar_index); + + // + // XTD ... + mConditions.isXTDSignalPeak = XTDIsSignalPeak(bar_index); + mConditions.isXTDSignalVale = XTDIsSignalVale(bar_index); + mConditions.isXTDBullishPeak = XTDIsBullishPeak(bar_index); + mConditions.isXTDBullishVale = XTDIsBullishVale(bar_index); + mConditions.isXTDBearishPeak = XTDIsBearishPeak(bar_index); + mConditions.isXTDBearishVale = XTDIsBearishVale(bar_index); + mConditions.isXTDBullOverBear = XTDIsBullOverBear(bar_index); + mConditions.isXTDBullUnderBear = XTDIsBullUnderBear(bar_index); + mConditions.isXTDSignalOverBear = XTDIsSignalOverBear(bar_index); + mConditions.isXTDSignalUnderBear = XTDIsSignalUnderBear(bar_index); + mConditions.isXTDBullCrossedOverBear = XTDIsBullCrossedOverBear(bar_index); + mConditions.isXTDBullCrossedUnderBear = XTDIsBullCrossedUnderBear(bar_index); + mConditions.isXTDSignalCrossedOverBear = XTDIsSignalCrossedOverBear(bar_index); + mConditions.isXTDSignalCrossedUnderBear = XTDIsSignalCrossedUnderBear(bar_index); + + // + // XFI ... + mConditions.isXFIPeak = XFIIsPeak(bar_index); + mConditions.isXFIVale = XFIIsVale(bar_index); + mConditions.isXFIOverZero = XFIIsOverZero(bar_index); + mConditions.isXFIUnderZero = XFIIsUnderZero(bar_index); + mConditions.isXFICrossedOverZero = XFIIsCrossedOverZero(bar_index); + mConditions.isXFICrossedUnderZero = XFIIsCrossedUnderZero(bar_index); + + // + // XTS ... + mConditions.isXTSAllSame = XTSIsAllSame(bar_index); + mConditions.isXTSCurrentMin = XTSIsCurrentMin(bar_index); + mConditions.isXTSCurrentMax = XTSIsCurrentMax(bar_index); + mConditions.isXTSCurrentOverFarest = XTSIsCurrentOverFarest(bar_index); + mConditions.isXTSCurrentOverNearest = XTSIsCurrentOverNearest(bar_index); + mConditions.isXTSCurrentOverMediest = XTSIsCurrentOverMediest(bar_index); + mConditions.isXTSCurrentUnderFarest = XTSIsCurrentUnderFarest(bar_index); + mConditions.isXTSCurrentUnderNearest = XTSIsCurrentUnderNearest(bar_index); + mConditions.isXTSCurrentUnderMediest = XTSIsCurrentUnderMediest(bar_index); + mConditions.isXTSCurrentCrossedOverFarest = XTSIsCurrentCrossedOverFarest(bar_index); + mConditions.isXTSCurrentCrossedOverNearest = XTSIsCurrentCrossedOverNearest(bar_index); + mConditions.isXTSCurrentCrossedOverMediest = XTSIsCurrentCrossedOverMediest(bar_index); + mConditions.isXTSCurrentCrossedUnderFarest = XTSIsCurrentCrossedUnderFarest(bar_index); + mConditions.isXTSCurrentCrossedUnderNearest = XTSIsCurrentCrossedUnderNearest(bar_index); + mConditions.isXTSCurrentCrossedUnderMediest = XTSIsCurrentCrossedUnderMediest(bar_index); + + // + // XRSI ... + mConditions.isXRSIPeak = XRSIIsPeak(bar_index); + mConditions.isXRSIVale = XRSIIsVale(bar_index); + mConditions.isXRSICrossedOverLongExit = XRSIIsCrossedOverLongExit(bar_index); + mConditions.isXRSICrossedOverLongEntry = XRSIIsCrossedOverLongEntry(bar_index); + mConditions.isXRSICrossedUnderShortExit = XRSIIsCrossedUnderShortExit(bar_index); + mConditions.isXRSICrossedUnderShortEntry = XRSIIsCrossedUnderShortEntry(bar_index); + + // + // XOBD ... + mConditions.isXOBDSwingLow = XOBDIsSwingLow(bar_index); + mConditions.isXOBDSwingHigh = XOBDIsSwingHigh(bar_index); + + // + // XCHLH ... + // + mConditions.isXCHLHSameHHs = XCHLHIsSameHHs(bar_index); + mConditions.isXCHLHSameLLs = XCHLHIsSameLLs(bar_index); + // + mConditions.isXCHLHSCMCHHSame = XCHLHIsMCSCHasSameHH(bar_index); + mConditions.isXCHLHSCMCLLSame = XCHLHIsMCSCHasSameLL(bar_index); + // + mConditions.isXCHLHSCLCHHSame = XCHLHIsLCSCHasSameHH(bar_index); + mConditions.isXCHLHSCLCLLSame = XCHLHIsLCSCHasSameLL(bar_index); + // + mConditions.isXCHLHMCLCHHSame = XCHLHIsLCMCHasSameHH(bar_index); + mConditions.isXCHLHMCLCLLSame = XCHLHIsLCMCHasSameLL(bar_index); + // + mConditions.isXCHLHMCOnTopOfLC = XCHLHIsMCOnTopOfLC(bar_index); + mConditions.isXCHLHMCInBottomOfLC = XCHLHIsMCInBottomOfLC(bar_index); + + // + // XCHMA ... + // + mConditions.isXCHMASCOverMax = XCHMAIsSCOverMax(bar_index); + mConditions.isXCHMASCOverMin = XCHMAIsSCOverMin(bar_index); + mConditions.isXCHMASCUnderMax = XCHMAIsSCUnderMax(bar_index); + mConditions.isXCHMASCUnderMin = XCHMAIsSCUnderMin(bar_index); + // + mConditions.isXCHMASCCrossedOverMax = XCHMAIsSCCrossedOverMax(bar_index); + mConditions.isXCHMASCCrossedUnderMax = XCHMAIsSCCrossedUnderMax(bar_index); + mConditions.isXCHMASCCrossedOverMin = XCHMAIsSCCrossedOverMin(bar_index); + mConditions.isXCHMASCCrossedUnderMin = XCHMAIsSCCrossedUnderMin(bar_index); + // + mConditions.isXCHMASCPeak = XCHMAIsSCPeak(bar_index); + mConditions.isXCHMASCVale = XCHMAIsSCVale(bar_index); + mConditions.isXCHMASCTrendsUp = XCHMAIsSCTrendsUp(bar_index); + mConditions.isXCHMASCTrendsDown = XCHMAIsSCTrendsDown(bar_index); + mConditions.isXCHMASCFastOverSlow = XCHMAIsSCFastOverSlow(bar_index); + mConditions.isXCHMASCFastUnderSlow = XCHMAIsSCFastUnderSlow(bar_index); + mConditions.isXCHMASCFastCrossedOverSlow = XCHMAIsSCFastCrossedOverSlow(bar_index); + mConditions.isXCHMASCFastCrossedUnderSlow = XCHMAIsSCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMAMCPeak = XCHMAIsMCPeak(bar_index); + mConditions.isXCHMAMCVale = XCHMAIsMCVale(bar_index); + mConditions.isXCHMAMCTrendsUp = XCHMAIsMCTrendsUp(bar_index); + mConditions.isXCHMAMCTrendsDown = XCHMAIsMCTrendsDown(bar_index); + mConditions.isXCHMAMCFastOverSlow = XCHMAIsMCFastOverSlow(bar_index); + mConditions.isXCHMAMCFastUnderSlow = XCHMAIsMCFastUnderSlow(bar_index); + mConditions.isXCHMAMCFastCrossedOverSlow = XCHMAIsMCFastCrossedOverSlow(bar_index); + mConditions.isXCHMAMCFastCrossedUnderSlow = XCHMAIsMCFastCrossedUnderSlow(bar_index); + // + mConditions.isXCHMALCPeak = XCHMAIsLCPeak(bar_index); + mConditions.isXCHMALCVale = XCHMAIsLCVale(bar_index); + mConditions.isXCHMALCTrendsUp = XCHMAIsLCTrendsUp(bar_index); + mConditions.isXCHMALCTrendsDown = XCHMAIsLCTrendsDown(bar_index); + mConditions.isXCHMALCFastOverSlow = XCHMAIsLCFastOverSlow(bar_index); + mConditions.isXCHMALCFastUnderSlow = XCHMAIsLCFastUnderSlow(bar_index); + mConditions.isXCHMALCFastCrossedOverSlow = XCHMAIsLCFastCrossedOverSlow(bar_index); + mConditions.isXCHMALCFastCrossedUnderSlow = XCHMAIsLCFastCrossedUnderSlow(bar_index); + + // + return mConditions; + } + + // + // Access Last Readed Market Conditions ... + XMarketConditions GetLastMarketCondition() + { + // + XMarketConditions result = {}; + + // + result = mXConditions; + + // + return result; + } + + // + // Check Market Conditions is Ready for Long Signals or not ... + bool IsReadyForLong( + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAPeaks = true, // Force Check XCHMA Peaks State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mXConditions.isXCHMASCOverMin || + mXConditions.isXCHMASCCrossedOverMin) && + (mXConditions.isXCHMASCUnderMin || + mXConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mXConditions.isXCHMASCOverMax || + mXConditions.isXCHMASCCrossedOverMax) && + (mXConditions.isXCHMASCUnderMax || + mXConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastOverSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mXConditions.isXCHMAMCFastOverSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastOverSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAPeaks && result) + { + // + result = + // + // XCHMA Check Peaks ... + !( + // + // All Cycles Peak ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMAMCPeak && + mXConditions.isXCHMALCPeak) + // + || + // + ( + // + // SC MC ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMAMCPeak) + // + || + // + // SC LC ... + (mXConditions.isXCHMASCPeak && + mXConditions.isXCHMALCPeak) + // + || + // + // MC LC ... + (mXConditions.isXCHMAMCPeak && + mXConditions.isXCHMALCPeak) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown) + // + || + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + (mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mXConditions.isXOBDSwingLow + // + ; + } + + // + if (checkXTS && result) + { + result = + // + // XTS Check ... + !( + // + mXConditions.isXTSCurrentMin && + // + ( + // + // All Under ... + ( + (mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + // Pairs ... + ( + // + ((mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest)) + // + || + // + ((mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + || + // + ((mXConditions.isXTSCurrentUnderMediest || + mXConditions.isXTSCurrentCrossedUnderMediest) && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Check Market Conditions is Ready for Short Signals or not ... + bool IsReadyForShort( + bool checkXCHMAMin = true, // Force Check XCHMA Min State + bool checkXCHMAMax = true, // Force Check XCHMA Max State + bool checkXCHMACycles = true, // Force Check XCHMA Cycles State + bool checkXCHMAVales = true, // Force Check XCHMA Vales State + bool checkXCHMATrendPowers = true, // Force Check XCHMA Trend Powers + bool checkXOBD = true, // Force Check XOBD State + bool checkXTS = true // Force Check XTS State + ) + { + // + bool result = true; + + // + if (checkXCHMAMin) + { + // + result = + // + // XCHMA MIN ... + !( + // + (mXConditions.isXCHMASCOverMin || + mXConditions.isXCHMASCCrossedOverMin) && + (mXConditions.isXCHMASCUnderMin || + mXConditions.isXCHMASCCrossedUnderMin) + // + ); + } + + // + if (checkXCHMAMax && result) + { + // + result = + // + // XCHMA MAX ... + !( + // + (mXConditions.isXCHMASCOverMax || + mXConditions.isXCHMASCCrossedOverMax) && + (mXConditions.isXCHMASCUnderMax || + mXConditions.isXCHMASCCrossedUnderMax) + // + ) + // + ; + } + + // + if (checkXCHMACycles && result) + { + // + result = + // + // Check XCHMA Trend Bullish ... + ( + // + // All Cycles Bullish ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedUnderSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // Two Cycle Fully Bullish ... + ( + // + // SC and MC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedOverSlow) + // + && + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + ) + // + || + // + // SC and LC ... + ( + // + // SC ... + (mXConditions.isXCHMASCFastUnderSlow || + mXConditions.isXCHMASCFastCrossedUnderSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedUnderSlow) + // + ) + // + || + // + // MC and LC ... + ( + // + // MC ... + (mXConditions.isXCHMAMCFastUnderSlow || + mXConditions.isXCHMAMCFastCrossedOverSlow) + // + && + // + // LC ... + (mXConditions.isXCHMALCFastUnderSlow || + mXConditions.isXCHMALCFastCrossedOverSlow) + // + ) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMAVales && result) + { + // + result = + // + // XCHMA Check Vales ... + !( + // + // All Cycles Vale ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMAMCVale && + mXConditions.isXCHMALCVale) + // + || + // + ( + // + // SC MC ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMAMCVale) + // + || + // + // SC LC ... + (mXConditions.isXCHMASCVale && + mXConditions.isXCHMALCVale) + // + || + // + // MC LC ... + (mXConditions.isXCHMAMCVale && + mXConditions.isXCHMALCVale) + // + ) + // + ) + // + ; + } + + // + if (checkXCHMATrendPowers && result) + { + // + result = + // + // XCHMA Check Trends Power ... + !( + // + // All Trends Down ... + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + // Twisted pairs ... + ( + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMAMCTrendsDown) + // + || + // + (mXConditions.isXCHMASCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + || + // + (mXConditions.isXCHMAMCTrendsDown && + mXConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ; + } + + // + if (checkXOBD && result) + { + // + result = + // + // XOBD Check Swings ... + !mXConditions.isXOBDSwingHigh + // + ; + } + + // + if (checkXTS && result) + { + // + result = + // + // XTS Check ... + !( + // + mXConditions.isXTSCurrentMax && + // + ( + // + // All Over ... + ( + (mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + // Pairs ... + ( + // + ((mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest)) + // + || + // + ((mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + || + // + ((mXConditions.isXTSCurrentOverMediest || + mXConditions.isXTSCurrentCrossedOverMediest) && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest)) + // + ) + // + ) + // + ) + // + ; + } + + // + return result; + } + + // + // Converts Market Conditions to Specific String Representation ... + string GenerateConditionsString( + XMarketConditions &condition, // Specify Conditiond + string separator = "\n", // Specify Separator + bool ignoreFalses = true // Ignore False Conditions + ) + { + // + XMarketConditions mConditions = {}; + + // + mConditions = condition; + + // + string result = "\n"; + + // + // XOBD ... + result += + "| XOBD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingLow)) + { + result += "isXOBDSwingLow: " + (string)mConditions.isXOBDSwingLow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXOBDSwingHigh)) + { + result += "isXOBDSwingHigh: " + (string)mConditions.isXOBDSwingHigh + separator; + } + + // + // Separator ... + result += separator; + + // + // XTM ... + result += + "| XTM |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMPeak)) + { + result += "isXTMPeak: " + (string)mConditions.isXTMPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMVale)) + { + result += "isXTMVale: " + (string)mConditions.isXTMVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullish)) + { + result += "isXTMStartBullish: " + (string)mConditions.isXTMStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBullishAfterNeutural)) + { + result += "isXTMStartBullishAfterNeutural: " + (string)mConditions.isXTMStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBullish)) + { + result += "isXTMBullish: " + (string)mConditions.isXTMBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullish)) + { + result += "isXTMEndBullish: " + (string)mConditions.isXTMEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBullishByNeutural)) + { + result += "isXTMEndBullishByNeutural: " + (string)mConditions.isXTMEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearish)) + { + result += "isXTMStartBearish: " + (string)mConditions.isXTMStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMStartBearishAfterNeutural)) + { + result += "isXTMStartBearishAfterNeutural: " + (string)mConditions.isXTMStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMBearish)) + { + result += "isXTMBearish: " + (string)mConditions.isXTMBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearish)) + { + result += "isXTMEndBearish: " + (string)mConditions.isXTMEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMEndBearishByNeutural)) + { + result += "isXTMEndBearishByNeutural: " + (string)mConditions.isXTMEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTMNeutural)) + { + result += "isXTMNeutural: " + (string)mConditions.isXTMNeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XAMA ... + result += + "| XAMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAPeak)) + { + result += "isXAMAPeak: " + (string)mConditions.isXAMAPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAVale)) + { + result += "isXAMAVale: " + (string)mConditions.isXAMAVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullish)) + { + result += "isXAMAStartBullish: " + (string)mConditions.isXAMAStartBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBullishAfterNeutural)) + { + result += "isXAMAStartBullishAfterNeutural: " + (string)mConditions.isXAMAStartBullishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABullish)) + { + result += "isXAMABullish: " + (string)mConditions.isXAMABullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullish)) + { + result += "isXAMAEndBullish: " + (string)mConditions.isXAMAEndBullish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBullishByNeutural)) + { + result += "isXAMAEndBullishByNeutural: " + (string)mConditions.isXAMAEndBullishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearish)) + { + result += "isXAMAStartBearish: " + (string)mConditions.isXAMAStartBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAStartBearishAfterNeutural)) + { + result += "isXAMAStartBearishAfterNeutural: " + (string)mConditions.isXAMAStartBearishAfterNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMABearish)) + { + result += "isXAMABearish: " + (string)mConditions.isXAMABearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearish)) + { + result += "isXAMAEndBearish: " + (string)mConditions.isXAMAEndBearish + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMAEndBearishByNeutural)) + { + result += "isXAMAEndBearishByNeutural: " + (string)mConditions.isXAMAEndBearishByNeutural + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXAMANeutural)) + { + result += "isXAMANeutural: " + (string)mConditions.isXAMANeutural + separator; + } + + // + // Separator ... + result += separator; + + // + // XTD ... + result += + "| XTD |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalPeak)) + { + result += "isXTDSignalPeak: " + (string)mConditions.isXTDSignalPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalVale)) + { + result += "isXTDSignalVale: " + (string)mConditions.isXTDSignalVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishPeak)) + { + result += "isXTDBullishPeak: " + (string)mConditions.isXTDBullishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullishVale)) + { + result += "isXTDBullishVale: " + (string)mConditions.isXTDBullishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishPeak)) + { + result += "isXTDBearishPeak: " + (string)mConditions.isXTDBearishPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBearishVale)) + { + result += "isXTDBearishVale: " + (string)mConditions.isXTDBearishVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullOverBear)) + { + result += "isXTDBullOverBear: " + (string)mConditions.isXTDBullOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullUnderBear)) + { + result += "isXTDBullUnderBear: " + (string)mConditions.isXTDBullUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalOverBear)) + { + result += "isXTDSignalOverBear: " + (string)mConditions.isXTDSignalOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalUnderBear)) + { + result += "isXTDSignalUnderBear: " + (string)mConditions.isXTDSignalUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedOverBear)) + { + result += "isXTDBullCrossedOverBear: " + (string)mConditions.isXTDBullCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDBullCrossedUnderBear)) + { + result += "isXTDBullCrossedUnderBear: " + (string)mConditions.isXTDBullCrossedUnderBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedOverBear)) + { + result += "isXTDSignalCrossedOverBear: " + (string)mConditions.isXTDSignalCrossedOverBear + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTDSignalCrossedUnderBear)) + { + result += "isXTDSignalCrossedUnderBear: " + (string)mConditions.isXTDSignalCrossedUnderBear + separator; + } + + // + // Separator ... + result += separator; + + // + // XFI ... + result += + "| XFI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIPeak)) + { + result += "isXFIPeak: " + (string)mConditions.isXFIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIVale)) + { + result += "isXFIVale: " + (string)mConditions.isXFIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIOverZero)) + { + result += "isXFIOverZero: " + (string)mConditions.isXFIOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFIUnderZero)) + { + result += "isXFIUnderZero: " + (string)mConditions.isXFIUnderZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedOverZero)) + { + result += "isXFICrossedOverZero: " + (string)mConditions.isXFICrossedOverZero + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXFICrossedUnderZero)) + { + result += "isXFICrossedUnderZero: " + (string)mConditions.isXFICrossedUnderZero + separator; + } + + // + // Separator ... + result += separator; + + // + // XTS ... + result += + "| XTS |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSAllSame)) + { + result += "isXTSAllSame: " + (string)mConditions.isXTSAllSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMin)) + { + result += "isXTSCurrentMin: " + (string)mConditions.isXTSCurrentMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentMax)) + { + result += "isXTSCurrentMax: " + (string)mConditions.isXTSCurrentMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverFarest)) + { + result += "isXTSCurrentOverFarest: " + (string)mConditions.isXTSCurrentOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverNearest)) + { + result += "isXTSCurrentOverNearest: " + (string)mConditions.isXTSCurrentOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentOverMediest)) + { + result += "isXTSCurrentOverMediest: " + (string)mConditions.isXTSCurrentOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderFarest)) + { + result += "isXTSCurrentUnderFarest: " + (string)mConditions.isXTSCurrentUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderNearest)) + { + result += "isXTSCurrentUnderNearest: " + (string)mConditions.isXTSCurrentUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentUnderMediest)) + { + result += "isXTSCurrentUnderMediest: " + (string)mConditions.isXTSCurrentUnderMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverFarest)) + { + result += "isXTSCurrentCrossedOverFarest: " + (string)mConditions.isXTSCurrentCrossedOverFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverNearest)) + { + result += "isXTSCurrentCrossedOverNearest: " + (string)mConditions.isXTSCurrentCrossedOverNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedOverMediest)) + { + result += "isXTSCurrentCrossedOverMediest: " + (string)mConditions.isXTSCurrentCrossedOverMediest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderFarest)) + { + result += "isXTSCurrentCrossedUnderFarest: " + (string)mConditions.isXTSCurrentCrossedUnderFarest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderNearest)) + { + result += "isXTSCurrentCrossedUnderNearest: " + (string)mConditions.isXTSCurrentCrossedUnderNearest + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXTSCurrentCrossedUnderMediest)) + { + result += "isXTSCurrentCrossedUnderMediest: " + (string)mConditions.isXTSCurrentCrossedUnderMediest + separator; + } + + // + // Separator ... + result += separator; + + // + // XLH ... + result += + "| XLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHIncreased)) + { + result += "isXLHHHIncreased: " + (string)mConditions.isXLHHHIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHDecreased)) + { + result += "isXLHHHDecreased: " + (string)mConditions.isXLHHHDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLIncreased)) + { + result += "isXLHLLIncreased: " + (string)mConditions.isXLHLLIncreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLDecreased)) + { + result += "isXLHLLDecreased: " + (string)mConditions.isXLHLLDecreased + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHighAttachedHH)) + { + result += "isXLHHighAttachedHH: " + (string)mConditions.isXLHHighAttachedHH + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLowAttachedLL)) + { + result += "isXLHLowAttachedLL: " + (string)mConditions.isXLHLowAttachedLL + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHHHSameInLength)) + { + result += "isXLHHHSameInLength: " + (string)mConditions.isXLHHHSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHLLSameInLength)) + { + result += "isXLHLLSameInLength: " + (string)mConditions.isXLHLLSameInLength + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedOverSignal)) + { + result += "isXLHPriceCrossedOverSignal: " + (string)mConditions.isXLHPriceCrossedOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceOverSignal)) + { + result += "isXLHPriceOverSignal: " + (string)mConditions.isXLHPriceOverSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceCrossedUnderSignal)) + { + result += "isXLHPriceCrossedUnderSignal: " + (string)mConditions.isXLHPriceCrossedUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceUnderSignal)) + { + result += "isXLHPriceUnderSignal: " + (string)mConditions.isXLHPriceUnderSignal + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXLHPriceInSignalRange)) + { + result += "isXLHPriceInSignalRange: " + (string)mConditions.isXLHPriceInSignalRange + separator; + } + + // + // Separator ... + result += separator; + + // + // XRSI ... + result += + "| XRSI |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIPeak)) + { + result += "isXRSIPeak: " + (string)mConditions.isXRSIPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSIVale)) + { + result += "isXRSIVale: " + (string)mConditions.isXRSIVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongExit)) + { + result += "isXRSICrossedOverLongExit: " + (string)mConditions.isXRSICrossedOverLongExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedOverLongEntry)) + { + result += "isXRSICrossedOverLongEntry: " + (string)mConditions.isXRSICrossedOverLongEntry + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortExit)) + { + result += "isXRSICrossedUnderShortExit: " + (string)mConditions.isXRSICrossedUnderShortExit + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXRSICrossedUnderShortEntry)) + { + result += "isXRSICrossedUnderShortEntry: " + (string)mConditions.isXRSICrossedUnderShortEntry + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHLH ... + result += + "| XCHLH |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameHHs)) + { + result += "isXCHLHSameHHs: " + (string)mConditions.isXCHLHSameHHs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSameLLs)) + { + result += "isXCHLHSameLLs: " + (string)mConditions.isXCHLHSameLLs + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCHHSame)) + { + result += "isXCHLHSCMCHHSame: " + (string)mConditions.isXCHLHSCMCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCMCLLSame)) + { + result += "isXCHLHSCMCLLSame: " + (string)mConditions.isXCHLHSCMCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCHHSame)) + { + result += "isXCHLHSCLCHHSame: " + (string)mConditions.isXCHLHSCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHSCLCLLSame)) + { + result += "isXCHLHSCLCLLSame: " + (string)mConditions.isXCHLHSCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCHHSame)) + { + result += "isXCHLHMCLCHHSame: " + (string)mConditions.isXCHLHMCLCHHSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCLCLLSame)) + { + result += "isXCHLHMCLCLLSame: " + (string)mConditions.isXCHLHMCLCLLSame + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCOnTopOfLC)) + { + result += "isXCHLHMCOnTopOfLC: " + (string)mConditions.isXCHLHMCOnTopOfLC + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHLHMCInBottomOfLC)) + { + result += "isXCHLHMCInBottomOfLC: " + (string)mConditions.isXCHLHMCInBottomOfLC + separator; + } + + // + // Separator ... + result += separator; + + // + // XCHMA ... + result += + "| XCHMA |" + separator; + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMax)) + { + result += "isXCHMASCOverMax: " + (string)mConditions.isXCHMASCOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCOverMin)) + { + result += "isXCHMASCOverMin: " + (string)mConditions.isXCHMASCOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMax)) + { + result += "isXCHMASCUnderMax: " + (string)mConditions.isXCHMASCUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCUnderMin)) + { + result += "isXCHMASCUnderMin: " + (string)mConditions.isXCHMASCUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMax)) + { + result += "isXCHMASCCrossedOverMax: " + (string)mConditions.isXCHMASCCrossedOverMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMax)) + { + result += "isXCHMASCCrossedUnderMax: " + (string)mConditions.isXCHMASCCrossedUnderMax + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedOverMin)) + { + result += "isXCHMASCCrossedOverMin: " + (string)mConditions.isXCHMASCCrossedOverMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCCrossedUnderMin)) + { + result += "isXCHMASCCrossedUnderMin: " + (string)mConditions.isXCHMASCCrossedUnderMin + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCPeak)) + { + result += "isXCHMASCPeak: " + (string)mConditions.isXCHMASCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCVale)) + { + result += "isXCHMASCVale: " + (string)mConditions.isXCHMASCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsUp)) + { + result += "isXCHMASCTrendsUp: " + (string)mConditions.isXCHMASCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCTrendsDown)) + { + result += "isXCHMASCTrendsDown: " + (string)mConditions.isXCHMASCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastOverSlow)) + { + result += "isXCHMASCFastOverSlow: " + (string)mConditions.isXCHMASCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastUnderSlow)) + { + result += "isXCHMASCFastUnderSlow: " + (string)mConditions.isXCHMASCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedOverSlow)) + { + result += "isXCHMASCFastCrossedOverSlow: " + (string)mConditions.isXCHMASCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMASCFastCrossedUnderSlow)) + { + result += "isXCHMASCFastCrossedUnderSlow: " + (string)mConditions.isXCHMASCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCPeak)) + { + result += "isXCHMAMCPeak: " + (string)mConditions.isXCHMAMCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCVale)) + { + result += "isXCHMAMCVale: " + (string)mConditions.isXCHMAMCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsUp)) + { + result += "isXCHMAMCTrendsUp: " + (string)mConditions.isXCHMAMCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCTrendsDown)) + { + result += "isXCHMAMCTrendsDown: " + (string)mConditions.isXCHMAMCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastOverSlow)) + { + result += "isXCHMAMCFastOverSlow: " + (string)mConditions.isXCHMAMCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastUnderSlow)) + { + result += "isXCHMAMCFastUnderSlow: " + (string)mConditions.isXCHMAMCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedOverSlow)) + { + result += "isXCHMAMCFastCrossedOverSlow: " + (string)mConditions.isXCHMAMCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMAMCFastCrossedUnderSlow)) + { + result += "isXCHMAMCFastCrossedUnderSlow: " + (string)mConditions.isXCHMAMCFastCrossedUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCPeak)) + { + result += "isXCHMALCPeak: " + (string)mConditions.isXCHMALCPeak + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCVale)) + { + result += "isXCHMALCVale: " + (string)mConditions.isXCHMALCVale + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsUp)) + { + result += "isXCHMALCTrendsUp: " + (string)mConditions.isXCHMALCTrendsUp + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCTrendsDown)) + { + result += "isXCHMALCTrendsDown: " + (string)mConditions.isXCHMALCTrendsDown + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastOverSlow)) + { + result += "isXCHMALCFastOverSlow: " + (string)mConditions.isXCHMALCFastOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastUnderSlow)) + { + result += "isXCHMALCFastUnderSlow: " + (string)mConditions.isXCHMALCFastUnderSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedOverSlow)) + { + result += "isXCHMALCFastCrossedOverSlow: " + (string)mConditions.isXCHMALCFastCrossedOverSlow + separator; + } + + // + if ( + !ignoreFalses || + (ignoreFalses && mConditions.isXCHMALCFastCrossedUnderSlow)) + { + result += "isXCHMALCFastCrossedUnderSlow: " + (string)mConditions.isXCHMALCFastCrossedUnderSlow + separator; + } + + // + // Separator ... + result += separator; + + // + return result; + } + + // + // END Common Functions ... + // + + // + // START Actions Based On Signallers ... + // + + // + // START XTD Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTDignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTDEnableSignaller) + { + return result; + } + + // + result = true; + mXTDEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTDSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTDEnableSignaller) + { + return result; + } + + // + result = true; + mXTDEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTDLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + mXTDAllowLongSignals) + { + return result; + } + + // + result = true; + mXTDAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTDLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowLongSignals) + { + return result; + } + + // + result = true; + mXTDAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTDShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + mXTDAllowShortSignals) + { + return result; + } + + // + result = true; + mXTDAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTDShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowShortSignals) + { + return result; + } + + // + result = true; + mXTDAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTDHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXTDSignalCrossedOverBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTDHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTDEnableSignaller || + !mXTDAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXTDSignalCrossedUnderBear + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTD Signaller ... + // + + // + // START XTAM Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTAMignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTAMEnableSignaller) + { + return result; + } + + // + result = true; + mXTAMEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTAMSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTAMEnableSignaller) + { + return result; + } + + // + result = true; + mXTAMEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTAMLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + mXTAMAllowLongSignals) + { + return result; + } + + // + result = true; + mXTAMAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTAMLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowLongSignals) + { + return result; + } + + // + result = true; + mXTAMAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTAMShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + mXTAMAllowShortSignals) + { + return result; + } + + // + result = true; + mXTAMAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTAMShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowShortSignals) + { + return result; + } + + // + result = true; + mXTAMAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTAMHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (xAMAMaBuffer[1] > xTMMaBuffer[1] && + xAMAMaBuffer[2] > xTMMaBuffer[2]) + // + && + // + !(xAMAMaBuffer[2] > xTMMaBuffer[2] && + xAMAMaBuffer[3] > xTMMaBuffer[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTAMHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTAMEnableSignaller || + !mXTAMAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + (xAMAMaBuffer[1] < xTMMaBuffer[1] && + xAMAMaBuffer[2] < xTMMaBuffer[2]) + // + && + // + !(xAMAMaBuffer[2] < xTMMaBuffer[2] && + xAMAMaBuffer[3] < xTMMaBuffer[3]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTAM Signaller ... + // + + // + // START XSI Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXSIignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXSIEnableSignaller) + { + return result; + } + + // + result = true; + mXSIEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXSISignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXSIEnableSignaller) + { + return result; + } + + // + result = true; + mXSIEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXSILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + mXSIAllowLongSignals) + { + return result; + } + + // + result = true; + mXSIAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXSILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowLongSignals) + { + return result; + } + + // + result = true; + mXSIAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXSIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + mXSIAllowShortSignals) + { + return result; + } + + // + result = true; + mXSIAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXSIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowShortSignals) + { + return result; + } + + // + result = true; + mXSIAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XSIHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXRSICrossedOverLongEntry && + xRSIBuffer[3] < xRSILongEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XSIHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXSIEnableSignaller || + !mXSIAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXRSICrossedUnderShortEntry && + xRSIBuffer[3] > xRSIShortEntryValue + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + true, // XCHMA Cycles + true, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // END XSI Signaller ... + // + + // + // START XTSFI Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXTSFIignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXTSFIEnableSignaller) + { + return result; + } + + // + result = true; + mXTSFIEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXTSFISignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXTSFIEnableSignaller) + { + return result; + } + + // + result = true; + mXTSFIEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXTSFILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + mXTSFIAllowLongSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXTSFILongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowLongSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXTSFIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + mXTSFIAllowShortSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXTSFIShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowShortSignals) + { + return result; + } + + // + result = true; + mXTSFIAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XTSFIHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + XTSGetMinValue(1) == xTSFarestBuffer[1] && + (mXConditions.isXTSCurrentOverFarest || + mXConditions.isXTSCurrentCrossedOverFarest) && + (xTSCurrentBuffer[1] < xTSNearestBuffer[1] || + xTSCurrentBuffer[1] < xTSMediestBuffer[1]) && + !(mXConditions.isXTSCurrentUnderNearest || + mXConditions.isXTSCurrentCrossedUnderNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XTSFIHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXTSFIEnableSignaller || + !mXTSFIAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + XTSGetMaxValue(1) == xTSFarestBuffer[1] && + (mXConditions.isXTSCurrentUnderFarest || + mXConditions.isXTSCurrentCrossedUnderFarest) && + (xTSCurrentBuffer[1] > xTSNearestBuffer[1] || + xTSCurrentBuffer[1] > xTSMediestBuffer[1]) && + !(mXConditions.isXTSCurrentOverNearest || + mXConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XTSFI Signaller ... + // + + // + // START XOBDLH Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXOBDLHignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXOBDLHEnableSignaller) + { + return result; + } + + // + result = true; + mXOBDLHEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXOBDLHSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXOBDLHEnableSignaller) + { + return result; + } + + // + result = true; + mXOBDLHEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXOBDLHLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + mXOBDLHAllowLongSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXOBDLHLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowLongSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXOBDLHShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + mXOBDLHAllowShortSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXOBDLHShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowShortSignals) + { + return result; + } + + // + result = true; + mXOBDLHAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XOBDLHHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowLongSignals) + { + return result; + } + + // + XMarketConditions xConditions2 = GenerateMarketConditions(2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xConditions2.isXOBDSwingLow && + xConditions2.isXLHLowAttachedLL && + xLHLLBuffer[1] >= xLHLLBuffer[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XOBDLHHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXOBDLHEnableSignaller || + !mXOBDLHAllowShortSignals) + { + return result; + } + + // + XMarketConditions xConditions2 = GenerateMarketConditions(2); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xConditions2.isXOBDSwingHigh && + xConditions2.isXLHHighAttachedHH && + xLHHHBuffer[1] <= xLHHHBuffer[2] + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + false, // XOBD + false // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // END XOBDLH Signaller ... + // + + // + // START XCHMACC Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMACCignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMACCEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMACCEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMACCSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMACCEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMACCEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMACCLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + mXCHMACCAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMACCLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMACCShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + mXCHMACCAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMACCShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMACCAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMACCHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowLongSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xCHMAScFastBuffer[1] > xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] > xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] > xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] > xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] > xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] > xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] > xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] > xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] > xCHMALcSlowBuffer[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong() + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMACCHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMACCEnableSignaller || + !mXCHMACCAllowShortSignals) + { + return result; + } + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + xCHMAScFastBuffer[1] < xCHMAScSlowBuffer[1] && + xCHMAMcFastBuffer[1] < xCHMAMcSlowBuffer[1] && + xCHMALcFastBuffer[1] < xCHMALcSlowBuffer[1] && + // + xCHMAScFastBuffer[2] < xCHMAScSlowBuffer[2] && + xCHMAMcFastBuffer[2] < xCHMAMcSlowBuffer[2] && + xCHMALcFastBuffer[2] < xCHMALcSlowBuffer[2] && + // + !( + // + xCHMAScFastBuffer[3] < xCHMAScSlowBuffer[3] && + xCHMAMcFastBuffer[3] < xCHMAMcSlowBuffer[3] && + xCHMALcFastBuffer[3] < xCHMALcSlowBuffer[3] + // + ) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort() + // + ) + // + ; + + // + return result; + } + + // + // END XCHMACC Signaller ... + // + + // + // START XCHMAMX Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMAMXignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMAMXEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMXEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMAMXSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMAMXEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMXEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMAMXLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + mXCHMAMXAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMAMXLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMAMXShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + mXCHMAMXAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMAMXShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMXAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMAMXHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedOverMax && + xCHMAScFastBuffer[2] < xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMax2 && + MathAbs(xCHMANonSCMax2 - xCHMAScFastBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) && + MathAbs(xCHMANonSCMax2 - xCHMAScSlowBuffer[2]) > MathAbs(xCHMAScFastBuffer[2] - xCHMAScSlowBuffer[2]) + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMAMXHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMXEnableSignaller || + !mXCHMAMXAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMax2 = XCHMAGetCyclesMaxValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedUnderMax && + xCHMAScFastBuffer[2] > xCHMANonSCMax2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMax2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForShort( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + // + return result; + } + + // + // END XCHMAMX Signaller ... + // + + // + // START XCHMAMN Signaller ... + // + + // + // Enable Signaller ... + bool EnableSXCHMAMNignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (mXCHMAMNEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMNEnableSignaller = true; + + // + return result; + } + + // + // Disable Signaller ... + bool DisbaleXCHMAMNSignaller() + { + // + bool result = false; + + // + // Validate Args ... + if (!mXCHMAMNEnableSignaller) + { + return result; + } + + // + result = true; + mXCHMAMNEnableSignaller = false; + + // + return result; + } + + // + // Allow Sginaller to Issue Long Signals ... + bool EnableXCHMAMNLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + mXCHMAMNAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowLongSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Long Signals ... + bool DisbaleXCHMAMNLongs() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowLongSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowLongSignals = false; + + // + return result; + } + + // + // Allow Signaller to Issue Short Sginals ... + bool EnableXCHMAMNShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + mXCHMAMNAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowShortSignals = true; + + // + return result; + } + + // + // Disallow Signaller to Issue Short Signals ... + bool DisableXCHMAMNShorts() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowShortSignals) + { + return result; + } + + // + result = true; + mXCHMAMNAllowShortSignals = false; + + // + return result; + } + + // + // Check Market Base Conditions for Long Signals ... + bool XCHMAMNHasLongConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowLongSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedOverMin && + xCHMAScFastBuffer[2] < xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] < xCHMANonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + + // + return result; + } + + // + // Check Market Base Conditions for Short Signals ... + bool XCHMAMNHasShortConditions() + { + // + bool result = false; + + // + // Validate Args ... + if ( + !mXCHMAMNEnableSignaller || + !mXCHMAMNAllowShortSignals) + { + return result; + } + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double xCHMANonSCMin2 = XCHMAGetCyclesMinValue(2, cycles); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + // each Strategy must has a Base Conditions, which they are usually common combinations + // of Market Properties that must be happens to lookup for signals ... + ( + // + mXConditions.isXCHMASCCrossedUnderMin && + xCHMAScFastBuffer[2] > xCHMANonSCMin2 && + xCHMAScSlowBuffer[2] > xCHMANonSCMin2 + // + ) + // + && + // + // Next Step is combine sorts of Conditions which make our choice + // so Exact in Market ... + ( + // + IsReadyForLong( + true, // XCHMA Min + true, // XCHMA Max + false, // XCHMA Cycles + false, // XCHMA Peaks + false, // XCHMA Trend Powers + true, // XOBD + true // XTS + ) + // + ) + // + ; + // + return result; + } + + // + // END XCHMAMN Signaller ... + // + + // + // END Actions Based On Signallers ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // XTD ... + bool mXTDEnableSignaller; + bool mXTDAllowLongSignals; + bool mXTDAllowShortSignals; + + // + // XTAM ... + bool mXTAMEnableSignaller; + bool mXTAMAllowLongSignals; + bool mXTAMAllowShortSignals; + + // + // XSI ... + bool mXSIEnableSignaller; + bool mXSIAllowLongSignals; + bool mXSIAllowShortSignals; + + // + // XTSFI ... + bool mXTSFIEnableSignaller; + bool mXTSFIAllowLongSignals; + bool mXTSFIAllowShortSignals; + + // + // XOBDLH ... + bool mXOBDLHEnableSignaller; + bool mXOBDLHAllowLongSignals; + bool mXOBDLHAllowShortSignals; + + // + // XCHMACC ... + bool mXCHMACCEnableSignaller; + bool mXCHMACCAllowLongSignals; + bool mXCHMACCAllowShortSignals; + + // + // XCHMAMX ... + bool mXCHMAMXEnableSignaller; + bool mXCHMAMXAllowLongSignals; + bool mXCHMAMXAllowShortSignals; + + // + // XCHMAMN ... + bool mXCHMAMNEnableSignaller; + bool mXCHMAMNAllowLongSignals; + bool mXCHMAMNAllowShortSignals; + + // + // Here we Define some Global Market Variables to Analyse MArket Conditions + // using them at each time ... + XMarketConditions mXConditions; +}; \ No newline at end of file diff --git a/Experts/x-saherelm.xau5.ea.mq5 b/Experts/x-saherelm.xau5.ea.mq5 new file mode 100644 index 00000000..002dbff8 --- /dev/null +++ b/Experts/x-saherelm.xau5.ea.mq5 @@ -0,0 +1,395 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Expert Advisor +// ---------------------------------------- +// Name: XAUUSD +// Description: this is an expert controller +// advisors which provides a mechanism for use them ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XAU5 EA" +#property strict + +// +// START Inputs ... +// + +input group "Commons"; + +// +// XCTIMER inputs ... +input bool xAU5ShowCandleTimer = true; // Show Condle Remaining Time +input color xAU5CandleTimerColot = clrYellow; // Candle Timer Color +input ENUM_BASE_CORNER xAU5CandleTimerCorner = CORNER_RIGHT_LOWER; // Where to Show Candle Timer + +// +// END Inputs ... +// + +// +// START Including Providers ... +// + +// +// Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// XAU5 Signal Provider ... +#include "../Providers/x-saherelm.xau5.provider.lib.mq5" + +// +// END Including Providers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +bool isXAU5NewHour; +bool isXAU5NewDay; +bool isXAU5NewWeek; +bool isXAU5NewMonth; + +// +int xAU5CTimerHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + logTag = "XAU5EA"; + drawPrefix = logTag; + alertPrefix = logTag; + + // + // Apply default Chart Style for EA ... + ApplyChartStyle(); + + // + // Reset Timings ... + ResetTiming(); + + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Initialize XAU5 Provider ... + if (!XAU5InitSignalProviderLibrary()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init XCTimer ... + if (xAU5ShowCandleTimer) + { + if (!XAU5CTimerInit()) + { + return INIT_FAILED; + } + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Initialize XAU5 Provider ... + XAU5DeinitSignalProviderLibrary(reason); + + // + // De Init XDraw Library ... + // OnDeinitDrawLibrary(); + + // + IndicatorRelease(xAU5CTimerHandler); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + // Handle Monthly Alert ... + bool isFirstMonth = xMonth == -1; + isXAU5NewMonth = IsNewMonth(); + bool canMonthlyAlert = + isXAU5NewMonth && + xAU5EnableAlerts && + xAU5EnableMonthlyAlerts; + bool canMonthlyReport = + !isFirstMonth && + canMonthlyAlert && + xAU5EnableMonthlyReports; + if (canMonthlyAlert) + { + // + string message = "New Month ..."; + + // + // Prepare Monthly Report ... + if (canMonthlyReport) + { + // + string report = xAU5Reporter.GenerateReportString(XREPORT_MONTHLY); + + // + message = "Last Month Report:\n" + report; + } + + // + // Reset Report ... + xAU5Reporter.Reset(XREPORT_MONTHLY); + + // + SendAlert(message); + } + + // + // Handle Weekly Alert ... + bool isFirstWeek = xDayOfWeek == -1; + isXAU5NewWeek = IsNewWeek(); + bool canWeeklyAlert = + isXAU5NewWeek && + xAU5EnableAlerts && + xAU5EnableWeeklyAlerts; + bool canWeeklyReport = + !isFirstWeek && + canWeeklyAlert && + xAU5EnableWeeklyReports; + if (canWeeklyAlert) + { + // + string message = "New Week ..."; + + // + // Prepare Weekly Report ... + if (canWeeklyReport) + { + // + string report = xAU5Reporter.GenerateReportString(XREPORT_WEEKLY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xAU5Reporter.Reset(XREPORT_WEEKLY); + + // + SendAlert(message); + } + + // + // Handle Daily Alert ... + bool isFirstDay = xDay == -1; + isXAU5NewDay = IsNewDay(); + bool canDailyAlert = + isXAU5NewDay && + xAU5EnableAlerts && + xAU5EnableDailyAlerts; + bool canDailyReport = + !isFirstDay && + canDailyAlert && + xAU5EnableDailyReports; + if (canDailyAlert) + { + // + string message = "New Day ..."; + + // + // Prepare Daily Report ... + if (canDailyReport) + { + // + string report = xAU5Reporter.GenerateReportString(XREPORT_DAILY); + + // + message = "Last Week Report:\n" + report; + } + + // + // Reset Report ... + xAU5Reporter.Reset(XREPORT_DAILY); + + // + SendAlert(message); + } + + // + // Handle Hourly Alert ... + bool isFirstHour = xHour == -1; + isXAU5NewHour = IsNewHour(); + bool canHourlyAlert = + isXAU5NewHour && + xAU5EnableAlerts && + xAU5EnableHourlyAlerts; + if (canHourlyAlert) + { + // + string message = "New Hour ..."; + + // + SendAlert(message); + } + + // + // Prevent Going Forward if user Disable it ... + if (xAU5EnableProvider) + { + // + // Handle Processing on XAU5 Signal Provider ... + XAU5SignalProviderDoControlState(); + } + + // + if (!IsNewCandle() && xAU5WaitUntilNextCandle) + { + return; + } + + // + xAU5WaitUntilNextCandle = false; + + // + // Prevent Going Forward if user Disable it ... + if (xAU5EnableProvider) + { + // + // Handle Processing on XAU5 Signal Provider ... + XAU5SignalProviderHandleTick(); + } +} + +// +// Handle Trade Events ... +void OnTrade() +{ + + // + // Prevent Going Forward if user Disable it ... + if (xAU5EnableProvider) + { + // + // Handle Processing Trades on XAU5 Signal Provider ... + XAU5SignalProviderHandleTrade(); + } +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + + // + // Validate XAU5 Provider Inputs ... + result = XAU5ValidateInputs(); + if (!result) + { + return false; + } + + // + // Logging State ... + string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; + LogMessage(message); + + // + return result; +} + +bool XAU5CTimerInit() +{ + // + bool result = true; + + // + xAU5CTimerHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xctimer.indicator", + // + // Inputs ... + xAU5CandleTimerColot, + xAU5CandleTimerCorner + ); + + // + if (xAU5CTimerHandler == INVALID_HANDLE) { + result = false; + } + + // + return result; +} +// +// END Functions ... +// diff --git a/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 b/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 new file mode 100644 index 00000000..f565e415 --- /dev/null +++ b/Helpers/x-saherelm.xama.indicator.helper.lib.mq5 @@ -0,0 +1,607 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; + +// +// XAMA Indicator Buffer Lines ... +enum ENUM_X_XAMA_BUFFER_LINES +{ + X_XAMA_MA_LINE = 0, + X_XAMA_MC_COLOR_LINE = 1, + X_XAMA_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XAMA Indicator"; + +// +// input int xAMALength = 18; // Market Length +// input int xAMAFastEMA = 2; // Fast EMA Period +// input int xAMASlowEMA = 30; // Slow EMA Period +// input int xAMAShift = 0; // Shift +// input ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// Configurations ... +int xAMALength = 18; // Market Length +int xAMAFastEMA = 2; // Fast EMA Period +int xAMASlowEMA = 30; // Slow EMA Period +int xAMAShift = 0; // Shift +ENUM_APPLIED_PRICE xAMAAppliedTo = PRICE_CLOSE; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xAMAHandler = INVALID_HANDLE; +double xAMAMaBuffer[]; +double xAMAStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XAMAValidateInputs() +{ + // + bool result = false; + + // + result = + xAMALength > 2 && + xAMAFastEMA < xAMALength && + xAMAFastEMA < xAMASlowEMA && + xAMAShift >= 0; + + // + if (!result) + { + // + LogMessage("XAMA Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XAMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Indicator Handlers ... + ResetLastError(); + + // + // XAMA Handler ... + ArraySetAsSeries(xAMAMaBuffer, true); + ArraySetAsSeries(xAMAStateBuffer, true); + xAMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xama.indicator", + // + // Inputs ... + xAMALength, + xAMAFastEMA, + xAMASlowEMA, + xAMAShift, + xAMAAppliedTo + // + ); + if (xAMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XAMA Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XAMAReleaseHandlers() +{ + IndicatorRelease(xAMAHandler); +} + +// +// Handle Reading Buffers ... +void XAMAReadBuffers( + int xAMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XAMA Ma Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_MA_LINE, + 0, + xAMAItemsPerTick, + xAMAMaBuffer); + + // + // XAMA State Buffer ... + CopyBuffer( + xAMAHandler, + X_XAMA_STATE_LINE, + 0, + xAMAItemsPerTick, + xAMAStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XAMA Custom Functions ... +// + +// +// Check SC is Peak ... +bool XAMAIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XAMAIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xAMAMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XAMAIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XAMAIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XAMAIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XAMAIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BULLISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XAMAIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XAMAIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] != X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XAMAIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XAMAIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XAMAIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] != X_XAMA_BEARISH && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XAMAIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL && + xAMAStateBuffer[bar_index + 1] == X_XAMA_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XAMAIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XAMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xAMAStateBuffer[bar_index] == X_XAMA_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XAMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xAMAMaBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XAMA Custom Functions ... +// diff --git a/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..d7071b48 --- /dev/null +++ b/Helpers/x-saherelm.xchlh.oscillator.helper.lib.mq5 @@ -0,0 +1,1032 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHLH Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Cycles Enumeration ... +enum ENUM_X_XCHLH_CYCLES +{ + X_XCHLH_CYCLE_LONG, + X_XCHLH_CYCLE_MEDIUM, + X_XCHLH_CYCLE_SHORT, +}; + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// XCHLH Buffer Lines ... +enum ENUM_X_XCHLH_BUFFER_LINES +{ + X_XCHLH_LC_HH_LINE = 0, + X_XCHLH_LC_LL_LINE = 1, + X_XCHLH_MC_HH_LINE = 2, + X_XCHLH_MC_LL_LINE = 3, + X_XCHLH_SC_HH_LINE = 4, + X_XCHLH_SC_LL_LINE = 5, + X_XCHLH_SIGNAL_T_LINE = 6, + X_XCHLH_SIGNAL_B_LINE = 7, + X_XCHLH_HOT_STATE_LINE = 8, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XCHLH Oscillator"; + +// // +// // Common ... +// input group "XCHLH Hot Areas"; +// input bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +// input uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +// input color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +// input uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +// input color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// // +// // LC Inputs ... +// input group "XCHLH Long Cycle"; +// input group "XCHLH LC Market"; +// input int xCHLHLcLength = 288; // Length +// input double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH LC Style"; +// input int xCHLHLcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHLcHHColor = clrAqua; // Highest High Color +// input color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +// input group "XCHLH LC Drawings"; +// input bool xCHLHLcDrawHH = true; // Draw Highest High +// input bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// // +// // MC Inputs ... +// input group "XCHLH Medium Cycle"; +// input group "XCHLH MC Market"; +// input int xCHLHMcLength = 72; // Length +// input double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH MC Style"; +// input int xCHLHMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHMcHHColor = clrLime; // Highest High Color +// input color xCHLHMcLLColor = clrRed; // Lowest Low Color +// input group "XCHLH MC Drawings"; +// input bool xCHLHMcDrawHH = true; // Draw Highest High +// input bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// // +// // SC Inputs ... +// input group "XCHLH Short Cycle"; +// input group "XCHLH SC Market"; +// input int xCHLHScLength = 7; // Length +// input double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +// input ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +// input group "XCHLH SC Style"; +// input int xCHLHScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +// input color xCHLHScHHColor = clrLightBlue; // Highest High Color +// input color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +// input group "XCHLH SC Drawings"; +// input bool xCHLHScDrawHH = true; // Draw Highest High +// input bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// Configurations ... +// +// Common ... +bool xCHLHDrawHotAreas = false; // Draw Hot Areas Symbol +uchar xCHLHHotHHArrowCode = 234; // Hot HH Arrow Code +color xCHLHHotHHArrowColor = clrAqua; // Hot HH Arrow Color +uchar xCHLHHotLLArrowCode = 233; // Hot LL Arrow Code +color xCHLHHotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +int xCHLHLcLength = 288; // Length +double xCHLHLcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHLcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHLcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHLcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHLcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHLcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHLcHHColor = clrAqua; // Highest High Color +color xCHLHLcLLColor = clrFuchsia; // Lowest Low Color +bool xCHLHLcDrawHH = true; // Draw Highest High +bool xCHLHLcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +int xCHLHMcLength = 72; // Length +double xCHLHMcThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHMcHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHMcLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHMcDrawStyle = STYLE_DOT; // Draw Style +color xCHLHMcHHColor = clrLime; // Highest High Color +color xCHLHMcLLColor = clrRed; // Lowest Low Color +bool xCHLHMcDrawHH = true; // Draw Highest High +bool xCHLHMcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +int xCHLHScLength = 7; // Length +double xCHLHScThresholdInPips = 0.3; // Threshold In Pips +ENUM_SERIESMODE xCHLHScHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xCHLHScLLMode = MODE_LOW; // Lowest Low Calculation Method +int xCHLHScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHLHScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHLHScDrawStyle = STYLE_DOT; // Draw Style +color xCHLHScHHColor = clrLightBlue; // Highest High Color +color xCHLHScLLColor = clrLightSalmon; // Lowest Low Color +bool xCHLHScDrawHH = true; // Draw Highest High +bool xCHLHScDrawLL = true; // Draw Lowest Low + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHLHHandler = INVALID_HANDLE; +double xCHLHLcHHBuffer[]; +double xCHLHLcLLBuffer[]; +double xCHLHMcHHBuffer[]; +double xCHLHMcLLBuffer[]; +double xCHLHScHHBuffer[]; +double xCHLHScLLBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHLHValidateInputs() +{ + // + bool result = false; + + // + result = + xCHLHScLength >= 2 && + xCHLHMcLength > xCHLHScLength && + xCHLHLcLength > xCHLHMcLength; + + // + if (!result) + { + // + LogMessage("XCHLH Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHLH Handler ... + ArraySetAsSeries(xCHLHLcHHBuffer, true); + ArraySetAsSeries(xCHLHLcLLBuffer, true); + ArraySetAsSeries(xCHLHMcHHBuffer, true); + ArraySetAsSeries(xCHLHMcLLBuffer, true); + ArraySetAsSeries(xCHLHScHHBuffer, true); + ArraySetAsSeries(xCHLHScLLBuffer, true); + xCHLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchlh.oscillator", + // + // Inputs ... + // + // Commons ... + "", + xCHLHDrawHotAreas, + xCHLHHotHHArrowCode, + xCHLHHotHHArrowColor, + xCHLHHotLLArrowCode, + xCHLHHotLLArrowColor, + // + // LC ... + "", + "", + xCHLHLcLength, + xCHLHLcThresholdInPips, + xCHLHLcHHMode, + xCHLHLcLLMode, + "", + xCHLHLcDrawWidth, + xCHLHLcDrawType, + xCHLHLcDrawStyle, + xCHLHLcHHColor, + xCHLHLcLLColor, + "", + xCHLHLcDrawHH, + xCHLHLcDrawLL, + // + // MC ... + "", + "", + xCHLHMcLength, + xCHLHMcThresholdInPips, + xCHLHMcHHMode, + xCHLHMcLLMode, + "", + xCHLHMcDrawWidth, + xCHLHMcDrawType, + xCHLHMcDrawStyle, + xCHLHMcHHColor, + xCHLHMcLLColor, + "", + xCHLHMcDrawHH, + xCHLHMcDrawLL, + // + // SC ... + "", + "", + xCHLHScLength, + xCHLHScThresholdInPips, + xCHLHScHHMode, + xCHLHScLLMode, + "", + xCHLHScDrawWidth, + xCHLHScDrawType, + xCHLHScDrawStyle, + xCHLHScHHColor, + xCHLHScLLColor, + "", + xCHLHScDrawHH, + xCHLHScDrawLL); + if (xCHLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHLHReleaseHandlers() +{ + IndicatorRelease(xCHLHHandler); +} + +// +// Handle Reading Buffers ... +void XCHLHReadBuffers( + int xCHLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHLH LC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcHHBuffer); + + // + // XCHLH LC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_LC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHLcLLBuffer); + + // + // XCHLH MC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcHHBuffer); + + // + // XCHLH MC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_MC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHMcLLBuffer); + + // + // XCHLH SC HH Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_HH_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScHHBuffer); + + // + // XCHLH SC LL Buffer ... + CopyBuffer( + xCHLHHandler, + X_XCHLH_SC_LL_LINE, + 0, + xCHLHItemsPerTick, + xCHLHScLLBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHLH Custom Functions ... +// + +// +// Check LC and MC has Same HH ... +bool XCHLHIsLCMCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and MC has Same LL ... +bool XCHLHIsLCMCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + + // + result = lcValue == mcValue; + + // + return result; +} + +// +// Check LC and SC has Same HH ... +bool XCHLHIsLCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check LC and SC has Same LL ... +bool XCHLHIsLCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = lcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same HH ... +bool XCHLHIsMCSCHasSameHH( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check MC and SC has Same LL ... +bool XCHLHIsMCSCHasSameLL( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = mcValue == scValue; + + // + return result; +} + +// +// Check Is Same Highest Highs ... +bool XCHLHIsSameHHs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcHHBuffer[bar_index]; + double mcValue = xCHLHMcHHBuffer[bar_index]; + double scValue = xCHLHScHHBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Is Same Lowest Lows ... +bool XCHLHIsSameLLs( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if (!XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + double lcValue = xCHLHLcLLBuffer[bar_index]; + double mcValue = xCHLHMcLLBuffer[bar_index]; + double scValue = xCHLHScLLBuffer[bar_index]; + + // + result = + // + lcValue == mcValue && + mcValue == scValue + // + ; + + // + return result; +} + +// +// Check Medium Cycle is On Top of Long Cycle's Mid ... +bool XCHLHIsMCOnTopOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsOnTopOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check Medium Cycle is In Bottom of Long Cycle's Mid ... +bool XCHLHIsMCInBottomOfLC( + int bar_index // Specified Bar Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + ENUM_X_XCHLH_CYCLES sCycle = X_XCHLH_CYCLE_MEDIUM; + ENUM_X_XCHLH_CYCLES dCycle = X_XCHLH_CYCLE_LONG; + + // + result = + // + XCHLHCheckCycleIsInBottomOfAnother( + bar_index, + sCycle, + dCycle) + // + ; + + // + return result; +} + +// +// Check and Validate Buffer Sizes ... +bool XCHLHIsValidBufferSizes( + int size // Specified Min Size +) +{ + // + bool result = false; + + // + result = + // + ArraySize(xCHLHLcHHBuffer) > size && + ArraySize(xCHLHLcLLBuffer) > size && + // + ArraySize(xCHLHMcHHBuffer) > size && + ArraySize(xCHLHMcLLBuffer) > size && + // + ArraySize(xCHLHScHHBuffer) > size && + ArraySize(xCHLHScLLBuffer) > size; + + // + return result; +} + +// +// Get Cycle Middle Value ... +double XCHLHGetCycleMid( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Cycle Max Value ... + double iMax = XCHLHGetCycleMax( + bar_index, + cycle); + + // + // Retrieve Cycle Min Value ... + double iMin = XCHLHGetCycleMin( + bar_index, + cycle); + + // + result = (iMax - iMin) / 2; + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHLHGetCycleMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcHHBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcHHBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScHHBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Max Value ... +double XCHLHGetCyclesMax( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMax( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHLHGetCycleMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + // Long Cycle ... + case X_XCHLH_CYCLE_LONG: + result = xCHLHLcLLBuffer[1]; + break; + + // + // Medium Cycle ... + case X_XCHLH_CYCLE_MEDIUM: + result = xCHLHMcLLBuffer[1]; + break; + + // + // Short Cycle ... + case X_XCHLH_CYCLE_SHORT: + result = xCHLHScLLBuffer[1]; + break; + } + + // + return result; +} + +// +// Get Specified Cycles Min Value ... +double XCHLHGetCyclesMin( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES &cycles[] // Specified Cycle ... +) +{ + // + bool result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + ArraySize(cycles) <= 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycles); i++) + { + // + ENUM_X_XCHLH_CYCLES iCycle = cycles[i]; + + // + double iValue = XCHLHGetCycleMin( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Check a Cycle is On Top of Another Cycle's Mid ... +bool XCHLHCheckCycleIsOnTopOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Min Value of Source Cycle ... + double iMin = XCHLHGetCycleMin( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMin >= iMid + // + ; + + // + return result; +} + +// +// Check a Cycle is Under Bottom of Another Cycle's Mid ... +bool XCHLHCheckCycleIsInBottomOfAnother( + int bar_index, // Specified Bar Index ... + ENUM_X_XCHLH_CYCLES sourceCycle, // Specified Source Cycle which Checks ... + ENUM_X_XCHLH_CYCLES destCycle // Specified Dest Cycle which source Checked based on it ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHLHIsValidBufferSizes(bar_index + 1)) + { + return result; + } + + // + // Retrieve Max Value of Source Cycle ... + double iMax = XCHLHGetCycleMax( + bar_index, + sourceCycle); + + // + // Retrieve Mid Value of Dest Cycle ... + double iMid = XCHLHGetCycleMid( + bar_index, + destCycle); + + // + // Generate Result ... + result = + // + iMax <= iMid + // + ; + + // + return result; +} + +// +// END XCHLH Custom Functions ... +// diff --git a/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..e84d762f --- /dev/null +++ b/Helpers/x-saherelm.xchma.oscillator.helper.lib.mq5 @@ -0,0 +1,2229 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCHMA Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XCHMA Cycles ... +enum ENUM_XCHMA_CYCLES +{ + X_XCHMA_CYCLE_LONG, + X_XCHMA_CYCLE_MEDIUM, + X_XCHMA_CYCLE_SHORT, +}; + +// +// XCHMA Oscillator Hot State Presentation ... +enum ENUM_XCHMA_HOT_STATES +{ + X_XCHMA_HOT_BULLISH = 1, + X_XCHMA_HOT_NEUTURAL = 0, + X_XCHMA_HOT_BEARISH = -1, +}; + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; + +// +// XCHMA Oscillator Buffer Lines ... +enum ENUM_X_XCHMA_BUFFER_LINES +{ + X_XCHMA_LC_FAST_LINE = 0, + X_XCHMA_LC_SLOW_LINE = 1, + X_XCHMA_LC_STATE_LINE = 6, + X_XCHMA_MC_FAST_LINE = 2, + X_XCHMA_MC_SLOW_LINE = 3, + X_XCHMA_MC_STATE_LINE = 7, + X_XCHMA_SC_FAST_LINE = 4, + X_XCHMA_SC_SLOW_LINE = 5, + X_XCHMA_SC_STATE_LINE = 8, + X_XCHMA_HOT_STATE_LINE = 9, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XCHMA Oscillator"; + +// // +// // Commons ... +// input group "XCHMA Hot Areas"; +// input bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +// input uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +// input color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +// input uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +// input color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// // +// // LC Inputs ... +// input group "XCHMA Long Cycle"; +// input group "XCHMA LC Market"; +// input int xCHMALcFastLength = 288; // Fast Length +// input int xCHMALcSlowLength = 576; // Slow Length +// input ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA LC Style"; +// input int xCHMALcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMALcFastColor = clrAqua; // Fast Color +// input color xCHMALcSlowColor = clrFuchsia; // Slow Color +// input group "XCHMA LC Drawings"; +// input bool xCHMALcDrawFast = true; // Draw Fast +// input bool xCHMALcDrawSlow = true; // Draw Slow +// input bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// // +// // MC Inputs ... +// input group "XCHMA Medium Cycle"; +// input group "XCHMA MC Market"; +// input int xCHMAMcFastLength = 72; // Fast Length +// input int xCHMAMcSlowLength = 144; // Slow Length +// input ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA MC Style"; +// input int xCHMAMcDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +// input color xCHMAMcFastColor = clrLime; // Fast Color +// input color xCHMAMcSlowColor = clrRed; // Slow Color +// input group "XCHMA MC Drawings"; +// input bool xCHMAMcDrawFast = true; // Draw Fast +// input bool xCHMAMcDrawSlow = true; // Draw Slow +// input bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// // +// // SC Inputs ... +// input group "XCHMA Short Cycle"; +// input group "XCHMA SC Market"; +// input int xCHMAScFastLength = 7; // Fast Length +// input int xCHMAScSlowLength = 14; // Slow Length +// input ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +// input ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +// input group "XCHMA SC Style"; +// input int xCHMAScDrawWidth = 1; // Draw Width +// input ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +// input ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +// input color xCHMAScFastColor = clrLightBlue; // Fast Color +// input color xCHMAScSlowColor = clrLightSalmon; // Slow Color +// input group "XCHMA SC Drawings"; +// input bool xCHMAScDrawFast = true; // Draw Fast +// input bool xCHMAScDrawSlow = true; // Draw Slow +// input bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// Configurations ... +// +// Commons ... +bool xCHMADrawHotAreas = false; // Draw Hot Areas Symbol; +uchar xCHMAHotBullishArrowCode = 228; // Hot Bullish Arrow Code; +color xCHMAHotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color; +uchar xCHMAHotBearishArrowCode = 230; // Hot Bearish Arrow Code; +color xCHMAHotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color; + +// +// LC Inputs ... +int xCHMALcFastLength = 288; // Fast Length +int xCHMALcSlowLength = 576; // Slow Length +ENUM_MA_METHOD xCHMALcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMALcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMALcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMALcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMALcDrawStyle = STYLE_DOT; // Draw Style +color xCHMALcFastColor = clrAqua; // Fast Color +color xCHMALcSlowColor = clrFuchsia; // Slow Color +bool xCHMALcDrawFast = true; // Draw Fast +bool xCHMALcDrawSlow = true; // Draw Slow +bool xCHMALcDrawCrosses = false; // Draw Cross Lines + +// +// MC Inputs ... +int xCHMAMcFastLength = 72; // Fast Length +int xCHMAMcSlowLength = 144; // Slow Length +ENUM_MA_METHOD xCHMAMcMethod = MODE_EMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAMcAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAMcDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAMcDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAMcDrawStyle = STYLE_DOT; // Draw Style +color xCHMAMcFastColor = clrLime; // Fast Color +color xCHMAMcSlowColor = clrRed; // Slow Color +bool xCHMAMcDrawFast = true; // Draw Fast +bool xCHMAMcDrawSlow = true; // Draw Slow +bool xCHMAMcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +int xCHMAScFastLength = 7; // Fast Length +int xCHMAScSlowLength = 14; // Slow Length +ENUM_MA_METHOD xCHMAScMethod = MODE_SMA; // Calculation Method +ENUM_APPLIED_PRICE xCHMAScAppliedTo = PRICE_CLOSE; // Applied To +int xCHMAScDrawWidth = 1; // Draw Width +ENUM_DRAW_TYPE xCHMAScDrawType = DRAW_LINE; // Draw Type +ENUM_LINE_STYLE xCHMAScDrawStyle = STYLE_SOLID; // Draw Style +color xCHMAScFastColor = clrLightBlue; // Fast Color +color xCHMAScSlowColor = clrLightSalmon; // Slow Color +bool xCHMAScDrawFast = true; // Draw Fast +bool xCHMAScDrawSlow = true; // Draw Slow +bool xCHMAScDrawCrosses = false; // Draw Cross Lines + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xCHMAHandler = INVALID_HANDLE; +double xCHMALcFastBuffer[]; +double xCHMALcSlowBuffer[]; +double xCHMAMcFastBuffer[]; +double xCHMAMcSlowBuffer[]; +double xCHMAScFastBuffer[]; +double xCHMAScSlowBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XCHMAValidateInputs() +{ + // + bool result = false; + + // + result = + xCHMAScFastLength >= 2 && + xCHMAScSlowLength > xCHMAScFastLength && + xCHMAMcFastLength > xCHMAScSlowLength && + xCHMAMcSlowLength > xCHMAMcFastLength && + xCHMALcFastLength > xCHMAMcSlowLength && + xCHMALcSlowLength > xCHMALcFastLength; + + // + if (!result) + { + // + LogMessage("XCHMA Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XCHMAInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XCHMA Handler ... + ArraySetAsSeries(xCHMALcFastBuffer, true); + ArraySetAsSeries(xCHMALcSlowBuffer, true); + ArraySetAsSeries(xCHMAMcFastBuffer, true); + ArraySetAsSeries(xCHMAMcSlowBuffer, true); + ArraySetAsSeries(xCHMAScFastBuffer, true); + ArraySetAsSeries(xCHMAScSlowBuffer, true); + xCHMAHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xchma.oscillator", + // + // Inputs ... + "", + xCHMADrawHotAreas, + xCHMAHotBullishArrowCode, + xCHMAHotBullishArrowColor, + xCHMAHotBearishArrowCode, + xCHMAHotBearishArrowColor, + // + // Long Cycle ... + "", + "", + xCHMALcFastLength, + xCHMALcSlowLength, + xCHMALcMethod, + xCHMALcAppliedTo, + "", + xCHMALcDrawWidth, + xCHMALcDrawType, + xCHMALcDrawStyle, + xCHMALcFastColor, + xCHMALcSlowColor, + "", + xCHMALcDrawFast, + xCHMALcDrawSlow, + xCHMALcDrawCrosses, + // + // Medium Cycle ... + "", + "", + xCHMAMcFastLength, + xCHMAMcSlowLength, + xCHMAMcMethod, + xCHMAMcAppliedTo, + "", + xCHMAMcDrawWidth, + xCHMAMcDrawType, + xCHMAMcDrawStyle, + xCHMAMcFastColor, + xCHMAMcSlowColor, + "", + xCHMAMcDrawFast, + xCHMAMcDrawSlow, + xCHMAMcDrawCrosses, + // + // Short Cycle ... + "", + "", + xCHMAScFastLength, + xCHMAScSlowLength, + xCHMAScMethod, + xCHMAScAppliedTo, + "", + xCHMAScDrawWidth, + xCHMAScDrawType, + xCHMAScDrawStyle, + xCHMAScFastColor, + xCHMAScSlowColor, + "", + xCHMAScDrawFast, + xCHMAScDrawSlow, + xCHMAScDrawCrosses); + if (xCHMAHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XCHMA Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XCHMAReleaseHandlers() +{ + IndicatorRelease(xCHMAHandler); +} + +// +// Handle Reading Buffers ... +void XCHMAReadBuffers( + int xCHMAItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XCHMA Long Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_LC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMALcSlowBuffer); + + // + // XCHMA Medium Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_MC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAMcSlowBuffer); + + // + // XCHMA Short Cycle ... + // + // XCHMA Fast ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_FAST_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScFastBuffer); + + // + // XCHMA Slow ... + CopyBuffer( + xCHMAHandler, + X_XCHMA_SC_SLOW_LINE, + 0, + xCHMAItemsPerTick, + xCHMAScSlowBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XCHMA Custom Functions ... +// + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMax( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // SC Fast ... + result = MathMax( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMax( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMax( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMax( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMax( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMax( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Retrieve Max Cycles Value ... +double XCHMAGetMin( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if (!XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = xCHMAScFastBuffer[bar_index]; + + // + // SC Fast ... + result = MathMin( + result, + xCHMAScFastBuffer[bar_index]); + + // + // SC Slow ... + result = MathMin( + result, + xCHMAScSlowBuffer[bar_index]); + + // + // MC Fast ... + result = MathMin( + result, + xCHMAMcFastBuffer[bar_index]); + + // + // MC Slow ... + result = MathMin( + result, + xCHMAMcSlowBuffer[bar_index]); + + // + // LC Fast ... + result = MathMin( + result, + xCHMALcFastBuffer[bar_index]); + + // + // LC Slow ... + result = MathMin( + result, + xCHMALcSlowBuffer[bar_index]); + + // + return result; +} + +// +// Short Cycle Over Max Of Cycle Channels ... +bool XCHMAIsSCOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Max Of Cycle Channels ... +bool XCHMAIsSCUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMax1 + // + ; + + // + return result; +} + +// +// Short Cycle Over Min Of Cycle Channels ... +bool XCHMAIsSCOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 > nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Under Min Of Cycle Channels ... +bool XCHMAIsSCUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 < nonOfShortCycleMin1 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Max Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMax1 && + shortCycleMin2 <= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Max Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMax1 = XCHMAGetCyclesMaxValue( + bar_index, + cycles); + double nonOfShortCycleMax2 = XCHMAGetCyclesMaxValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMax1 && + shortCycleMax2 >= nonOfShortCycleMax2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Over Min Of Cycle Channels ... +bool XCHMAIsSCCrossedOverMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMin1 = XCHMAGetCycleMinValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMin2 = XCHMAGetCycleMinValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMin1 > nonOfShortCycleMin1 && + shortCycleMin2 <= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Short Cycle Crossed Under Min Of Cycle Channels ... +bool XCHMAIsSCCrossedUnderMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XCHMAIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double shortCycleMax1 = XCHMAGetCycleMaxValue( + bar_index, + X_XCHMA_CYCLE_SHORT); + double shortCycleMax2 = XCHMAGetCycleMaxValue( + bar_index + 1, + X_XCHMA_CYCLE_SHORT); + + // + ENUM_XCHMA_CYCLES cycles[]; + Add( + X_XCHMA_CYCLE_MEDIUM, + cycles); + Add( + X_XCHMA_CYCLE_LONG, + cycles); + + // + double nonOfShortCycleMin1 = XCHMAGetCyclesMinValue( + bar_index, + cycles); + double nonOfShortCycleMin2 = XCHMAGetCyclesMinValue( + bar_index + 1, + cycles); + + // + // Calculate Result ... + result = + // + shortCycleMax1 < nonOfShortCycleMin1 && + shortCycleMax2 >= nonOfShortCycleMin2 + // + ; + + // + return result; +} + +// +// Long Cycle ... +// + +// +// Check LC is Peak ... +bool XCHMAIsLCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC is Vale ... +bool XCHMAIsLCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMALcSlowBuffer + // + ); + + // + return result; +} + +// +// Check LC Fast Crossed Over Slow ... +bool XCHMAIsLCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Over Slow ... +bool XCHMAIsLCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Crossed Under Slow ... +bool XCHMAIsLCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check LC Fast Under Slow ... +bool XCHMAIsLCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMALcFastBuffer, + xCHMALcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetLCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMALcFastBuffer[bar_index] - xCHMALcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsLCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetLCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetLCTrendPower(i + 1); + double iTrend = XCHMAGetLCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Medium Cycle ... +// + +// +// Check MC is Peak ... +bool XCHMAIsMCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC is Vale ... +bool XCHMAIsMCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAMcSlowBuffer + // + ); + + // + return result; +} + +// +// Check MC Fast Crossed Over Slow ... +bool XCHMAIsMCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Over Slow ... +bool XCHMAIsMCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Crossed Under Slow ... +bool XCHMAIsMCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check MC Fast Under Slow ... +bool XCHMAIsMCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAMcFastBuffer, + xCHMAMcSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get Trend Power ... +double XCHMAGetMCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAMcFastBuffer[bar_index] - xCHMAMcSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check XTM TrendsDown or Up ... +bool XCHMAIsMCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetMCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetMCTrendPower(i + 1); + double iTrend = XCHMAGetMCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Short Cycle ... +// + +// +// Check SC is Peak ... +bool XCHMAIsSCPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XCHMAIsSCVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xCHMAScSlowBuffer + // + ); + + // + return result; +} + +// +// Check SC Fast Crossed Over Slow ... +bool XCHMAIsSCFastCrossedOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Over Slow ... +bool XCHMAIsSCFastOverSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Crossed Under Slow ... +bool XCHMAIsSCFastCrossedUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Check SC Fast Under Slow ... +bool XCHMAIsSCFastUnderSlow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xCHMAScFastBuffer, + xCHMAScSlowBuffer, + bar_index); + + // + return result; +} + +// +// Get SC Trend Power ... +double XCHMAGetSCTrendPower( + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + MathAbs(xCHMAScFastBuffer[bar_index] - xCHMAScSlowBuffer[bar_index]) + // + ; + + // + return result; +} + +// +// Check SC Trends Up ... +bool XCHMAIsSCTrendsUp( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsUpCount > trendsDownCount + // + ; + + // + return result; +} + +// +// Check SC Trends Down ... +bool XCHMAIsSCTrendsDown( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + length + 2)) + { + return result; + } + + // + double trend1 = XCHMAGetSCTrendPower(bar_index); + + // + int trendsUpCount = 0; + int trendsDownCount = 0; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iPrevTrend = XCHMAGetSCTrendPower(i + 1); + double iTrend = XCHMAGetSCTrendPower(i); + + // + if ( + trend1 > iTrend && + iTrend >= iPrevTrend && + trend1 >= iPrevTrend) + { + trendsUpCount++; + } + else if ( + trend1 < iTrend && + iTrend <= iPrevTrend && + trend1 <= iPrevTrend) + { + trendsDownCount++; + } + } + + // + result = + // + trendsDownCount > trendsUpCount + // + ; + + // + return result; +} + +// +// Utility Functions ... +// + +// +// Check a Cycle is Over of Another ... +bool XCHMAIsCycleOverAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMinValue = XCHMAGetCycleMinValue(bar_index, sourceCycle); + double destMaxValue = XCHMAGetCycleMaxValue(bar_index, destCycle); + + // + result = + // + sourceMinValue > destMaxValue + // + ; + + // + return result; +} + +// +// Check a Cycle is Under of Another ... +bool XCHMAIsCycleUnderAnother( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES sourceCycle, // Specified Cycle ... + ENUM_XCHMA_CYCLES destCycle // Specified Cycle ... +) +{ + // + bool result = false; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceMaxValue = XCHMAGetCycleMaxValue(bar_index, sourceCycle); + double destMinValue = XCHMAGetCycleMinValue(bar_index, destCycle); + + // + result = + // + sourceMaxValue < destMinValue + // + ; + + // + return result; +} + +// +// Get Cycle Min Value ... +double XCHMAGetCycleMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMin( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMin( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMin( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Min Value ... +double XCHMAGetCyclesMinValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMinValue( + bar_index, + iCycle); + + // + result = result == 0 || result > iValue ? iValue : result; + } + + // + return result; +} + +// +// Get Cycle Max Value ... +double XCHMAGetCycleMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES cycle // Specified Cycle ... +) +{ + // + double result = 0; + + // + // Validate BufferSize ... + if ( + bar_index <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (cycle) + { + // + case X_XCHMA_CYCLE_LONG: + result = MathMax( + xCHMALcFastBuffer[bar_index], + xCHMALcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_MEDIUM: + result = MathMax( + xCHMAMcFastBuffer[bar_index], + xCHMAMcSlowBuffer[bar_index]); + break; + + // + case X_XCHMA_CYCLE_SHORT: + result = MathMax( + xCHMAScFastBuffer[bar_index], + xCHMAScSlowBuffer[bar_index]); + break; + } + + // + return result; +} + +// +// Get Cycles Max Value ... +double XCHMAGetCyclesMaxValue( + int bar_index, // Specified Index ... + ENUM_XCHMA_CYCLES &cycle[] // Specified Cycles ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + // + bar_index <= 0 || + ArraySize(cycle) <= 0 || + !XCHMAIsValidBuffersSize(bar_index + 1) + // + ) + { + return result; + } + + // + // Loop Through Cycles ... + for (int i = 0; i < ArraySize(cycle); i++) + { + // + ENUM_XCHMA_CYCLES iCycle = cycle[i]; + double iValue = XCHMAGetCycleMaxValue( + bar_index, + iCycle); + + // + result = result == 0 || result < iValue ? iValue : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XCHMAIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xCHMALcFastBuffer) < size || + ArraySize(xCHMALcSlowBuffer) < size || + // + ArraySize(xCHMAMcFastBuffer) < size || + ArraySize(xCHMAMcSlowBuffer) < size || + // + ArraySize(xCHMAScFastBuffer) < size || + ArraySize(xCHMAScSlowBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Add Specified Object to it's correspond Buffer ... +void Add( + ENUM_XCHMA_CYCLES item, + ENUM_XCHMA_CYCLES &buffer[]) +{ + // + ArrayResize( + buffer, + ArraySize(buffer) + 1); + + // + buffer[ArraySize(buffer) - 1] = item; +} + +// +// END XCHMA Custom Functions ... +// diff --git a/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..19d3417c --- /dev/null +++ b/Helpers/x-saherelm.xfi.oscillator.helper.lib.mq5 @@ -0,0 +1,358 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XFI Oscillator"; + +// // +// input int xFILength = 18; // Market Length +// input ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +// input ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// Configurations ... +int xFILength = 18; // Market Length +ENUM_MA_METHOD xFIMethod = MODE_SMA; // MA Method +ENUM_APPLIED_VOLUME xFIAppliedTo = VOLUME_TICK; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xFIHandler = INVALID_HANDLE; +double xFIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XFIValidateInputs() +{ + // + bool result = false; + + // + result = xFILength > 2; + + // + if (!result) + { + // + LogMessage("XFI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XFIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XFI Handler ... + ArraySetAsSeries(xFIBuffer, true); + xFIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xfi.oscillator", + // + // Inputs ... + xFILength, + xFIMethod, + xFIAppliedTo + // + ); + if (xFIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XFI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XFIReleaseHandlers() +{ + IndicatorRelease(xFIHandler); +} + +// +// Handle Reading Buffers ... +void XFIReadBuffers( + int xFIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XFI Signal ... + CopyBuffer( + xFIHandler, + 0, + 0, + xFIItemsPerTick, + xFIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XFI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XFIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XFIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XFIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xFIBuffer + // + ); + + // + return result; +} + +// +// Detect XFI Crossed Over Zero ... +bool XFIIsCrossedOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0 && + xFIBuffer[bar_index + 1] <= 0; + + // + return result; +} + +// +// Detect XFI Over Zero ... +bool XFIIsOverZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] > 0; + + // + return result; +} + +// +// Detect XFI Crossed Under Zero ... +bool XFIIsCrossedUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0 && + xFIBuffer[bar_index + 1] >= 0; + + // + return result; +} + +// +// Detect XFI Under Zero ... +bool XFIIsUnderZero( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XFIIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xFIBuffer[bar_index] < 0; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XFIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xFIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XFI Custom Functions ... +// diff --git a/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 b/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 new file mode 100644 index 00000000..e6a92f65 --- /dev/null +++ b/Helpers/x-saherelm.xlh.indicator.helper.lib.mq5 @@ -0,0 +1,668 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XLH Indicator Buffer Lines ... +enum ENUM_X_XLH_BUFFER_LINES +{ + X_XLH_HH_LINE = 0, + X_XLH_LL_LINE = 1, + X_XLH_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XLH Indicator"; + +// input int xLHLength = 72; // Length +// input ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +// input ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// Configurations ... +int xLHLength = 72; // Length +ENUM_SERIESMODE xLHHHMode = MODE_HIGH; // Highest High Calculation Method +ENUM_SERIESMODE xLHLLMode = MODE_LOW; // Lowest Low Calculation Method + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xLHHandler = INVALID_HANDLE; + +// +double xLHHHBuffer[]; +double xLHLLBuffer[]; +double xLHSignalBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XLHValidateInputs() +{ + // + bool result = false; + + // + result = xLHLength >= 2; + + // + if (!result) + { + // + LogMessage("XLH Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XLHInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XLH Handler ... + ArraySetAsSeries(xLHHHBuffer, true); + ArraySetAsSeries(xLHLLBuffer, true); + ArraySetAsSeries(xLHSignalBuffer, true); + + // + xLHHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xlh.indicator", + // + // Inputs ... + xLHLength, + xLHHHMode, + xLHLLMode + // + ); + if (xLHHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XLH Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XLHReleaseHandlers() +{ + IndicatorRelease(xLHHandler); +} + +// +// Handle Reading Buffers ... +void XLHReadBuffers( + int xLHItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // HH Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_HH_LINE, + 0, + xLHItemsPerTick, + xLHHHBuffer + // + ); + + // + // LL Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_LL_LINE, + 0, + xLHItemsPerTick, + xLHLLBuffer + // + ); + + // + // Signal Buffer ... + CopyBuffer( + xLHHandler, + X_XLH_SIGNAL_LINE, + 0, + xLHItemsPerTick, + xLHSignalBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XLH Custom Functions ... +// + +// +// TODO: What we have to Implement ... +// - [] + +// +// Check Candle High is HH ... +bool XLHIsHighAttachedHH( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.high == xLHHHBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Candle Low is LL ... +bool XLHIsLowAttachedLL( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle = GetCandle(bar_index); + + // + result = + // + candle.low == xLHLLBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Up Signal ... +bool XLHIsPriceCrossedOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] && + candle2.low < xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Over Signal ... +bool XLHIsPriceOverSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.low > xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Jumping Down Signal ... +bool XLHIsPriceCrossedUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + XOHCL candle2 = GetCandle(bar_index + 1); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] && + candle2.high > xLHSignalBuffer[bar_index + 1] + // + ; + + // + return result; +} + +// +// Check Price Down Signal ... +bool XLHIsPriceUnderSignal( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check Price Ranging Signal ... +bool XLHIsPriceInSignalRange( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + XOHCL candle1 = GetCandle(bar_index); + + // + result = + // + candle1.high > xLHSignalBuffer[bar_index] && + candle1.low < xLHSignalBuffer[bar_index] + // + ; + + // + return result; +} + +// +// Check HH Increased ... +bool XLHIsHHIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check HH Decreased ... +bool XLHIsHHDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHHHBuffer + // + ); + + // + return result; +} + +// +// Check LL Increased ... +bool XLHIsLLIncreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsIncreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check LL Decreased ... +bool XLHIsLLDecreased( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xLHLLBuffer + // + ); + + // + return result; +} + +// +// Check HH Same in Length ... +bool XLHIsHHSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHHHBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHHHBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check LL Same in Length ... +bool XLHIsLLSameInLength( + int bar_index, // Specified Index ... + int length = 5 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XLHIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + double value1 = xLHLLBuffer[bar_index]; + + // + // Loop ... + result = true; + for (int i = bar_index + 1; i < bar_index + length + 1; i++) + { + // + double iValue = xLHLLBuffer[i]; + if (iValue != value1) + { + // + result = false; + + // + break; + } + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XLHIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xLHHHBuffer) < size || + ArraySize(xLHLLBuffer) < size || + ArraySize(xLHSignalBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XLH Custom Functions ... +// diff --git a/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 b/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 new file mode 100644 index 00000000..f90f15b2 --- /dev/null +++ b/Helpers/x-saherelm.xobd.indicator.helper.lib.mq5 @@ -0,0 +1,249 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XOBD Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XOBD Indicator"; + +// input int xOBDLength = 5; // Swing Length +// input uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +// input color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +// input uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +// input color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// Configurations ... +int xOBDLength = 5; // Swing Length +uchar xOBDSwingHighArrowCode = 108; // Swing High Arrow Code +color xOBDSwingHighArrowColor = clrMagenta; // Swing High Arrow Color +uchar xOBDSwingLowArrowCode = 108; // Swing Low Arrow Code +color xOBDSwingLowArrowColor = clrAqua; // Swing Low Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +// +int xOBDHandler = INVALID_HANDLE; + +// +double xOBDBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XOBDValidateInputs() +{ + // + bool result = false; + + // + result = xOBDLength >= 2; + + // + if (!result) + { + // + LogMessage("XOBD Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XOBDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XOBD Handler ... + ArraySetAsSeries(xOBDBuffer, true); + + // + xOBDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xobd.indicator", + // + // Inputs ... + xOBDLength, + xOBDSwingHighArrowCode, + xOBDSwingHighArrowColor, + xOBDSwingLowArrowCode, + xOBDSwingLowArrowColor + // + ); + if (xOBDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XOBD Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XOBDReleaseHandlers() +{ + IndicatorRelease(xOBDHandler); +} + +// +// Handle Reading Buffers ... +void XOBDReadBuffers( + int xOBDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // OBD Buffer ... + CopyBuffer( + xOBDHandler, + 0, + 0, + xOBDItemsPerTick, + xOBDBuffer + // + ); +} + +// +// END Handler Funcions ... +// + +// +// START XOBD Custom Functions ... +// + +// +// Check is Swing Low Occured or not ... +bool XOBDIsSwingLow( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_LOW; + + // + return result; +} + +// +// Check is Swing High Occured or not ... +bool XOBDIsSwingHigh( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XOBDIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = xOBDBuffer[bar_index] == X_SWING_HIGH; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XOBDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xOBDBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XOBD Custom Functions ... +// diff --git a/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..e6971b7a --- /dev/null +++ b/Helpers/x-saherelm.xrsi.oscillator.helper.lib.mq5 @@ -0,0 +1,433 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XRSI Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XRSI Oscillator Buffer Lines ... +// + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XRSI Oscillator"; + +// // +// input group "XRSI Market"; +// input int xRSILength = 18; // Market Length +// input ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// // +// input group "XRSI Short Entry"; +// input double xRSIShortEntryValue = 70; // Short Entry Level +// input color xRSIShortEntryColor = clrRed; // Short Entry Level Color +// input ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// // +// input group "XRSI Short Exit"; +// input double xRSIShortExitValue = 40; // Short Exit Level +// input color xRSIShortExitColor = clrRed; // Short Exit Level Color +// input ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// // +// input group "XRSI Long Entry"; +// input double xRSILongEntryValue = 30; // Long Entry Level +// input color xRSILongEntryColor = clrRed; // Long Entry Level Color +// input ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// // +// input group "XRSI Long Exit"; +// input double xRSILongExitValue = 60; // Long Exit Level +// input color xRSILongExitColor = clrRed; // Long Exit Level Color +// input ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// Configurations ... +int xRSILength = 18; // Market Length +ENUM_APPLIED_PRICE xRSIAppliedTo = PRICE_OPEN; // Applied To + +// +double xRSIShortEntryValue = 70; // Short Entry Level +color xRSIShortEntryColor = clrRed; // Short Entry Level Color +ENUM_LINE_STYLE xRSIShortEntryLineStyle = STYLE_SOLID; // Short Entry Style + +// +double xRSIShortExitValue = 40; // Short Exit Level +color xRSIShortExitColor = clrRed; // Short Exit Level Color +ENUM_LINE_STYLE xRSIShortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +double xRSILongEntryValue = 30; // Long Entry Level +color xRSILongEntryColor = clrRed; // Long Entry Level Color +ENUM_LINE_STYLE xRSILongEntryLineStyle = STYLE_SOLID; // Long Entry Style + +// +double xRSILongExitValue = 60; // Long Exit Level +color xRSILongExitColor = clrRed; // Long Exit Level Color +ENUM_LINE_STYLE xRSILongExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xRSIHandler = INVALID_HANDLE; +double xRSIBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XRSIValidateInputs() +{ + // + bool result = false; + + // + result = + xRSILongEntryValue < xRSILongExitValue && + xRSIShortEntryValue > xRSIShortExitValue && + xRSIShortEntryValue > xRSILongExitValue && + xRSIShortExitValue < xRSILongExitValue; + + // + if (!result) + { + // + LogMessage("XRSI Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XRSIInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XRSI Handler ... + ArraySetAsSeries(xRSIBuffer, true); + xRSIHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xrsi.oscillator", + // + // Inputs ... + // + // Market ... + "", + xRSILength, + xRSIAppliedTo, + // + // Short Entry ... + "", + xRSIShortEntryValue, + xRSIShortEntryColor, + xRSIShortEntryLineStyle, + // + // Short Exit ... + "", + xRSIShortExitValue, + xRSIShortExitColor, + xRSIShortExitLineStyle, + // + // Long Entry ... + "", + xRSILongEntryValue, + xRSILongEntryColor, + xRSILongEntryLineStyle, + // + // Long Exit ... + "", + xRSILongExitValue, + xRSILongExitColor, + xRSILongExitLineStyle + // + ); + if (xRSIHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XRSI Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XRSIReleaseHandlers() +{ + IndicatorRelease(xRSIHandler); +} + +// +// Handle Reading Buffers ... +void XRSIReadBuffers( + int xRSIItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XRSI Signal ... + CopyBuffer( + xRSIHandler, + 0, + 0, + xRSIItemsPerTick, + xRSIBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XRSI Custom Functions ... +// + +// +// Check SC is Peak ... +bool XRSIIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// Check SC is Vale ... +bool XRSIIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xRSIBuffer + // + ); + + // + return result; +} + +// +// RSI Value GO Up from Long Entry ... +bool XRSIIsCrossedOverLongEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongEntryValue && + xRSIBuffer[bar_index + 2] <= xRSILongEntryValue; + + // + return result; +} + +// +// RSI Value GO Up from Long Exit ... +bool XRSIIsCrossedOverLongExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] > xRSILongExitValue && + xRSIBuffer[bar_index + 2] <= xRSILongExitValue; + + // + return result; +} + +// +// RSI Value Go Down Short Entry ... +bool XRSIIsCrossedUnderShortEntry( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortEntryValue && + xRSIBuffer[bar_index + 2] >= xRSIShortEntryValue; + + // + return result; +} + +// +// RSI Value Go Down Short Exit ... +bool XRSIIsCrossedUnderShortExit( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XRSIIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + xRSIBuffer[bar_index + 1] < xRSIShortExitValue && + xRSIBuffer[bar_index + 2] >= xRSIShortExitValue; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XRSIIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xRSIBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XRSI Custom Functions ... +// diff --git a/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..6286228b --- /dev/null +++ b/Helpers/x-saherelm.xtd.oscillator.helper.lib.mq5 @@ -0,0 +1,931 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTD Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; + +// +// XTD Oscillator Buffer Lines ... +enum ENUM_X_XTD_BUFFER_LINES +{ + X_XTD_BULLISH_POWER_LINE = 0, + X_XTD_BEARISH_POWER_LINE = 1, + X_XTD_SIGNAL_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTD Oscillator"; + +// input int xTDLength = 18; // Market Length +// input bool xTDDrawCrosses = false; // Draw Cross Arrows +// input uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +// input color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +// input uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +// input color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// Configurations ... +int xTDLength = 18; // Market Length +bool xTDDrawCrosses = false; // Draw Cross Arrows +uchar xTDBullishArrowCode = 228; // Cross Over Arrow Code +color xTDBullishArrowColor = clrAqua; // Cross Over Arrow Color +uchar xTDBearishArrowCode = 230; // Cross Under Arrow Code +color xTDBearishArrowColor = clrMagenta; // Cross Under Arrow Color + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTDHandler = INVALID_HANDLE; +double xTDBullishBuffer[]; +double xTDBearishBuffer[]; +double xTDSignalBuffer[]; +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTDValidateInputs() +{ + // + bool result = false; + + // + result = xTDLength >= 2; + + // + if (!result) + { + // + LogMessage("XTD Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTDInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTD Handler ... + ArraySetAsSeries(xTDBullishBuffer, true); + ArraySetAsSeries(xTDBearishBuffer, true); + ArraySetAsSeries(xTDSignalBuffer, true); + xTDHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtd.oscillator", + // + // Inputs ... + xTDLength, + xTDDrawCrosses, + xTDBullishArrowCode, + xTDBullishArrowColor, + xTDBearishArrowCode, + xTDBearishArrowColor); + if (xTDHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTD Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTDReleaseHandlers() +{ + IndicatorRelease(xTDHandler); +} + +// +// Handle Reading Buffers ... +void XTDReadBuffers( + int xTDItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BULLISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBullishBuffer); + + // + // XTD Bullish Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_BEARISH_POWER_LINE, + 0, + xTDItemsPerTick, + xTDBearishBuffer); + + // + // XTD Signal Buffer ... + CopyBuffer( + xTDHandler, + X_XTD_SIGNAL_LINE, + 0, + xTDItemsPerTick, + xTDSignalBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTD Custom Functions ... +// + +// +// Check Signal Vale ... +bool XTDIsSignalVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsSignalPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDSignalBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBullishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBullishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBullishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Vale ... +bool XTDIsBearishVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... +bool XTDIsBearishPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTDBearishBuffer + // + ); + + // + return result; +} + +// +// Check Signal Peak ... + +// +// Check Bullish Crossed Over Bearish ... +bool XTDIsBullCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Over Bearish ... +bool XTDIsBullOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Crossed Under Bearish ... +bool XTDIsBullCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Bullish Under Bearish ... +bool XTDIsBullUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDBullishBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Over Bearish ... +bool XTDIsSignalCrossedOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Over Bearish ... +bool XTDIsSignalOverBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsOver( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Crossed Under Bearish ... +bool XTDIsSignalCrossedUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsCrossUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check Signal Under Bearish ... +bool XTDIsSignalUnderBear( + int bar_index // Specified Bar Index +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTDIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = IsUnder( + xTDSignalBuffer, + xTDBearishBuffer, + 1); + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTDIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDBullishBuffer) < size || + ArraySize(xTDSignalBuffer) < size) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// Count Signal Crossed Over Bear ... +int XTDCountSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Signal Crossed Under Bear ... +int XTDCountSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Over Bear ... +int XTDCountBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Count Bull Crossed Under Bear ... +int XTDCountBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = 0; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + result++; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Over Bear ... +int XTDFindLastSignalCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Signal Crossed Onder Bear ... +int XTDFindLastSignalCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsSignalCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Over Bear ... +int XTDFindLastBullCrossedOverBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedOverBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// Find Last Bull Crossed Under Bear ... +int XTDFindLastBullCrossedUnderBearIndex( + int bar_index // Specified Bar Index +) +{ + // + int result = -1; + + // + int count = ArraySize(xTDSignalBuffer) - 1; + if ( + bar_index <= 0 || + count <= bar_index + 1) + { + return result; + } + + // + // Loop Through ... + for (int i = bar_index + 1; i < count && result == -1; i++) + { + // + // Check Cross On i Point ... + bool isCrossedOnI = XTDIsBullCrossedUnderBear(i); + if (isCrossedOnI) + { + // + result = i; + break; + } + } + + // + return result; +} + +// +// END XTD Custom Functions ... +// diff --git a/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 b/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 new file mode 100644 index 00000000..a871ed42 --- /dev/null +++ b/Helpers/x-saherelm.xtm.indicator.helper.lib.mq5 @@ -0,0 +1,598 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTM Indicator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; + +// +// XTM Indicator Buffer Lines ... +enum ENUM_X_XTM_BUFFER_LINES +{ + X_XTM_MA_LINE = 0, + X_XTM_MC_COLOR_LINE = 1, + X_XTM_STATE_LINE = 2, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// input group "XTM Indicator"; + +// input int xTMMaPeriod = 18; // Period +// input int xTMMaShift = 0; // Shift +// input ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +// input ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// Configurations ... +int xTMMaPeriod = 18; // Period +int xTMMaShift = 0; // Shift +ENUM_MA_METHOD xTMMaMethod = MODE_EMA; // Method +ENUM_APPLIED_PRICE xTMMaAppliedTo = PRICE_OPEN; // Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTMHandler = INVALID_HANDLE; +double xTMMaBuffer[]; +double xTMStateBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTMValidateInputs() +{ + // + bool result = false; + + // + result = xTMMaPeriod >= 2; + + // + if (!result) + { + // + LogMessage("XTM Indicator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Indicators ... +bool XTMInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Handler ... + ArraySetAsSeries(xTMMaBuffer, true); + ArraySetAsSeries(xTMStateBuffer, true); + xTMHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xtm.indicator", + // + // Inputs ... + xTMMaPeriod, + xTMMaShift, + xTMMaMethod, + xTMMaAppliedTo); + if (xTMHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTM Indicator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XTMReleaseHandlers() +{ + IndicatorRelease(xTMHandler); +} + +// +// Handle Reading Buffers ... +void XTMReadBuffers( + int xTMItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // Ma Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_MA_LINE, + 0, + xTMItemsPerTick, + xTMMaBuffer); + + // + // State Buffer ... + CopyBuffer( + xTMHandler, + X_XTM_STATE_LINE, + 0, + xTMItemsPerTick, + xTMStateBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTM Custom Functions ... +// + +// +// Find Peak based On this Indicator ... +bool XTMIsPeak( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + // Must Decreasing ... + bool isIncreasing = IsIncreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Find Vale based On this Indicator ... +bool XTMIsVale( + int bar_index, // Specified Index ... + int length = 10 // Specified Length ... +) +{ + // + bool result = false; + + // + if ( + length <= 0 || + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + length + 1)) + { + return result; + } + + // + result = IsDecreasing( + bar_index + length, + bar_index, + xTMMaBuffer + // + ); + + // + return result; +} + +// +// Check TM Crossed Up ... +bool XTMIsStartBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Up After Neutural State ... +bool XTMIsStartBullishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Up State ... +bool XTMIsBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State ... +bool XTMIsEndBullish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BULLISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Ends Up State By Neutural ... +bool XTMIsEndBullishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BULLISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down ... +bool XTMIsStartBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] != X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Crossed Down After Neutural State ... +bool XTMIsStartBearishAfterNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check TM In Down State ... +bool XTMIsBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State ... +bool XTMIsEndBearish( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] != X_XTM_BEARISH && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM Ends Down State By Neutural ... +bool XTMIsEndBearishByNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL && + xTMStateBuffer[bar_index + 1] == X_XTM_BEARISH + // + ; + + // + return result; +} + +// +// Check TM In Neutural State ... +bool XTMIsNeutural( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + if ( + bar_index <= 0 || + !XTMIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + // + xTMStateBuffer[bar_index] == X_XTM_NEUTURAL + // + ; + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTMIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTMMaBuffer) < size || + ArraySize(xTMStateBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +// END XTM Custom Functions ... +// diff --git a/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 b/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 new file mode 100644 index 00000000..875eec08 --- /dev/null +++ b/Helpers/x-saherelm.xts.oscillator.helper.lib.mq5 @@ -0,0 +1,1179 @@ +///////////////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator Helper for Signal Providers +// -------------------------------------------------------------------------- +// +// 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 + +// +// Includes ... +#include "../Libraries/x-saherelm.log.lib.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Enum Definitions ... +// + +// +// Methods to Calculate TimeFrames ... +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// Buffer Lines ... +enum ENUM_X_XTS_BUFFER_LINES +{ + X_XTS_CURRENT_LINE = 0, + X_XTS_NEAREST_LINE = 1, + X_XTS_MEDIEST_LINE = 2, + X_XTS_FAREST_LINE = 3, +}; + +// +// Periods ... +enum ENUM_X_XTS_PERIODS +{ + // + // Current Period ... + X_XTS_PERIOD_CURRENT, + // + // Nearest Period ... + X_XTS_PERIOD_NEAREST, + // + // Mediest Period ... + X_XTS_PERIOD_MEDIEST, + // + // Farest Period ... + X_XTS_PERIOD_FAREST, +}; + +// +// END Enum Definitions ... +// + +// +// START Inputs ... +// + +// // +// input group "XTS Oscillator"; + +// // +// input group "XTS Current Period"; +// input ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// // +// input group "XTS Nearest Period"; +// input ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +// input ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +// input ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// // +// input group "XTS Mediest Period"; +// input ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +// input ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +// input ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// // +// input group "XTS Farest Period"; +// input ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +// input ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +// input ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Configurations ... +ENUM_APPLIED_PRICE xTSCurrentAppliedTo = PRICE_CLOSE; // Current Applied To +// +ENUM_X_PERIOD_METHOD xTSNearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +ENUM_TIMEFRAMES xTSNearestPeriod = NULL; // Nearest Time Frame +ENUM_APPLIED_PRICE xTSNearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +ENUM_X_PERIOD_METHOD xTSMediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +ENUM_TIMEFRAMES xTSMediestPeriod = NULL; // Mediest Time Frame +ENUM_APPLIED_PRICE xTSMediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +ENUM_X_PERIOD_METHOD xTSFarestMethod = X_PERIOD_AUTO; // How to Find Farest Period +ENUM_TIMEFRAMES xTSFarestPeriod = NULL; // Farest Time Frame +ENUM_APPLIED_PRICE xTSFarestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// END Inputs ... +// + +// +// START Definitions ... +// + +int xTSHandler = INVALID_HANDLE; +double xTSCurrentBuffer[]; +double xTSNearestBuffer[]; +double xTSMediestBuffer[]; +double xTSFarestBuffer[]; + +// +// END Definitions ... +// + +// +// START Handler Functions ... +// + +// +// Validate Inputs ... +bool XTSValidateInputs() +{ + // + bool result = false; + + // + result = true; + + // + if (!result) + { + // + LogMessage("XTS Oscillator Inputs Validation Failed ..."); + } + + // + return result; +} + +// +// Init Oscillators ... +bool XTSInitHandlers() +{ + // + bool result = false; + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTS Handler ... + ArraySetAsSeries(xTSCurrentBuffer, true); + ArraySetAsSeries(xTSNearestBuffer, true); + ArraySetAsSeries(xTSMediestBuffer, true); + ArraySetAsSeries(xTSFarestBuffer, true); + xTSHandler = iCustom( + _Symbol, + _Period, + "x-saherelm.xts.oscillator", + // + // Inputs ... + "", + xTSCurrentAppliedTo, + "", + xTSNearestMethod, + xTSNearestPeriod, + xTSNearestAppliedTo, + "", + xTSMediestMethod, + xTSMediestPeriod, + xTSMediestAppliedTo, + "", + xTSFarestMethod, + xTSFarestPeriod, + xTSFarestAppliedTo + // + ); + if (xTSHandler == INVALID_HANDLE) + { + // + LogMessage("failed to Initialize XTS Oscillator: " + (string)GetLastError()); + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Oscillators ... +void XTSReleaseHandlers() +{ + IndicatorRelease(xTSHandler); +} + +// +// Handle Reading Buffers ... +void XTSReadBuffers( + int xTSItemsPerTick // Number Of Reading Buffer Items Per Tick +) +{ + // + // XTS Current ... + CopyBuffer( + xTSHandler, + X_XTS_CURRENT_LINE, + 0, + xTSItemsPerTick, + xTSCurrentBuffer); + + // + // XTS Nearest ... + CopyBuffer( + xTSHandler, + X_XTS_NEAREST_LINE, + 0, + xTSItemsPerTick, + xTSNearestBuffer); + + // + // XTS Mediest ... + CopyBuffer( + xTSHandler, + X_XTS_MEDIEST_LINE, + 0, + xTSItemsPerTick, + xTSMediestBuffer); + + // + // XTS Farest ... + CopyBuffer( + xTSHandler, + X_XTS_FAREST_LINE, + 0, + xTSItemsPerTick, + xTSFarestBuffer); +} + +// +// END Handler Funcions ... +// + +// +// START XTS Custom Functions ... +// + +// +// Calculate Min Value ... +double XTSGetMinValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMinValue( + periods, + bar_index); + + // + return result; +} + +// +// Calculate Max Value ... +double XTSGetMaxValue( + int bar_index // Specified Index ... +) +{ + // + ENUM_X_XTS_PERIODS periods[]; + XTSGetAllPeriodsEnum(periods); + + // + double result = XTSGetPeriodsMaxValue( + periods, + bar_index); + + // + return result; +} + +// +// Check if all Periods Values are Same ... +bool XTSIsAllSame( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + result = + xTSCurrentBuffer[bar_index] == xTSNearestBuffer[bar_index] && + xTSNearestBuffer[bar_index] == xTSMediestBuffer[bar_index] && + xTSMediestBuffer[bar_index] == xTSFarestBuffer[bar_index]; + + // + return result; +} + +// +// Current ... + +// +// Check Current Buffer is Min Or Not ... +bool XTSIsCurrentMin( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double minValue = XTSGetMinValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == minValue; + + // + return result; +} + +// +// Check Current Buffer is Max Or Not ... +bool XTSIsCurrentMax( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double maxValue = XTSGetMaxValue(bar_index); + + // + result = + xTSCurrentBuffer[bar_index] == maxValue; + + // + return result; +} + +// +// Current VS Nearest ... + +// +// Check Current Crossed Over Nearest ... +bool XTSIsCurrentCrossedOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Nearest ... +bool XTSIsCurrentOverNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Nearest ... +bool XTSIsCurrentCrossedUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Nearest ... +bool XTSIsCurrentUnderNearest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_NEAREST, + bar_index); + + // + return result; +} + +// +// Current VS Mediest ... + +// +// Check Current Crossed Over Mediest ... +bool XTSIsCurrentCrossedOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Over Mediest ... +bool XTSIsCurrentOverMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Mediest ... +bool XTSIsCurrentCrossedUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Check Current Under Mediest ... +bool XTSIsCurrentUnderMediest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_MEDIEST, + bar_index); + + // + return result; +} + +// +// Current VS Farest ... + +// +// Check Current Crossed Over Farest ... +bool XTSIsCurrentCrossedOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Over Farest ... +bool XTSIsCurrentOverFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodOverAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Crossed Under Farest ... +bool XTSIsCurrentCrossedUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodCrossedUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Check Current Under Farest ... +bool XTSIsCurrentUnderFarest( + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + result = XTSIsPeriodUnderAnother( + X_XTS_PERIOD_CURRENT, + X_XTS_PERIOD_FAREST, + bar_index); + + // + return result; +} + +// +// Globally Custom Functions ... + +// +// Check a Period Crossed Over another one ... +bool XTSIsPeriodCrossedOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue > destValue && + sourceValue1 <= destValue1; + + // + return result; +} + +// +// Check a Period Over another one ... +bool XTSIsPeriodOverAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue > destValue; + + // + return result; +} + +// +// Check a Period Crossed Under another one ... +bool XTSIsPeriodCrossedUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 2)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + double sourceValue1 = XTSGetPeriodValue( + source, + bar_index + 1); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + double destValue1 = XTSGetPeriodValue( + dest, + bar_index + 1); + + // + result = + sourceValue < destValue && + sourceValue1 >= destValue1; + + // + return result; +} + +// +// Check a Period Under another one ... +bool XTSIsPeriodUnderAnother( + ENUM_X_XTS_PERIODS source, // Specified Source Period which Check it's Crossed ... + ENUM_X_XTS_PERIODS dest, // Specified Dest Period Which used to Check Source Crosses ... + int bar_index // Specified Index ... +) +{ + // + bool result = false; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + double sourceValue = XTSGetPeriodValue( + source, + bar_index); + + // + double destValue = XTSGetPeriodValue( + dest, + bar_index); + + // + result = + sourceValue < destValue; + + // + return result; +} + +// +// Retrieve Specific Period's Value from Buffer for Specific Bar Index ... +double XTSGetPeriodValue( + ENUM_X_XTS_PERIODS period, // Specified Period to read it's Value ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + // Validate Args ... + if ( + bar_index < 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + switch (period) + { + // + case X_XTS_PERIOD_CURRENT: + result = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + result = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + result = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + result = xTSFarestBuffer[bar_index]; + break; + } + + // + return result; +} + +// +// Fill All Exists Periods ... +void XTSGetAllPeriodsEnum( + ENUM_X_XTS_PERIODS &result[] // Hold's Result ... +) +{ + // + CleanBuffer(result); + + // + Add( + X_XTS_PERIOD_CURRENT, + result); + + // + Add( + X_XTS_PERIOD_NEAREST, + result); + + // + Add( + X_XTS_PERIOD_MEDIEST, + result); + + // + Add( + X_XTS_PERIOD_FAREST, + result); +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS exception // Excepted Period ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + if (iPeriod != exception) + { + Add( + iPeriod, + result); + } + } +} + +// +// Fill All Exists Periods Except ... +void XTSGetAllPeriodsEnumExcept( + ENUM_X_XTS_PERIODS &result[], // Hold's Result ... + ENUM_X_XTS_PERIODS &exceptions[] // Excepted Periods ... +) +{ + // + CleanBuffer(result); + + // + ENUM_X_XTS_PERIODS allPeriods[]; + XTSGetAllPeriodsEnum(allPeriods); + int periodsCount = ArraySize(allPeriods); + if (periodsCount <= 0) + { + return; + } + + // + int exceptionsCount = ArraySize(exceptions); + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = allPeriods[i]; + + // + bool canAddIPeriod = false; + if (exceptionsCount <= 0) + { + canAddIPeriod = true; + } + else + { + // + // Loop through Exceptions ... + for (int j = 0; j < exceptionsCount; j++) + { + // + ENUM_X_XTS_PERIODS jException = exceptions[j]; + + // + if (iPeriod == jException) + { + // + canAddIPeriod = false; + break; + } + + // + canAddIPeriod = true; + } + } + + // + if (canAddIPeriod) + { + // + Add( + iPeriod, + result); + } + } +} + +// +// Calculate Periods Min Value ... +double XTSGetPeriodsMinValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result > iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Calculate Periods Max Value ... +double XTSGetPeriodsMaxValue( + ENUM_X_XTS_PERIODS &periods[], // Specified Periods ... + int bar_index // Specified Index ... +) +{ + // + double result = 0; + + // + int periodsCount = ArraySize(periods); + + // + // Validate Args ... + if ( + bar_index < 0 || + periodsCount <= 0 || + !XTSIsValidBuffersSize(bar_index + 1)) + { + return result; + } + + // + // Loop ... + for (int i = 0; i < periodsCount; i++) + { + // + ENUM_X_XTS_PERIODS iPeriod = periods[i]; + + // + double iValue = 0; + + // + switch (iPeriod) + { + // + case X_XTS_PERIOD_CURRENT: + iValue = xTSCurrentBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_NEAREST: + iValue = xTSNearestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_MEDIEST: + iValue = xTSMediestBuffer[bar_index]; + break; + + // + case X_XTS_PERIOD_FAREST: + iValue = xTSFarestBuffer[bar_index]; + break; + } + + // + // Compare iValue to result ... + result = + result == 0 || + result < iValue + ? iValue + : result; + } + + // + return result; +} + +// +// Check all Buffers has valid Size ... +bool XTSIsValidBuffersSize( + int size // the size of buffers which min size for requirements +) +{ + // + bool result = false; + + // + if ( + size <= 0 || + // + ArraySize(xTSCurrentBuffer) < size + // + ) + { + result = false; + } + else + { + result = true; + } + + // + return result; +} + +// +void Add( + ENUM_X_XTS_PERIODS item, // Specified Item ... + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + int bufferSize = ArraySize(buffer); + + // + ArrayResize( + buffer, + bufferSize + 1); + + // + buffer[bufferSize] = item; +} + +void CleanBuffer( + ENUM_X_XTS_PERIODS &buffer[] // Specified Buffer ... +) +{ + // + ArrayFree(buffer); + ArrayResize(buffer, 0); +} + +// +// END XTS Custom Functions ... +// diff --git a/Indicators/x-saherelm.xama.indicator.mq5 b/Indicators/x-saherelm.xama.indicator.mq5 new file mode 100644 index 00000000..14d1ef70 --- /dev/null +++ b/Indicators/x-saherelm.xama.indicator.mq5 @@ -0,0 +1,353 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAMA Indicator +// --------------------------------------------- +// Name: XAMA +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XAMA Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XAMA" + +// +// XAMA Indicator States ... +enum ENUM_X_XAMA_STATES +{ + X_XAMA_BULLISH = 1, + X_XAMA_BEARISH = -1, + X_XAMA_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Period +input int fastEMA = 2; // Fast EMA Period +input int slowEMA = 30; // Slow EMA Period +input int maShift = 0; // Shift +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XAMA" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iAMA( + _Symbol, + _Period, + length, + fastEMA, + slowEMA, + maShift, + appliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(maHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(fastEMA, slowEMA); + maxLength = MathMax(maxLength, length); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XAMA " + "(" + (string)length + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", length, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XAMA_BULLISH : lineColorIndex == 2 ? X_XAMA_BEARISH + : X_XAMA_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xchlh.oscillator.mq5 b/Indicators/x-saherelm.xchlh.oscillator.mq5 new file mode 100644 index 00000000..5c74787c --- /dev/null +++ b/Indicators/x-saherelm.xchlh.oscillator.mq5 @@ -0,0 +1,753 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel LH Oscillator +// --------------------------------------------------- +// Name: XCHLH +// Description: detecting HH and LL based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHLH Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHLH" + +// +// XCHLH Hot States ... +enum ENUM_X_XCHLH_HOT_STATES +{ + X_XCHLH_HOT_HH = 1, + X_XCHLH_NEUTURAL = 0, + X_XCHLH_HOT_LL = -1, +}; + +// +// Including Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotHHArrowCode = 234; // Hot HH Arrow Code +input color hotHHArrowColor = clrAqua; // Hot HH Arrow Color +input uchar hotLLArrowCode = 233; // Hot LL Arrow Code +input color hotLLArrowColor = clrFuchsia; // Hot LL Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcLength = 28; // Length +input double lcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE lcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE lcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcHHColor = clrAqua; // Highest High Color +input color lcLLColor = clrFuchsia; // Lowest Low Color +input group "LC Drawings"; +input bool lcDrawHH = true; // Draw Highest High +input bool lcDrawLL = true; // Draw Lowest Low + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcLength = 14; // Length +input double mcThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE mcHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE mcLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcHHColor = clrLime; // Highest High Color +input color mcLLColor = clrRed; // Lowest Low Color +input group "MC Drawings"; +input bool mcDrawHH = true; // Draw Highest High +input bool mcDrawLL = true; // Draw Lowest Low + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scLength = 7; // Length +input double scThresholdInPips = 0.3; // Threshold In Pips +input ENUM_SERIESMODE scHHMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE scLLMode = MODE_LOW; // Lowest Low Calculation Method +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_DOT; // Draw Style +input color scHHColor = clrLightBlue; // Highest High Color +input color scLLColor = clrLightSalmon; // Lowest Low Color +input group "SC Drawings"; +input bool scDrawHH = true; // Draw Highest High +input bool scDrawLL = true; // Draw Lowest Low +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcHHBufferIndex 0 +#define lcLLBufferIndex 1 + +// +double lcHHBuffer[]; +double lcLLBuffer[]; + +// +// MC ... +#define mcHHBufferIndex 2 +#define mcLLBufferIndex 3 + +// +double mcHHBuffer[]; +double mcLLBuffer[]; + +// +// SC ... +#define scHHBufferIndex 4 +#define scLLBufferIndex 5 + +// +double scHHBuffer[]; +double scLLBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcLength, mcLength); + maxLength = MathMax(maxLength, scLength); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = + lcLength >= 4 && + lcLength > mcLength && + lcLength > scLength; + bool isMCInputsValid = + mcLength >= 4 && + mcLength > scLength && + mcLength < lcLength; + bool isSCInputsValid = + scLength >= 4 && + scLength < mcLength && + scLength < lcLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + LCCalculateBuffers(bar_index); + + // + // MC ... + MCCalculateBuffers(bar_index); + + // + // SC ... + SCCalculateBuffers(bar_index); + + // + // SIGNAL ... + SignalCalculateBuffers(bar_index); + + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC HH Buffer ... + string lcHHBufferLabel = ShortName + " LC HH (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcHHDrawType = lcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcHHBufferIndex, PLOT_LABEL, lcHHBufferLabel); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_COLOR, lcHHColor); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcHHBufferIndex, PLOT_DRAW_TYPE, lcHHDrawType); + + // + // LC LL Buffer ... + string lcLLBufferLabel = ShortName + " LC LL (" + (string)lcLength + ")"; + ENUM_DRAW_TYPE lcLLDrawType = lcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_BEGIN, lcLength); + PlotIndexSetString(lcLLBufferIndex, PLOT_LABEL, lcLLBufferLabel); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_COLOR, lcLLColor); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcLLBufferIndex, PLOT_DRAW_TYPE, lcLLDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC HH Buffer ... + string mcHHBufferLabel = ShortName + " MC HH (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcHHDrawType = mcDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcHHBufferIndex, PLOT_LABEL, mcHHBufferLabel); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_COLOR, mcHHColor); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcHHBufferIndex, PLOT_DRAW_TYPE, mcHHDrawType); + + // + // MC LL Buffer ... + string mcLLBufferLabel = ShortName + " MC LL (" + (string)mcLength + ")"; + ENUM_DRAW_TYPE mcLLDrawType = mcDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_BEGIN, mcLength); + PlotIndexSetString(mcLLBufferIndex, PLOT_LABEL, mcLLBufferLabel); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_COLOR, mcLLColor); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcLLBufferIndex, PLOT_DRAW_TYPE, mcLLDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC HH Buffer ... + string scHHBufferLabel = ShortName + " SC HH (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scHHDrawType = scDrawHH ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scHHBufferIndex, PLOT_LABEL, scHHBufferLabel); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_COLOR, scHHColor); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scHHBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scHHBufferIndex, PLOT_DRAW_TYPE, scHHDrawType); + + // + // SC LL Buffer ... + string scLLBufferLabel = ShortName + " SC LL (" + (string)scLength + ")"; + ENUM_DRAW_TYPE scLLDrawType = scDrawLL ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_BEGIN, scLength); + PlotIndexSetString(scLLBufferIndex, PLOT_LABEL, scLLBufferLabel); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_COLOR, scLLColor); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scLLBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scLLBufferIndex, PLOT_DRAW_TYPE, scLLDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Calculations ... +void LCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = lcLength; + ENUM_SERIESMODE hhMode = lcHHMode; + ENUM_SERIESMODE llMode = lcLLMode; + double threshold = PipsToPrice(lcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + lcHHBuffer[bar_index] = hhValue; + lcLLBuffer[bar_index] = llValue; +} + +// +// MC Calculations ... +void MCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = mcLength; + ENUM_SERIESMODE hhMode = mcHHMode; + ENUM_SERIESMODE llMode = mcLLMode; + double threshold = PipsToPrice(mcThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + mcHHBuffer[bar_index] = hhValue; + mcLLBuffer[bar_index] = llValue; +} + +// +// SC Calculations ... +void SCCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // Detect Cycle HH and LL ... + int length = scLength; + ENUM_SERIESMODE hhMode = scHHMode; + ENUM_SERIESMODE llMode = scLLMode; + double threshold = PipsToPrice(scThresholdInPips); + double hh = GetHighestHigh( + length, + bar_index, + hhMode); + double hhValue = hh + threshold; + double ll = GetLowestLow( + length, + bar_index, + llMode); + double llValue = ll - threshold; + + // + scHHBuffer[bar_index] = hhValue; + scLLBuffer[bar_index] = llValue; +} + +// +// SIGNAL Calculations ... +void SignalCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC Values ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + double lcDelta = lcHH - lcLL; + double lcAvg = lcDelta / 2; + + // + // MC Values ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + double mcDelta = mcHH - mcLL; + double mcAvg = mcDelta / 2; + + // + // SC Values ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + double scDelta = scHH - scLL; + double scAvg = scDelta / 2; + + // + // Min Value ... + double minValue = MathMin( + scLL, mcLL); + minValue = MathMin( + lcLL, minValue); + + // + // Max Value ... + double maxValue = MathMin( + scHH, mcHH); + maxValue = MathMin( + lcHH, maxValue); +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcHH = lcHHBuffer[bar_index]; + double lcLL = lcLLBuffer[bar_index]; + // + double lcHH1 = lcHHBuffer[bar_index + 1]; + double lcLL1 = lcLLBuffer[bar_index + 1]; + + // + // MC ... + double mcHH = mcHHBuffer[bar_index]; + double mcLL = mcLLBuffer[bar_index]; + // + double mcHH1 = mcHHBuffer[bar_index + 1]; + double mcLL1 = mcLLBuffer[bar_index + 1]; + + // + // SC ... + double scHH = scHHBuffer[bar_index]; + double scLL = scLLBuffer[bar_index]; + // + double scHH1 = scHHBuffer[bar_index + 1]; + double scLL1 = scLLBuffer[bar_index + 1]; + + // + bool isHotLLState = scLL == mcLL && mcLL == lcLL; + bool isHotLLState1 = scLL1 == mcLL1 && mcLL1 == lcLL1; + // + bool isHotHHState = scHH == mcHH && mcHH == lcHH; + bool isHotHHState1 = scHH1 == mcHH1 && mcHH1 == lcHH1; + + // + bool isHotLL = isHotLLState && !isHotLLState1; + bool isHotHH = isHotHHState && !isHotHHState1; + + // + double hotStateValue = X_XCHLH_NEUTURAL; + if (isHotHH) + { + hotStateValue = X_XCHLH_HOT_HH; + } + else if (isHotLL) + { + hotStateValue = X_XCHLH_HOT_LL; + } + + // + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotHHArea = hotStateValue == 1; + bool isHotLLArea = hotStateValue == -1; + if (isHotHHArea || isHotLLArea) + { + // + bool isHH = isHotHHArea; + + // + double price = isHH ? candle.high : candle.low; + ENUM_ARROW_ANCHOR anchor = isHH ? ANCHOR_BOTTOM : ANCHOR_TOP; + color clr = isHH ? hotHHArrowColor : hotLLArrowColor; + uchar arrowCode = isHH ? hotHHArrowCode : hotLLArrowCode; + string name = "HOT " + (isHH ? "HH" : "LL") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr, + STYLE_SOLID, + 1); + } + } +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xchma.oscillator.mq5 b/Indicators/x-saherelm.xchma.oscillator.mq5 new file mode 100644 index 00000000..12d6c691 --- /dev/null +++ b/Indicators/x-saherelm.xchma.oscillator.mq5 @@ -0,0 +1,1153 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Cycle Channel Moving Averages Oscillator +// ---------------------------------------------------------------- +// Name: XCHMA +// Description: trend detecting based on cycles ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCHMA Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCHMA" + +// +// XCHMA Oscillator Cycles State Presentation ... +enum ENUM_XCHMA_CYCLE_STATES +{ + X_XCHMA_FAST_CROSSED_OVER_SLOW = 2, + X_XCHMA_FAST_OVER_SLOW = 1, + X_XCHMA_NEUTURAL = 0, + X_XCHMA_FAST_UNDER_SLOW = -1, + X_XCHMA_FAST_CROSSED_UNDER_SLOW = -2, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +// +// Common ... +input group "Hot Areas"; +input bool drawHotAreas = true; // Draw Hot Areas Symbol +input uchar hotBullishArrowCode = 228; // Hot Bullish Arrow Code +input color hotBullishArrowColor = clrAqua; // Hot Bullish Arrow Color +input uchar hotBearishArrowCode = 230; // Hot Bearish Arrow Code +input color hotBearishArrowColor = clrFuchsia; // Hot Bearish Arrow Color + +// +// LC Inputs ... +input group "Long Cycle"; +input group "LC Market"; +input int lcFastLength = 20; // Fast Length +input int lcSlowLength = 50; // Slow Length +input ENUM_MA_METHOD lcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE lcAppliedTo = PRICE_CLOSE; // Applied To +input group "LC Style"; +input int lcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE lcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE lcDrawStyle = STYLE_DOT; // Draw Style +input color lcFastColor = clrAqua; // Fast Color +input color lcSlowColor = clrFuchsia; // Slow Color +input group "LC Drawings"; +input bool lcDrawFast = true; // Draw Fast +input bool lcDrawSlow = true; // Draw Slow +input bool lcDrawCrosses = true; // Draw Cross Lines + +// +// MC Inputs ... +input group "Medium Cycle"; +input group "MC Market"; +input int mcFastLength = 10; // Fast Length +input int mcSlowLength = 30; // Slow Length +input ENUM_MA_METHOD mcMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE mcAppliedTo = PRICE_CLOSE; // Applied To +input group "MC Style"; +input int mcDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE mcDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE mcDrawStyle = STYLE_DOT; // Draw Style +input color mcFastColor = clrLime; // Fast Color +input color mcSlowColor = clrRed; // Slow Color +input group "MC Drawings"; +input bool mcDrawFast = true; // Draw Fast +input bool mcDrawSlow = true; // Draw Slow +input bool mcDrawCrosses = false; // Draw Cross Lines + +// +// SC Inputs ... +input group "Short Cycle"; +input group "SC Market"; +input int scFastLength = 7; // Fast Length +input int scSlowLength = 14; // Slow Length +input ENUM_MA_METHOD scMethod = MODE_EMA; // Calculation Method +input ENUM_APPLIED_PRICE scAppliedTo = PRICE_CLOSE; // Applied To +input group "SC Style"; +input int scDrawWidth = 1; // Draw Width +input ENUM_DRAW_TYPE scDrawType = DRAW_LINE; // Draw Type +input ENUM_LINE_STYLE scDrawStyle = STYLE_SOLID; // Draw Style +input color scFastColor = clrLightBlue; // Fast Color +input color scSlowColor = clrLightSalmon; // Slow Color +input group "SC Drawings"; +input bool scDrawFast = true; // Draw Fast +input bool scDrawSlow = true; // Draw Slow +input bool scDrawCrosses = false; // Draw Cross Lines +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 7 +#property indicator_plots 6 + +// +// LC ... +#define lcFastBufferIndex 0 +#define lcSlowBufferIndex 1 + +// +double lcFastBuffer[]; +double lcSlowBuffer[]; + +// +// MC ... +#define mcFastBufferIndex 2 +#define mcSlowBufferIndex 3 + +// +double mcFastBuffer[]; +double mcSlowBuffer[]; + +// +// SC ... +#define scFastBufferIndex 4 +#define scSlowBufferIndex 5 + +// +double scFastBuffer[]; +double scSlowBuffer[]; + +// +// Hot State ... +// +#define hotStateBufferIndex 6 + +// +double hotStateBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// LC ... +int lcFastHandler = INVALID_HANDLE; +int lcSlowHandler = INVALID_HANDLE; + +// +// MC ... +int mcFastHandler = INVALID_HANDLE; +int mcSlowHandler = INVALID_HANDLE; + +// +// SC ... +int scFastHandler = INVALID_HANDLE; +int scSlowHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init All Required Handlers ... + if (!InitHandlers()) + { + return INIT_FAILED; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // ReDraw Chart ... + ChartRedraw(); + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(lcFastLength, lcSlowLength); + + // + // Get Retrieved Values from indicators ... + // + // LC ... + int lcFastCalculatedBars = BarsCalculated(lcFastHandler); + int lcSlowCalculatedBars = BarsCalculated(lcSlowHandler); + + // + // MC ... + int mcFastCalculatedBars = BarsCalculated(mcFastHandler); + int mcSlowCalculatedBars = BarsCalculated(mcSlowHandler); + + // + // SC ... + int scFastCalculatedBars = BarsCalculated(scFastHandler); + int scSlowCalculatedBars = BarsCalculated(scSlowHandler); + + // + // Check Calculated Bars ... + if ( + // + // LC ... + lcFastCalculatedBars < maxLength || + lcSlowCalculatedBars < maxLength || + // + // MC ... + mcFastCalculatedBars < maxLength || + mcSlowCalculatedBars < maxLength || + // + // SC ... + scFastCalculatedBars < maxLength || + scSlowCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Copy Buffers from indicators ... + // + // LC ... + int lcFastCopiedItems = CopyBuffer(lcFastHandler, 0, 0, limit + 1, lcFastBuffer); + int lcSlowCopiedItems = CopyBuffer(lcSlowHandler, 0, 0, limit + 1, lcSlowBuffer); + + // + // MC ... + int mcFastCopiedItems = CopyBuffer(mcFastHandler, 0, 0, limit + 1, mcFastBuffer); + int mcSlowCopiedItems = CopyBuffer(mcSlowHandler, 0, 0, limit + 1, mcSlowBuffer); + + // + // SC ... + int scFastCopiedItems = CopyBuffer(scFastHandler, 0, 0, limit + 1, scFastBuffer); + int scSlowCopiedItems = CopyBuffer(scSlowHandler, 0, 0, limit + 1, scSlowBuffer); + + // + // Check Copied Items Number ... + if ( + // + // LC ... + lcFastCopiedItems <= 0 || + lcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0 || + // + // MC ... + mcFastCopiedItems <= 0 || + mcSlowCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + bool isLCInputsValid = lcFastLength >= 4 && lcSlowLength > lcFastLength; + bool isMCInputsValid = mcFastLength >= 4 && mcSlowLength > mcFastLength; + bool isSCInputsValid = scFastLength >= 4 && scSlowLength > scFastLength; + if ( + isLCInputsValid && + isMCInputsValid && + isSCInputsValid && + lcFastLength > mcFastLength && + mcFastLength > scFastLength) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // LC ... + LCDefineBuffers(); + + // + // MC ... + MCDefineBuffers(); + + // + // SC ... + SCDefineBuffers(); + + // + // Hot State Buffer ... + HotStateDefineBuffers(); +} + +// +// Init Handlers ... +bool InitHandlers() +{ + // + bool result = false; + + // + // LC ... + result = LCInitHandlers(); + if (!result) + { + return result; + } + + // + // MC ... + result = MCInitHandlers(); + if (!result) + { + return result; + } + + // + // SC ... + result = SCInitHandlers(); + if (!result) + { + return result; + } + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // HOT State Buffer ... + HotStateCalculateBuffers(bar_index); + + // + // After all Calculations we are ready to Draw what we want ... + DrawBuffers(bar_index); +} + +// +// LC Buffers Definitions ... +void LCDefineBuffers() +{ + // + // LC Fast Buffer ... + string lcFastBufferLabel = ShortName + " LC Fast (" + (string)lcFastLength + ")"; + ENUM_DRAW_TYPE lcFastDrawType = lcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcFastBuffer, true); + SetIndexBuffer(lcFastBufferIndex, lcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(lcFastBufferIndex, PLOT_LABEL, lcFastBufferLabel); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_COLOR, lcFastColor); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_BEGIN, lcFastLength); + PlotIndexSetInteger(lcFastBufferIndex, PLOT_DRAW_TYPE, lcFastDrawType); + + // + // LC Slow Buffer ... + string lcSlowBufferLabel = ShortName + " LC Slow (" + (string)lcSlowLength + ")"; + ENUM_DRAW_TYPE lcSlowDrawType = lcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(lcSlowBuffer, true); + SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(lcSlowBufferIndex, PLOT_LABEL, lcSlowBufferLabel); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_COLOR, lcSlowColor); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_STYLE, lcDrawStyle); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_LINE_WIDTH, lcDrawWidth); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_BEGIN, lcSlowLength); + PlotIndexSetInteger(lcSlowBufferIndex, PLOT_DRAW_TYPE, lcSlowDrawType); +} + +// +// MC Buffers Definitions ... +void MCDefineBuffers() +{ + // + // MC Fast Buffer ... + string mcFastBufferLabel = ShortName + " MC Fast (" + (string)mcFastLength + ")"; + ENUM_DRAW_TYPE mcFastDrawType = mcDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcFastBuffer, true); + SetIndexBuffer(mcFastBufferIndex, mcFastBuffer, INDICATOR_DATA); + PlotIndexSetString(mcFastBufferIndex, PLOT_LABEL, mcFastBufferLabel); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_COLOR, mcFastColor); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_BEGIN, mcFastLength); + PlotIndexSetInteger(mcFastBufferIndex, PLOT_DRAW_TYPE, mcFastDrawType); + + // + // MC Slow Buffer ... + string mcSlowBufferLabel = ShortName + " MC Slow (" + (string)mcSlowLength + ")"; + ENUM_DRAW_TYPE mcSlowDrawType = mcDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(mcSlowBuffer, true); + SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(mcSlowBufferIndex, PLOT_LABEL, mcSlowBufferLabel); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_COLOR, mcSlowColor); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_STYLE, mcDrawStyle); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_LINE_WIDTH, mcDrawWidth); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_BEGIN, mcSlowLength); + PlotIndexSetInteger(mcSlowBufferIndex, PLOT_DRAW_TYPE, mcSlowDrawType); +} + +// +// SC Buffers Definitions ... +void SCDefineBuffers() +{ + // + // SC Fast Buffer ... + string scFastBufferLabel = ShortName + " SC Fast (" + (string)scFastLength + ")"; + ENUM_DRAW_TYPE scFastDrawType = scDrawFast ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scFastBuffer, true); + SetIndexBuffer(scFastBufferIndex, scFastBuffer, INDICATOR_DATA); + PlotIndexSetString(scFastBufferIndex, PLOT_LABEL, scFastBufferLabel); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_COLOR, scFastColor); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scFastBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_BEGIN, scFastLength); + PlotIndexSetInteger(scFastBufferIndex, PLOT_DRAW_TYPE, scFastDrawType); + + // + // SC Slow Buffer ... + string scSlowBufferLabel = ShortName + " SC Slow (" + (string)scSlowLength + ")"; + ENUM_DRAW_TYPE scSlowDrawType = scDrawSlow ? lcDrawType : DRAW_NONE; + ArraySetAsSeries(scSlowBuffer, true); + SetIndexBuffer(scSlowBufferIndex, scSlowBuffer, INDICATOR_DATA); + PlotIndexSetString(scSlowBufferIndex, PLOT_LABEL, scSlowBufferLabel); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_COLOR, scSlowColor); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_STYLE, scDrawStyle); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_LINE_WIDTH, scDrawWidth); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_BEGIN, scSlowLength); + PlotIndexSetInteger(scSlowBufferIndex, PLOT_DRAW_TYPE, scSlowDrawType); +} + +// +// Hot State Buffer ... +void HotStateDefineBuffers() +{ + // + // Hot State Buffer ... + ArraySetAsSeries(hotStateBuffer, true); + SetIndexBuffer(hotStateBufferIndex, hotStateBuffer, INDICATOR_CALCULATIONS); +} + +// +// LC Init Handlers ... +bool LCInitHandlers() +{ + // + ResetLastError(); + + // + // LC Fast Handler ... + lcFastHandler = iMA( + _Symbol, + _Period, + lcFastLength, + 0, + lcMethod, + lcAppliedTo); + if (lcFastHandler == INVALID_HANDLE) + { + // + LogMessage("LC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // LC Slow Handler ... + lcSlowHandler = iMA( + _Symbol, + _Period, + lcSlowLength, + 0, + lcMethod, + lcAppliedTo); + if (lcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("LC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// MC Init Handlers ... +bool MCInitHandlers() +{ + // + ResetLastError(); + + // + // MC Fast Handler ... + mcFastHandler = iMA( + _Symbol, + _Period, + mcFastLength, + 0, + mcMethod, + mcAppliedTo); + if (mcFastHandler == INVALID_HANDLE) + { + // + LogMessage("MC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // MC Slow Handler ... + mcSlowHandler = iMA( + _Symbol, + _Period, + mcSlowLength, + 0, + mcMethod, + mcAppliedTo); + if (mcSlowHandler == INVALID_HANDLE) + { + // + LogMessage("MC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// SC Init Handlers ... +bool SCInitHandlers() +{ + // + ResetLastError(); + + // + // SC Fast Handler ... + scFastHandler = iMA( + _Symbol, + _Period, + scFastLength, + 0, + scMethod, + scAppliedTo); + if (scFastHandler == INVALID_HANDLE) + { + // + LogMessage("SC Fast Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + // SC Slow Handler ... + scSlowHandler = iMA( + _Symbol, + _Period, + scSlowLength, + 0, + scMethod, + scAppliedTo); + if (scSlowHandler == INVALID_HANDLE) + { + // + LogMessage("SC Slow Indicator initialization failed: " + (string)GetLastError()); + + // + return false; + } + + // + return true; +} + +// +// LC State ... +double GetLCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + lcFastBuffer, + lcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// MC State ... +double GetMCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + mcFastBuffer, + mcSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// SC State ... +double GetSCState( + int bar_index // Current Candle Index ... +) +{ + // + // Fast Cross Over Slow Detection ... + bool isFastCrossedOverSlow = IsCrossOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Over Slow Detection ... + bool isFastOverSlow = IsOver( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Cross Under Slow Detection ... + bool isFastCrossedUnderSlow = IsCrossUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Fast Under Slow Detection ... + bool isFastUnderSlow = IsUnder( + scFastBuffer, + scSlowBuffer, + bar_index); + + // + // Generate state value which represent curren bar index + // state between fast and slow lines ... + double result = X_XCHMA_NEUTURAL; + + // + // Filling state value based on Market Conditions ... + if (isFastCrossedOverSlow) + { + result = X_XCHMA_FAST_CROSSED_OVER_SLOW; + } + else if (isFastCrossedUnderSlow) + { + result = X_XCHMA_FAST_CROSSED_UNDER_SLOW; + } + else if (isFastOverSlow) + { + result = X_XCHMA_FAST_OVER_SLOW; + } + else if (isFastUnderSlow) + { + result = X_XCHMA_FAST_UNDER_SLOW; + } + + // + return result; +} + +// +// HOT State Calculate Buffers ... +void HotStateCalculateBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // LC ... + double lcFast = lcFastBuffer[bar_index]; + double lcSlow = lcSlowBuffer[bar_index]; + // + double lcFastPrev = lcFastBuffer[bar_index + 1]; + double lcSlowPrev = lcSlowBuffer[bar_index + 1]; + // + double lcState = GetLCState(bar_index); + + // + // MC ... + double mcFast = mcFastBuffer[bar_index]; + double mcSlow = mcSlowBuffer[bar_index]; + // + double mcFastPrev = mcFastBuffer[bar_index + 1]; + double mcSlowPrev = mcSlowBuffer[bar_index + 1]; + // + double mcState = GetMCState(bar_index); + + // + // SC ... + double scFast = scFastBuffer[bar_index]; + double scSlow = scSlowBuffer[bar_index]; + // + double scFastPrev = scFastBuffer[bar_index + 1]; + double scSlowPrev = scSlowBuffer[bar_index + 1]; + // + double scState = GetSCState(bar_index); + + // + // Detect HOT Bearish Area ... + bool isHotBearishArea = + lcFast < lcSlow && + mcFast < mcSlow && + scFast < scSlow; + // + bool isPrevHotBearishArea = + lcFastPrev < lcSlowPrev && + mcFastPrev < mcSlowPrev && + scFastPrev < scSlowPrev; + + // + // Detect HOT Bearish Area ... + bool isHotBullishArea = + lcFast > lcSlow && + mcFast > mcSlow && + scFast > scSlow; + // + bool isPrevHotBullishArea = + lcFastPrev > lcSlowPrev && + mcFastPrev > mcSlowPrev && + scFastPrev > scSlowPrev; + + // + // Generate HotState Value ... + double hotStateValue = + isHotBullishArea && !isPrevHotBullishArea + ? 1 + : isHotBearishArea && !isPrevHotBearishArea + ? -1 + : 0; + hotStateBuffer[bar_index] = hotStateValue; +} + +// +// Draw Buffers ... +void DrawBuffers( + int bar_index // Current Candle Index ... +) +{ + // + // General Requirements ... + + // + // Retrieve Candle Model ... + XOHCL candle = GetCandle(bar_index); + datetime time = iTime(_Symbol, _Period, bar_index); + + // + // Draw Arrow on Hot Areas ... + if (drawHotAreas) + { + // + double hotStateValue = hotStateBuffer[bar_index]; + bool isHotBullishArea = hotStateValue == 1; + bool isHotBearishArea = hotStateValue == -1; + if (isHotBullishArea || isHotBearishArea) + { + // + bool isBull = isHotBullishArea; + + // + double price = isBull ? candle.low : candle.high; + ENUM_ARROW_ANCHOR anchor = isBull ? ANCHOR_TOP : ANCHOR_BOTTOM; + color clr = isBull ? hotBullishArrowColor : hotBearishArrowColor; + uchar arrowCode = isBull ? hotBullishArrowCode : hotBearishArrowCode; + string name = "HOT " + (isBull ? "Bullish" : "Bearish") + "_" + (string)price + "_" + (string)time; + + // + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); + } + } + + // + // Draw LC Crosses ... + if (lcDrawCrosses) + { + // + double lcStateValue = GetLCState(bar_index); + bool isLcFastCrossedOverSlow = lcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isLcFastCrossedUnderSlow = lcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isLcFastCrossedOverSlow || isLcFastCrossedUnderSlow) + { + // + bool isBull = isLcFastCrossedOverSlow; + + // + color clr = isBull ? lcFastColor : lcSlowColor; + string name = "LC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw MC Crosses ... + if (mcDrawCrosses) + { + // + double mcStateValue = GetMCState(bar_index); + bool isMcFastCrossedOverSlow = mcStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isMcFastCrossedUnderSlow = mcStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isMcFastCrossedOverSlow || isMcFastCrossedUnderSlow) + { + // + bool isBull = isMcFastCrossedOverSlow; + + // + color clr = isBull ? mcFastColor : mcSlowColor; + string name = "MC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } + + // + // Draw SC Crosses ... + if (scDrawCrosses) + { + // + double scStateValue = GetSCState(bar_index); + bool isScFastCrossedOverSlow = scStateValue == X_XCHMA_FAST_CROSSED_OVER_SLOW; + bool isScFastCrossedUnderSlow = scStateValue == X_XCHMA_FAST_CROSSED_UNDER_SLOW; + if (isScFastCrossedOverSlow || isScFastCrossedUnderSlow) + { + // + bool isBull = isScFastCrossedOverSlow; + + // + color clr = isBull ? scFastColor : scSlowColor; + string name = "SC Fast Cross " + (isBull ? "Over" : "Under") + "_" + (string)time; + + // + DrawVerticalLine( + 0, + name, + 0, + time, + clr); + } + } +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xctimer.indicator.mq5 b/Indicators/x-saherelm.xctimer.indicator.mq5 new file mode 100644 index 00000000..6a064212 --- /dev/null +++ b/Indicators/x-saherelm.xctimer.indicator.mq5 @@ -0,0 +1,206 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XCTimer Indicator +// --------------------------------------------- +// Name: XCTimer +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCTimer Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XCTimer" +// +// END Constants ... +// + +// +// START Inputs ... +// +input color clr = clrYellow; +input ENUM_BASE_CORNER corner = CORNER_RIGHT_LOWER; +// +// END Inputs ... +// + +// +// START Buffers ... +// +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + CreateIndicatorObject(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Delete Object ... + ObjectDelete(0, ShortName); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + ArraySetAsSeries(time, true); + + // + int m = int(time[0] + PeriodSeconds() - TimeCurrent()); + int s = m % 60; + m = (m - s) / 60; + + // + long mSpread = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD); + + string _sp = "", _m = "", _s = ""; + if (mSpread < 10) + _sp = ".."; + else if (mSpread < 100) + _sp = "."; + if (m < 10) + _m = "0"; + if (s < 10) + _s = "0"; + + // + string objText = "Spread: " + IntegerToString(mSpread) + _sp + " Next Bar in " + _m + IntegerToString(m) + ":" + _s + IntegerToString(s); + + // + ObjectSetInteger(0, ShortName, OBJPROP_COLOR, clr); + ObjectSetString(0, ShortName, OBJPROP_TEXT, objText); + ObjectSetInteger(0, ShortName, OBJPROP_FONTSIZE, 10); + ObjectSetString(0, ShortName, OBJPROP_FONT, "Courier"); + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +void CreateIndicatorObject() +{ + // + ObjectCreate(0, ShortName, OBJ_LABEL, 0, 0, 0); + ObjectSetInteger(0, ShortName, OBJPROP_CORNER, corner); + ObjectSetInteger(0, ShortName, OBJPROP_XDISTANCE, 10); + ObjectSetInteger(0, ShortName, OBJPROP_YDISTANCE, 2); + ENUM_ANCHOR_POINT Anchor = ANCHOR_LEFT_UPPER; + switch (corner) + { + case CORNER_LEFT_UPPER: + Anchor = ANCHOR_LEFT_UPPER; + break; + case CORNER_RIGHT_UPPER: + Anchor = ANCHOR_RIGHT_UPPER; + break; + case CORNER_LEFT_LOWER: + Anchor = ANCHOR_LEFT_LOWER; + break; + case CORNER_RIGHT_LOWER: + Anchor = ANCHOR_RIGHT_LOWER; + break; + } + + // + ObjectSetInteger(0, ShortName, OBJPROP_ANCHOR, Anchor); +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xfi.oscillator.mq5 b/Indicators/x-saherelm.xfi.oscillator.mq5 new file mode 100644 index 00000000..cfd393ca --- /dev/null +++ b/Indicators/x-saherelm.xfi.oscillator.mq5 @@ -0,0 +1,317 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XFI Oscillator +// --------------------------------------------- +// Name: XFI +// Description: Price Momentum Power Detection +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XFI Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XFI" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 18; // Length +input ENUM_MA_METHOD method = MODE_SMA; // MA Method +input ENUM_APPLIED_VOLUME appliedTo = VOLUME_TICK; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 2 +#property indicator_plots 1 + +// +// FI Buffer ... +#define fiBufferIndex 0 +#define fiColorBufferIndex 1 + +// +double fiBuffer[]; +double fiColorBuffer[]; + +// +#property indicator_label1 "XFI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int fiHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + fiHandler = iForce( + _Symbol, + _Period, + length, + method, + appliedTo); + if (fiHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + IndicatorRelease(fiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + // Check Calculated Bars ... + int fiCalculatedBars = BarsCalculated(fiHandler); + if (fiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedFis = CopyBuffer(fiHandler, 0, 0, limit, fiBuffer); + if (copiedFis <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string fiBufferLabel = "XFI " + "(" + (string)length + ")"; + + // + // FI Buffer ... + ArraySetAsSeries(fiBuffer, true); + SetIndexBuffer(fiBufferIndex, fiBuffer, INDICATOR_DATA); + PlotIndexSetString(fiBufferIndex, PLOT_LABEL, fiBufferLabel); + + // + // FI Color Buffer ... + ArraySetAsSeries(fiColorBuffer, true); + SetIndexBuffer(fiColorBufferIndex, fiColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + double iValue = fiBuffer[bar_index]; + + // + double iColorIndex = + iValue > 0 ? 0 : iValue < 0 ? 2 + : 1; + + // + // Set Buffer Color Index ... + fiColorBuffer[bar_index] = iColorIndex; +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xlh.indicator.mq5 b/Indicators/x-saherelm.xlh.indicator.mq5 new file mode 100644 index 00000000..4dfc64e2 --- /dev/null +++ b/Indicators/x-saherelm.xlh.indicator.mq5 @@ -0,0 +1,346 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XLH Indicator +// --------------------------------------------- +// Name: XLH +// Description: Moving Average Indicator +// Market Analysor ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XLH Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XLH" +// +// END Constants ... +// + +// +// START Inputs ... +// +input int length = 14; // Length +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +// HH Buffer ... +#define hhBufferIndex 0 + +// +double hhBuffer[]; + +// +#property indicator_label1 "XLH HH" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrAqua +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// LL Buffer ... +#define llBufferIndex 1 + +// +double llBuffer[]; + +// +#property indicator_label2 "XLH LL" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrFuchsia +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +// Signal Buffer ... +#define signalBufferIndex 2 + +// +double signalBuffer[]; + +// +#property indicator_label3 "XLH S" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // HH Buffer ... + string hhBufferLabel = ShortName + " HH " + "(" + (string)length + ")"; + ArraySetAsSeries(hhBuffer, true); + SetIndexBuffer(hhBufferIndex, hhBuffer, INDICATOR_DATA); + PlotIndexSetInteger(hhBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(hhBufferIndex, PLOT_LABEL, hhBufferLabel); + + // + // LL Buffer ... + string llBufferLabel = ShortName + " LL " + "(" + (string)length + ")"; + ArraySetAsSeries(llBuffer, true); + SetIndexBuffer(llBufferIndex, llBuffer, INDICATOR_DATA); + PlotIndexSetInteger(llBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(llBufferIndex, PLOT_LABEL, llBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + " S " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, ""); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Threshold ... + // + // HH Buffer ... + int hhIndex = iHighest( + _Symbol, + _Period, + hhMode, + length, + bar_index); + double hhValue = GetAppliedPrice( + hhIndex, + hhMode); + + // + hhBuffer[bar_index] = hhValue; + + // + // LL Buffer ... + int llIndex = iLowest( + _Symbol, + _Period, + llMode, + length, + bar_index); + double llValue = GetAppliedPrice( + llIndex, + llMode); + + // + llBuffer[bar_index] = llValue; + + // + XOHCL c = GetCandle(bar_index); + double lhDiff = hhValue - llValue; + double signalValue = (lhDiff / 2); + + // + signalBuffer[bar_index] = (hhValue - signalValue); +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xobd.indicator.mq5 b/Indicators/x-saherelm.xobd.indicator.mq5 new file mode 100644 index 00000000..4ac05cf6 --- /dev/null +++ b/Indicators/x-saherelm.xobd.indicator.mq5 @@ -0,0 +1,390 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Indicator +// ----------------------------------------------------- +// Name: XOBD +// Description: detect Order Blocks based on Swings ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XOBD Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XOBD" +// +// END Constants ... +// + +// +// START Inputs ... +// +// +input int length = 5; // Swing Length + +// +input uchar swingHighArrowCode = 108; // Swing High Arrow Code +input color swingHighArrowColor = clrMagenta; // Swing High Arrow Color + +// +input uchar swingLowArrowCode = 108; // Swing Low Arrow Code +input color swingLowArrowColor = clrAqua; // Swing Low Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 1 +#property indicator_plots 0 + +// +#define swingBufferIndex 0 +double swingBuffer[]; +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length * 3); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + ArraySetAsSeries(swingBuffer, true); + SetIndexBuffer(swingBufferIndex, swingBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // GetCandleSwing(bar_index); + ENUM_X_SWING_TYPE type = X_NO_SWING; + + // + // Try To Detect Order Blocks ... + bool isSwingLow = false; + bool isSwingHigh = false; + + // + // Reading Candles Data ... + XOHCL candles[]; + for (int i = bar_index; i < bar_index + ((length * 2) + 2); i++) + { + // + XOHCL iCandle = GetCandle( + _Symbol, + _Period, + i); + + // + Add( + iCandle, + candles); + } + + // + // Swing Low ... + isSwingLow = + // + candles[1].close > candles[2].close && + candles[2].close > candles[3].close && + // + candles[3].close < candles[4].close && + // + candles[5].close > candles[4].close && + candles[6].close > candles[5].close + // + ; + + // + if (isSwingLow) + { + type = X_SWING_LOW; + } + + // + if (!isSwingLow) + { + // + // Swing High ... + isSwingHigh = + // + candles[1].close < candles[2].close && + candles[2].close < candles[3].close && + // + candles[3].close > candles[4].close && + // + candles[5].close < candles[4].close && + candles[6].close < candles[5].close + // + ; + + // + if (isSwingHigh) + { + type = X_SWING_HIGH; + } + } + + // + switch (type) + { + // + // Swing High ... + case X_SWING_HIGH: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(1, bar_index); + break; + + // + // Swinmg Low ... + case X_SWING_LOW: + // + swingBuffer[bar_index] = type; + DrawSwingArrow(0, bar_index); + break; + + // + // No Swing ... + default: + case X_NO_SWING: + // + swingBuffer[bar_index] = 0; + break; + } +} + +// +// Draw a Swing Arrow Shape ... +void DrawSwingArrow( + int type, // Swing Type: 0 - Low / 1 - High ... + int bar_index) +{ + // + bool isSwingHigh = type == 1; + XOHCL candle = GetCandle(bar_index + 3); + double arrowDistanceInPoint = 0; + + // + // Define Required Object Properties fro Draw an Arrow ... + datetime time = iTime(_Symbol, _Period, bar_index + 3); + double purePrice = isSwingHigh ? candle.high : candle.low; + color clr = isSwingHigh ? swingHighArrowColor : swingLowArrowColor; + ENUM_ARROW_ANCHOR anchor = isSwingHigh ? ANCHOR_BOTTOM : ANCHOR_TOP; + uchar arrowCode = uchar(isSwingHigh ? swingHighArrowCode : swingLowArrowCode); + double price = isSwingHigh ? purePrice + arrowDistanceInPoint : purePrice - arrowDistanceInPoint; + string name = "Swing " + (isSwingHigh ? "High" : "Low") + "_" + (string)time + "_" + (string)purePrice; + + // + // Draw desired Arrow ... + DrawArrow( + 0, + name, + 0, + time, + price, + arrowCode, + anchor, + clr); +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xrsi.oscillator.mq5 b/Indicators/x-saherelm.xrsi.oscillator.mq5 new file mode 100644 index 00000000..5659e07d --- /dev/null +++ b/Indicators/x-saherelm.xrsi.oscillator.mq5 @@ -0,0 +1,397 @@ +///////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 OrderBlock Detector Oscillator +// ------------------------------------------------------ +// Name: XRSI +// Description: detect market conditions based on RSI ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XRSI Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XRSI" + +// +// END Constants ... +// + +// +// START Inputs ... +// + +// +input group "Market"; +input int length = 14; // Market Length +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Short Entry"; +input double shortEntryValue = 70; // Short Entry Level +input color shortEntryColor = clrRed; // Short Entry Level Color +input ENUM_LINE_STYLE shortEntryLineStyle = STYLE_DOT; // Short Entry Style + +// +input group "Short Exit"; +input double shortExitValue = 40; // Short Exit Level +input color shortExitColor = clrRed; // Short Exit Level Color +input ENUM_LINE_STYLE shortExitLineStyle = STYLE_DOT; // Short Exit Style + +// +input group "Long Entry"; +input double longEntryValue = 30; // Long Entry Level +input color longEntryColor = clrRed; // Long Entry Level Color +input ENUM_LINE_STYLE longEntryLineStyle = STYLE_DOT; // Long Entry Style + +// +input group "Long Exit"; +input double longExitValue = 60; // Long Exit Level +input color longExitColor = clrRed; // Long Exit Level Color +input ENUM_LINE_STYLE longExitLineStyle = STYLE_DOT; // Long Exit Style + +// +// START Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Common and Models Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// + +// +#property indicator_separate_window +#property indicator_buffers 2 +#property indicator_plots 1 + +// +#define rsiBufferIndex 0 +#define rsiColorBufferIndex 1 + +// +double rsiBuffer[]; +double rsiColorBuffer[]; + +// +#property indicator_label1 "XRSI" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrAqua, clrGray, clrFuchsia +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +int rsiHandler = INVALID_HANDLE; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + rsiHandler = iRSI( + _Symbol, + _Period, + length, + appliedTo); + if (rsiHandler == INVALID_HANDLE) + { + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + IndicatorRelease(rsiHandler); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + int rsiCalculatedBars = BarsCalculated(rsiHandler); + if (rsiCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + int rsiCopiedItems = CopyBuffer(rsiHandler, 0, 0, limit, rsiBuffer); + if (rsiCopiedItems <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // RSI ... + string rsiBufferLabel = ShortName + " (" + (string)length + ")"; + ArraySetAsSeries(rsiBuffer, true); + SetIndexBuffer(rsiBufferIndex, rsiBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rsiBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(rsiBufferIndex, PLOT_LABEL, rsiBufferLabel); + + // + // RSI Color Buffer ... + ArraySetAsSeries(rsiColorBuffer, true); + SetIndexBuffer(rsiColorBufferIndex, rsiColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set Indicator Levels here ... + // OB, ExitLong, ExitShort, OS ... + IndicatorSetInteger(INDICATOR_LEVELS, 4); + + // + // SHORTENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, shortEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, shortEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, shortEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 0, "Short Entry"); + + // + // LONGEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, longExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, longExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, shortExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 1, "Long Exit"); + + // + // SHORTEXIT ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 2, shortExitValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 2, shortExitColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 2, longEntryLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 2, "Short Exit"); + + // + // LONGENTRY ... + IndicatorSetDouble(INDICATOR_LEVELVALUE, 3, longEntryValue); + IndicatorSetInteger(INDICATOR_LEVELCOLOR, 3, longEntryColor); + IndicatorSetInteger(INDICATOR_LEVELSTYLE, 3, longExitLineStyle); + IndicatorSetString(INDICATOR_LEVELTEXT, 3, "Long Entry"); + + // + // Set Maximum and Minimum for subwindow + IndicatorSetInteger(INDICATOR_DIGITS, 2); + IndicatorSetDouble(INDICATOR_MINIMUM, 0); + IndicatorSetDouble(INDICATOR_MAXIMUM, 100); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + double iValue = rsiBuffer[bar_index]; + + // + double iColorIndex = 0; + + // + if ( + iValue >= shortEntryValue || + iValue <= longEntryValue || + (iValue < longExitValue && + iValue > shortExitValue)) + { + iColorIndex = 0; + } + else if ( + iValue <= shortEntryValue && + iValue >= longExitValue) + { + iColorIndex = 2; + } + else if ( + iValue < shortExitValue && + iValue > longEntryValue) + { + iColorIndex = 1; + } + + // + rsiColorBuffer[bar_index] = iColorIndex; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xtd.oscillator.mq5 b/Indicators/x-saherelm.xtd.oscillator.mq5 new file mode 100644 index 00000000..5f46d187 --- /dev/null +++ b/Indicators/x-saherelm.xtd.oscillator.mq5 @@ -0,0 +1,465 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Trend Detector Oscillator +// -------------------------------------------------- +// Name: XTD +// Description: trend detecting in both sides ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTD Oscillator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTD" + +// +// XTD Oscillator States ... +enum ENUM_X_XTD_STATES +{ + X_XTD_BULLISH_CROSSED_OVER_BEARISH = 2, + X_XTD_BULLISH_OVER_BEARISH = 1, + X_XTD_NEUTURAL = 0, + X_XTD_BULLISH_UNDER_BEARISH = -1, + X_XTD_BULLISH_CROSSED_UNDER_BEARISH = -2 +}; +// +// END Constants ... +// + +// +// Include Models Library ... +#include "../Libraries/x-saherelm.models.lib.mq5" + +// +// START Inputs ... +// +input int length = 14; // Market Length +input bool drawCrosses = true; // Draw Cross Arrows + +// +// Bullish ... +input uchar bullishArrowCode = 228; // Cross Over Arrow Code +input color bullishArrowColor = clrAqua; // Cross Over Arrow Color + +// +// Bearish ... +input uchar bearishArrowCode = 230; // Cross Under Arrow Code +input color bearishArrowColor = clrMagenta; // Cross Under Arrow Color +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5"; + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5"; + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5"; + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 3 +#property indicator_plots 3 + +// +#define bullishBufferIndex 0 +#define bearishBufferIndex 1 +#define signalBufferIndex 2 + +// +double bullishBuffer[]; +double bearishBuffer[]; +double signalBuffer[]; + +// +#property indicator_label1 "XBullPower" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrLime +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +#property indicator_label2 "XBearPower" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrRed +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +#property indicator_label3 "XSignal" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +// +int xtdBullishCandleCount = 0; +int xtdBearishCandleCount = 0; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... + + // + // De Init Draw Library ... + OnDeinitDrawLibrary(); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, length); + + // + limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; + + // + // Main Loop ... + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + CalculateBuffers(i, close); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (length >= 5) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Bullish Buffer ... + string bullishBufferLabel = ShortName + "BullPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bullishBuffer, true); + SetIndexBuffer(bullishBufferIndex, bullishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bullishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bullishBufferIndex, PLOT_LABEL, bullishBufferLabel); + + // + // Bearish Buffer ... + string bearishBufferLabel = ShortName + "BearPow " + "(" + (string)length + ")"; + ArraySetAsSeries(bearishBuffer, true); + SetIndexBuffer(bearishBufferIndex, bearishBuffer, INDICATOR_DATA); + PlotIndexSetInteger(bearishBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(bearishBufferIndex, PLOT_LABEL, bearishBufferLabel); + + // + // Signal Buffer ... + string signalBufferLabel = ShortName + "Signal " + "(" + (string)length + ")"; + ArraySetAsSeries(signalBuffer, true); + SetIndexBuffer(signalBufferIndex, signalBuffer, INDICATOR_DATA); + PlotIndexSetInteger(signalBufferIndex, PLOT_DRAW_BEGIN, length); + PlotIndexSetString(signalBufferIndex, PLOT_LABEL, signalBufferLabel); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "( ", length, " )"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index, + const double &close[]) +{ + // + // Reset Global Counters ... + xtdBullishCandleCount = 0; + xtdBearishCandleCount = 0; + + // + // Loop through Closes ... + for (int i = bar_index; i <= bar_index + length; i++) + { + for (int j = i + 1; j <= bar_index + length; j++) + { + // + if (close[i] > close[j]) + { + xtdBullishCandleCount++; + } + + // + if (close[i] < close[j]) + { + xtdBearishCandleCount++; + } + } + } + + // + // Bullish Power Buffer ... + bullishBuffer[bar_index] = MathAbs(xtdBullishCandleCount); + + // + // Bearish Power Buffer ... + bearishBuffer[bar_index] = MathAbs(xtdBearishCandleCount); + + // + // Signal Buffer ... + signalBuffer[bar_index] = bullishBuffer[bar_index] - bearishBuffer[bar_index]; + + // + // Check and Draw Crosses if it's Specified ... + if (drawCrosses) + { + DrawCrosses(bar_index); + } +} + +// +// +double GetState( + int bar_index // Specified Bar Index +) +{ + // + // Check Cross Points ... + // bullishCrossedOverBearish = 2; + // bullishOverBearish = 1; + // bullishCrossedUnderBearish = -2; + // bullishUnderBearish = -1; + // OtherWise = 0; + bool isBullishCrossedOverBearish = IsCrossOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishCrossedUnderBearish = IsCrossUnder( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishOverBearish = IsOver( + bullishBuffer, + bearishBuffer, + bar_index); + bool isBullishUnderBearish = IsUnder( + bullishBuffer, + bearishBuffer, + bar_index); + + // + double result = X_XTD_NEUTURAL; + if (isBullishCrossedOverBearish) + { + result = X_XTD_BULLISH_CROSSED_OVER_BEARISH; + } + else if (isBullishCrossedUnderBearish) + { + result = X_XTD_BULLISH_CROSSED_UNDER_BEARISH; + } + else if (isBullishOverBearish) + { + result = X_XTD_BULLISH_OVER_BEARISH; + } + else if (isBullishUnderBearish) + { + result = X_XTD_BULLISH_UNDER_BEARISH; + } + else + { + result = X_XTD_NEUTURAL; + } + + // + return result; +} + +// +// Draw Crosses ... +void DrawCrosses( + int bar_index // the bars which required to draw cross arrow on it ... +) +{ + // + double stateValue = GetState(bar_index); + + // + bool isOver = stateValue == 2; + double low = iLow(_Symbol, _Period, bar_index); + double high = iHigh(_Symbol, _Period, bar_index); + + // + double price = isOver ? low : high; + datetime time = iTime(_Symbol, _Period, bar_index); + ENUM_ARROW_ANCHOR anchor = isOver ? ANCHOR_TOP : ANCHOR_BOTTOM; + uchar arrowCode = isOver ? bullishArrowCode : bearishArrowCode; + color arrowColor = isOver ? bullishArrowColor : bearishArrowColor; + string crossName = "Trend " + (isOver ? "Up" : "Down") + "_" + (string)time + "_" + (string)price; + + // + DrawArrow( + 0, + crossName, + 0, + time, + price, + arrowCode, + anchor, + arrowColor); +} +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xtm.indicator.mq5 b/Indicators/x-saherelm.xtm.indicator.mq5 new file mode 100644 index 00000000..eac88e0a --- /dev/null +++ b/Indicators/x-saherelm.xtm.indicator.mq5 @@ -0,0 +1,349 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Candle Indicator +// --------------------------------------------- +// Name: XTM +// Description: Trend Magic Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTM Indicator" +#property strict + +// +// START Constants ... +// +#define ShortName "XTM" + +// +// XTM Indicator States ... +enum ENUM_X_XTM_STATES +{ + X_XTM_BULLISH = 1, + X_XTM_BEARISH = -1, + X_XTM_NEUTURAL = 0, +}; +// +// END Constants ... +// + +// +// START Inputs ... +// +input int maPeriod = 14; // Period +input int maShift = 0; // Shift +input ENUM_MA_METHOD maMethod = MODE_SMA; // Method +input ENUM_APPLIED_PRICE maAppliedTo = PRICE_CLOSE; // Applied To +// +// END Inputs ... +// + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_chart_window + +// +#property indicator_buffers 3 +#property indicator_plots 1 + +// +// maBuffer ... +#define maBufferIndex 0 +#define maColorBufferIndex 1 +#define stateBufferIndex 2 + +double maBuffer[]; +double maColorBuffer[]; +double stateBuffer[]; + +#property indicator_label1 "XTM" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 clrLime, clrGray, clrRed +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// +int maHandler = INVALID_HANDLE; +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + + // + // Initializing MA Handler ... + maHandler = iMA( + _Symbol, + _Period, + maPeriod, + maShift, + maMethod, + maAppliedTo); + if (maHandler == INVALID_HANDLE) + { + // + string message = "Error Initializing Ma Handler ..."; + LogMessage(message); + + // + return INIT_FAILED; + } + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = MathMax(0, maPeriod); + + // + // Check Calculated Bars ... + int maCalculatedBars = BarsCalculated(maHandler); + if (maCalculatedBars < maxLength) + { + return prev_calculated; + } + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Buffers Copy ... + int copiedMas = CopyBuffer(maHandler, 0, 0, limit, maBuffer); + if (copiedMas <= 0) + { + return prev_calculated; + } + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + if (maPeriod >= 2) + { + result = true; + } + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + string maBufferLabel = "XTM " + "(" + (string)maPeriod + ")"; + + // + // Ma Buffer ... + ArraySetAsSeries(maBuffer, true); + SetIndexBuffer(maBufferIndex, maBuffer, INDICATOR_DATA); + PlotIndexSetString(maBufferIndex, PLOT_LABEL, maBufferLabel); + + // + // Ma Color Buffer ... + ArraySetAsSeries(maColorBuffer, true); + SetIndexBuffer(maColorBufferIndex, maColorBuffer, INDICATOR_COLOR_INDEX); + + // + // State Buffer ... + ArraySetAsSeries(stateBuffer, true); + SetIndexBuffer(stateBufferIndex, stateBuffer, INDICATOR_CALCULATIONS); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + // + string indicatorShortName = ""; + StringConcatenate(indicatorShortName, ShortName, " ", "(", maPeriod, ")"); + + // + IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Requirements ... + XOHCL candle = GetCandle(bar_index); + + // + double maValue = maBuffer[bar_index]; + + // + double lineColorIndex = + maValue < candle.low ? 0 : maValue > candle.high ? 2 + : 1; + + // + // Define State Value ... + // lineColorIndex == 0 => Bullish => 1; + // lineColorIndex == 1 => Neutural => 0; + // lineColorIndex == 2 => Bearish => -1; + double stateValue = + lineColorIndex == 0 ? X_XTM_BULLISH : lineColorIndex == 2 ? X_XTM_BEARISH + : X_XTM_NEUTURAL; + + // + // Set Ma Buffer Color Index ... + maColorBuffer[bar_index] = lineColorIndex; + + // + // Set State Buffer Value ... + stateBuffer[bar_index] = stateValue; +} + +// +// END Functions ... +// diff --git a/Indicators/x-saherelm.xts.oscillator.mq5 b/Indicators/x-saherelm.xts.oscillator.mq5 new file mode 100644 index 00000000..46e9fbf9 --- /dev/null +++ b/Indicators/x-saherelm.xts.oscillator.mq5 @@ -0,0 +1,558 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XTS Oscillator +// --------------------------------------------- +// Name: XTS +// Description: Time Sections Oscillator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XTS Oscillator" +#property strict + +// +// START Constants ... +// + +#define ShortName "XTS" + +enum ENUM_X_PERIOD_METHOD +{ + // + X_PERIOD_NOTHING, + // + X_PERIOD_AUTO, + // + X_PERIOD_MANUALLY +}; + +// +// XTS Oscillator States ... + +// +// END Constants ... +// + +// +// START Inputs ... +// +input group "Current Period"; +input ENUM_APPLIED_PRICE currentAppliedTo = PRICE_CLOSE; // Current Applied To +// +input group "Nearest Period"; +input ENUM_X_PERIOD_METHOD nearestMethod = X_PERIOD_AUTO; // How to Find Nearest Period +input ENUM_TIMEFRAMES nearestPeriod = NULL; // Nearest Time Frame +input ENUM_APPLIED_PRICE nearestAppliedTo = PRICE_CLOSE; // Nearest Applied To +// +input group "Mediest Period"; +input ENUM_X_PERIOD_METHOD mediestMethod = X_PERIOD_AUTO; // How to Find Mediest Period +input ENUM_TIMEFRAMES mediestPeriod = NULL; // Mediest Time Frame +input ENUM_APPLIED_PRICE mediestAppliedTo = PRICE_CLOSE; // Mediest Applied To +// +input group "Farest Period"; +input ENUM_X_PERIOD_METHOD farestMethod = X_PERIOD_AUTO; // How to Find Farest Period +input ENUM_TIMEFRAMES farestPeriod = NULL; // Farest Time Frame +input ENUM_APPLIED_PRICE farestAppliedTo = PRICE_CLOSE; // Farest Applied To + +// +// Includes Logging Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Includes Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// START Buffers ... +// +#property indicator_separate_window + +// +#property indicator_buffers 4 +#property indicator_plots 4 + +// +// Current ... +#define currentBufferIndex 0 + +double currentBuffer[]; + +#property indicator_label1 "XTS C" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrBrown +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 + +// +// Nearest ... +#define nearestBufferIndex 1 + +double nearestBuffer[]; + +#property indicator_label2 "XTS N" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrAqua +#property indicator_style2 STYLE_SOLID +#property indicator_width2 1 + +// +// Mediest ... +#define mediestBufferIndex 2 + +double mediestBuffer[]; + +#property indicator_label3 "XTS M" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrLime +#property indicator_style3 STYLE_SOLID +#property indicator_width3 1 + +// +// Farest ... +#define farestBufferIndex 3 + +double farestBuffer[]; + +#property indicator_label4 "XTS F" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrLightBlue +#property indicator_style4 STYLE_SOLID +#property indicator_width4 1 + +// +// END Buffers ... +// + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +ENUM_TIMEFRAMES mNearestPeriod = NULL; +ENUM_TIMEFRAMES mMediestPeriod = NULL; +ENUM_TIMEFRAMES mFarestPeriod = NULL; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Event Handlers ... +// + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + logTag = ShortName; + drawPrefix = ShortName; + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Oscillator ShortName ... + SetOscillatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + OnDeinitDrawLibrary(); + + // + Comment(""); +} + +// +// Calculations ... +// +// Calculating what we want ... +int OnCalculate( + // + // total Candles on chart ... + const int rates_total, + // + // total calculated Candles on charts ... + const int prev_calculated, + // + // history of Candles Open Time ... + const datetime &time[], + // + // history of Candles Open Price ... + const double &open[], + // + // history of Candles High Price ... + const double &high[], + // + // history of Candles Low Price ... + const double &low[], + // + // history of Candles Close Price ... + const double &close[], + // + // history of Tick Volumes on Candle ... + const long &tick_volume[], + // + // history of Trade Volumes ... + const long &volume[], + // + // history of Candles Spread Price ... + const int &spread[]) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + int maxLength = 30; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = 0; i < limit && !IsStopped(); i++) + { + // + // Do Buffers Calculation ... + CalculateBuffers(i); + } + + // + return rates_total; +} + +// +// END Event Handlers ... +// + +// +// START Functions ... +// +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = true; + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + int maxLength = 30; + + // + // Current ... + ArraySetAsSeries(currentBuffer, true); + SetIndexBuffer(currentBufferIndex, currentBuffer, INDICATOR_DATA); + PlotIndexSetInteger(currentBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Nearest ... + ArraySetAsSeries(nearestBuffer, true); + SetIndexBuffer(nearestBufferIndex, nearestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(nearestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Mediest ... + ArraySetAsSeries(mediestBuffer, true); + SetIndexBuffer(mediestBufferIndex, mediestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mediestBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // Farest ... + ArraySetAsSeries(farestBuffer, true); + SetIndexBuffer(farestBufferIndex, farestBuffer, INDICATOR_DATA); + PlotIndexSetInteger(farestBufferIndex, PLOT_DRAW_BEGIN, maxLength); +} + +// +// Set Oscillator Short Name and also we can define Buffers Labels ... +void SetOscillatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers(int bar_index) +{ + // + // Current ... + CalculateCurrent(bar_index); + + // + // Nearest ... + CalculateNearest(bar_index); + + // + // Mediest ... + CalculateMediest(bar_index); + + // + // Farest ... + CalculateFarest(bar_index); + + // + // Commenting ... + string comment = GenerateDescriptionComment(); + Comment(comment); +} + +// +// Current ... +void CalculateCurrent(int bar_index) +{ + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + _Period, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + currentAppliedTo); + + // + currentBuffer[bar_index] = value; +} + +// +// Nearest ... +void CalculateNearest(int bar_index) +{ + // + if (mNearestPeriod == NULL) + { + // + switch (nearestMethod) + { + // + case X_PERIOD_AUTO: + mNearestPeriod = GetNearestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mNearestPeriod = nearestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mNearestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + nearestAppliedTo); + + // + nearestBuffer[bar_index] = value; +} + +// +// Mediest ... +void CalculateMediest(int bar_index) +{ + // + if (mMediestPeriod == NULL) + { + // + switch (mediestMethod) + { + // + case X_PERIOD_AUTO: + mMediestPeriod = GetMediestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mMediestPeriod = mediestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mMediestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + mediestAppliedTo); + + // + mediestBuffer[bar_index] = value; +} + +// +// Farest ... +void CalculateFarest(int bar_index) +{ + // + if (mFarestPeriod == NULL) + { + // + switch (farestMethod) + { + // + case X_PERIOD_AUTO: + mFarestPeriod = GetFarestTimeFrame(_Period); + break; + + // + case X_PERIOD_NOTHING: + case X_PERIOD_MANUALLY: + mFarestPeriod = farestPeriod; + break; + } + } + + // + datetime barTime = iTime( + _Symbol, + _Period, + bar_index); + datetime startTime = GetPeriodStartTime( + _Symbol, + mFarestPeriod, + barTime); + int startBarIndex = iBarShift( + _Symbol, + _Period, + startTime); + + // + XOHCL c = GetCandle( + _Symbol, + _Period, + startBarIndex); + + // + double value = GetAppliedPrice( + c, + farestAppliedTo); + + // + farestBuffer[bar_index] = value; +} + +// +// Generate Comment ... +string GenerateDescriptionComment() +{ + // + string result = ""; + + // + result += "Nearest : " + EnumToString(mNearestPeriod) + "\n"; + result += "Mediest : " + EnumToString(mMediestPeriod) + "\n"; + result += "Farest : " + EnumToString(mFarestPeriod) + "\n"; + + // + return result; +} +// +// END Functions ... +// diff --git a/BKP/Main/Libraries/x-saherelm.alert.lib.mq5 b/Libraries/x-saherelm.alert.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.alert.lib.mq5 rename to Libraries/x-saherelm.alert.lib.mq5 diff --git a/BKP/Main/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.common.lib.mq5 rename to Libraries/x-saherelm.common.lib.mq5 diff --git a/BKP/Main/Libraries/x-saherelm.draw.lib.mq5 b/Libraries/x-saherelm.draw.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.draw.lib.mq5 rename to Libraries/x-saherelm.draw.lib.mq5 diff --git a/BKP/Main/Libraries/x-saherelm.http.lib.mq5 b/Libraries/x-saherelm.http.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.http.lib.mq5 rename to Libraries/x-saherelm.http.lib.mq5 diff --git a/BKP/Main/Libraries/x-saherelm.log.lib.mq5 b/Libraries/x-saherelm.log.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.log.lib.mq5 rename to Libraries/x-saherelm.log.lib.mq5 diff --git a/BKP/Main/Libraries/x-saherelm.models.lib.mq5 b/Libraries/x-saherelm.models.lib.mq5 similarity index 100% rename from BKP/Main/Libraries/x-saherelm.models.lib.mq5 rename to Libraries/x-saherelm.models.lib.mq5 diff --git a/Projects/XEU5/Experts/x-saherelm.xeu5.ea.mq5 b/Projects/XEU5/Experts/x-saherelm.xeu5.ea.mq5 index 55ee0578..4da65d3e 100644 --- a/Projects/XEU5/Experts/x-saherelm.xeu5.ea.mq5 +++ b/Projects/XEU5/Experts/x-saherelm.xeu5.ea.mq5 @@ -118,7 +118,7 @@ int OnInit() // Init XCTimer ... if (xEU5ShowCandleTimer) { - if (!XCTimerInit()) + if (!XEU5CTimerInit()) { return INIT_FAILED; } @@ -299,13 +299,13 @@ void OnTick() } // - if (!IsNewCandle() && waitUntilNextCandle) + if (!IsNewCandle() && xEU5WaitUntilNextCandle) { return; } // - waitUntilNextCandle = false; + xEU5WaitUntilNextCandle = false; // // Prevent Going Forward if user Disable it ... @@ -367,7 +367,7 @@ bool ValidateInputs() return result; } -bool XCTimerInit() +bool XEU5CTimerInit() { // bool result = true; diff --git a/Projects/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 b/Projects/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 index d58da3ed..b57e633c 100644 --- a/Projects/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 +++ b/Projects/XEU5/Providers/x-saherelm.xeu5.provider.indicators.lib.mq5 @@ -98,7 +98,7 @@ int xEU5CalculatedBars = 0; // // Check prevent Double Signalling on Same Candle ... -bool waitUntilNextCandle = false; +bool xEU5WaitUntilNextCandle = false; // // Signaller Variables ... diff --git a/Projects/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 b/Projects/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 index e5e8e42c..f2d86858 100644 --- a/Projects/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 +++ b/Projects/XEU5/Providers/x-saherelm.xeu5.provider.lib.mq5 @@ -514,7 +514,7 @@ void XEU5HandleOpenTrades() XEU5UpdateReports(); // - waitUntilNextCandle = true; + xEU5WaitUntilNextCandle = true; // // Open Long Trades ... diff --git a/Providers/x-saherelm.xau5.provider.indicators.lib.mq5 b/Providers/x-saherelm.xau5.provider.indicators.lib.mq5 new file mode 100644 index 00000000..020cda1c --- /dev/null +++ b/Providers/x-saherelm.xau5.provider.indicators.lib.mq5 @@ -0,0 +1,7744 @@ +/////////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAU5 Signal Provider Indicators Library +// ---------------------------------------------------------------- +// +// 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 Provider Inputs ... +#include "x-saherelm.xau5.provider.inputs.lib.mq5" + +// +// Include Provider Class ... +#include "../Classes/x-saherelm.provider.lib.mq5" + +// +// Signallers ... +input group "XAU5 Signallers"; + +// +// XTD ... +input group "XAU5 XTD Signaller"; +input bool xAU5XTDEnableSignaller = true; // Enable Signaller +input bool xAU5XTDAllowLongSignals = true; // Enable Long Signals +input bool xAU5XTDAllowShortSignals = true; // Enable Short Signals + +// +// XTAM ... +input group "XAU5 XTAM Signaller"; +input bool xAU5XTAMEnableSignaller = true; // Enable Signaller +input bool xAU5XTAMAllowLongSignals = true; // Enable Long Signals +input bool xAU5XTAMAllowShortSignals = true; // Enable Short Signals + +// +// XSI ... +input group "XAU5 XSI Signaller"; +input bool xAU5XSIEnableSignaller = true; // Enable Signaller +input bool xAU5XSIAllowLongSignals = true; // Enable Long Signals +input bool xAU5XSIAllowShortSignals = true; // Enable Short Signals + +// +// XTSFI ... +input group "XAU5 XTSFI Signaller"; +input bool xAU5XTSFIEnableSignaller = true; // Enable Signaller +input bool xAU5XTSFIAllowLongSignals = true; // Enable Long Signals +input bool xAU5XTSFIAllowShortSignals = true; // Enable Short Signals + +// +// XOBDLH ... +input group "XAU5 XOBDLH Signaller"; +input bool xAU5XOBDLHEnableSignaller = true; // Enable Signaller +input bool xAU5XOBDLHAllowLongSignals = true; // Enable Long Signals +input bool xAU5XOBDLHAllowShortSignals = true; // Enable Short Signals + +// +// XCHMACC ... +input group "XAU5 XCHMACC Signaller"; +input bool xAU5XCHMACCEnableSignaller = true; // Enable Signaller +input bool xAU5XCHMACCAllowLongSignals = true; // Enable Long Signals +input bool xAU5XCHMACCAllowShortSignals = true; // Enable Short Signals + +// +// XCHMAMX ... +input group "XAU5 XCHMAMX Signaller"; +input bool xAU5XCHMAMXEnableSignaller = true; // Enable Signaller +input bool xAU5XCHMAMXAllowLongSignals = true; // Enable Long Signals +input bool xAU5XCHMAMXAllowShortSignals = true; // Enable Short Signals + +// +// XCHMAMN ... +input group "XAU5 XCHMAMN Signaller"; +input bool xAU5XCHMAMNEnableSignaller = true; // Enable Signaller +input bool xAU5XCHMAMNAllowLongSignals = true; // Enable Long Signals +input bool xAU5XCHMAMNAllowShortSignals = true; // Enable Short Signals + +// +// Check in Test Mode or not ... +bool xAU5IsTestMode = false; + +// +// Detect max Input Length of Indicators ... +int xAU5MaxLengthOfInputs = 0; + +// +// Detect Calculated Bars ... +int xAU5CalculatedBars = 0; + +// +// Check prevent Double Signalling on Same Candle ... +bool xAU5WaitUntilNextCandle = false; + +// +// Signaller Variables ... +// +// XTD ... +bool xAU5MXTDEnableSignaller = xAU5XTDEnableSignaller; +bool xAU5MXTDAllowLongSignals = xAU5XTDAllowLongSignals; +bool xAU5MXTDAllowShortSignals = xAU5XTDAllowShortSignals; + +// +// XTAM ... +bool xAU5MXTAMEnableSignaller = xAU5XTAMEnableSignaller; +bool xAU5MXTAMAllowLongSignals = xAU5XTAMAllowLongSignals; +bool xAU5MXTAMAllowShortSignals = xAU5XTAMAllowShortSignals; + +// +// XSI ... +bool xAU5MXSIEnableSignaller = xAU5XSIEnableSignaller; +bool xAU5MXSIAllowLongSignals = xAU5XSIAllowLongSignals; +bool xAU5MXSIAllowShortSignals = xAU5XSIAllowShortSignals; + +// +// XTSFI ... +bool xAU5MXTSFIEnableSignaller = xAU5XTSFIEnableSignaller; +bool xAU5MXTSFIAllowLongSignals = xAU5XTSFIAllowLongSignals; +bool xAU5MXTSFIAllowShortSignals = xAU5XTSFIAllowShortSignals; + +// +// XOBDLH ... +bool xAU5MXOBDLHEnableSignaller = xAU5XOBDLHEnableSignaller; +bool xAU5MXOBDLHAllowLongSignals = xAU5XOBDLHAllowLongSignals; +bool xAU5MXOBDLHAllowShortSignals = xAU5XOBDLHAllowShortSignals; + +// +// XCHMACC ... +bool xAU5MXCHMACCEnableSignaller = xAU5XCHMACCEnableSignaller; +bool xAU5MXCHMACCAllowLongSignals = xAU5XCHMACCAllowLongSignals; +bool xAU5MXCHMACCAllowShortSignals = xAU5XCHMACCAllowShortSignals; + +// +// XCHMAMX ... +bool xAU5MXCHMAMXEnableSignaller = xAU5XCHMAMXEnableSignaller; +bool xAU5MXCHMAMXAllowLongSignals = xAU5XCHMAMXAllowLongSignals; +bool xAU5MXCHMAMXAllowShortSignals = xAU5XCHMAMXAllowShortSignals; + +// +// XCHMAMN ... +bool xAU5MXCHMAMNEnableSignaller = xAU5XCHMAMNEnableSignaller; +bool xAU5MXCHMAMNAllowLongSignals = xAU5XCHMAMNAllowLongSignals; +bool xAU5MXCHMAMNAllowShortSignals = xAU5XCHMAMNAllowShortSignals; + +// +XCPriver *xAU5Provider; + +// +// Validate Indicators Inputs ... +bool XAU5ValidateIndicatorsInputs() +{ + // + bool result = false; + + // + // XTM ... + result = XTMValidateInputs(); + if (!result) + { + return result; + } + + // + // XAMA ... + result = XAMAValidateInputs(); + if (!result) + { + return result; + } + + // + // XTD ... + result = XTDValidateInputs(); + if (!result) + { + return result; + } + + // + // XFI ... + result = XFIValidateInputs(); + if (!result) + { + return result; + } + + // + // XTS ... + result = XTSValidateInputs(); + if (!result) + { + return result; + } + + // + // XOBD ... + result = XOBDValidateInputs(); + if (!result) + { + return result; + } + + // + // XLH ... + result = XLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XRSI ... + result = XRSIValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHLH ... + result = XCHLHValidateInputs(); + if (!result) + { + return result; + } + + // + // XCHMA ... + result = XCHMAValidateInputs(); + if (!result) + { + return result; + } + + // + // Make an Instance Of XCPriver Class for Use ... + xAU5Provider = new XCPriver( + // + // Commons ... + _Symbol, + _Period, + // + // Signallers ... + // + // XTD ... + xAU5MXTDEnableSignaller, + xAU5MXTDAllowLongSignals, + xAU5MXTDAllowShortSignals, + // + // XTAM ... + xAU5MXTAMEnableSignaller, + xAU5MXTAMAllowLongSignals, + xAU5MXTAMAllowShortSignals, + // + // XSI ... + xAU5MXSIEnableSignaller, + xAU5MXSIAllowLongSignals, + xAU5MXSIAllowShortSignals, + // + // XTSFI ... + xAU5MXTSFIEnableSignaller, + xAU5MXTSFIAllowLongSignals, + xAU5MXTSFIAllowShortSignals, + // + // XOBDLH ... + xAU5MXOBDLHEnableSignaller, + xAU5MXOBDLHAllowLongSignals, + xAU5MXOBDLHAllowShortSignals, + // + // XCHMACC ... + xAU5MXCHMACCEnableSignaller, + xAU5MXCHMACCAllowLongSignals, + xAU5MXCHMACCAllowShortSignals, + // + // XCHMAMX ... + xAU5MXCHMAMXEnableSignaller, + xAU5MXCHMAMXAllowLongSignals, + xAU5MXCHMAMXAllowShortSignals, + // + // XCHMAMN ... + xAU5MXCHMAMNEnableSignaller, + xAU5MXCHMAMNAllowLongSignals, + xAU5MXCHMAMNAllowShortSignals + // + ); + + // + result = true; + + // + return result; +} + +// +// Init Indicators ... +bool XAU5InitIndicators() +{ + // + bool result = false; + + // + // Make it Enable when we need to Log Market Conditions ... + xAU5IsTestMode = IsRunningOnTestMode(); + + // + // Check and Calculate Max Length in Inputs ... + // + + // + // XTM ... + xAU5MaxLengthOfInputs = MathMax( + xTMMaPeriod, + xAU5NumberOfItemsPerTick); + + // + // XAMA ... + xAU5MaxLengthOfInputs = MathMax( + xAMALength, + xAU5NumberOfItemsPerTick); + xAU5MaxLengthOfInputs = MathMax( + xAMAFastEMA, + xAU5NumberOfItemsPerTick); + xAU5MaxLengthOfInputs = MathMax( + xAMASlowEMA, + xAU5NumberOfItemsPerTick); + + // + // XLH ... + xAU5MaxLengthOfInputs = MathMax( + xLHLength, + xAU5NumberOfItemsPerTick); + + // + // XTD ... + xAU5MaxLengthOfInputs = MathMax( + xTDLength, + xAU5MaxLengthOfInputs); + + // + // XFI ... + xAU5MaxLengthOfInputs = MathMax( + xFILength, + xAU5MaxLengthOfInputs); + + // + // XRSI ... + xAU5MaxLengthOfInputs = MathMax( + xRSILength, + xAU5MaxLengthOfInputs); + + // + // XOBD ... + xAU5MaxLengthOfInputs = MathMax( + xOBDLength, + xAU5MaxLengthOfInputs); + + // + // XCHLH ... + xAU5MaxLengthOfInputs = MathMax( + xCHLHLcLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHLHMcLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHLHScLength, + xAU5MaxLengthOfInputs); + + // + // XCHMA ... + xAU5MaxLengthOfInputs = MathMax( + xCHMAScFastLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHMAScSlowLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHMAMcFastLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHMAMcSlowLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHMALcFastLength, + xAU5MaxLengthOfInputs); + xAU5MaxLengthOfInputs = MathMax( + xCHMALcSlowLength, + xAU5MaxLengthOfInputs); + + // + // Validate Indicators Inputs before Initialization ... + result = XAU5ValidateIndicatorsInputs(); + if (!result) + { + return result; + } + + // + // Validate Signallers ... + + // + // XTD ... + bool isXTDEnable = + xAU5XTDEnableSignaller && + (xAU5XTDAllowLongSignals || + xAU5XTDAllowShortSignals); + + // + // XTAM ... + bool isXTAMEnable = + xAU5XTAMEnableSignaller && + (xAU5XTAMAllowLongSignals || + xAU5XTAMAllowShortSignals); + + // + // XSI ... + bool isXSIEnable = + xAU5XSIEnableSignaller && + (xAU5XSIAllowLongSignals || + xAU5XSIAllowShortSignals); + + // + // XTSFI ... + bool isXTSFIEnable = + xAU5XTSFIEnableSignaller && + (xAU5XTSFIAllowLongSignals || + xAU5XTSFIAllowShortSignals); + + // + // XOBDLH ... + bool isXOBDLHEnable = + xAU5XOBDLHEnableSignaller && + (xAU5XOBDLHAllowLongSignals || + xAU5XOBDLHAllowShortSignals); + + // + // XCHMACC ... + bool isXCHMACCEnable = + xAU5XCHMACCEnableSignaller && + (xAU5XCHMACCAllowLongSignals || + xAU5XCHMACCAllowShortSignals); + + // + // XCHMAMX ... + bool isXCHMAMXEnable = + xAU5XCHMAMXEnableSignaller && + (xAU5XCHMAMXAllowLongSignals || + xAU5XCHMAMXAllowShortSignals); + + // + // XCHMAMN ... + bool isXCHMAMNEnable = + xAU5XCHMAMNEnableSignaller && + (xAU5XCHMAMNAllowLongSignals || + xAU5XCHMAMNAllowShortSignals); + + // + bool hasSignaller = + // + isXTDEnable || + isXTAMEnable || + isXSIEnable || + isXTSFIEnable || + isXOBDLHEnable || + isXCHMACCEnable || + isXCHMAMXEnable || + isXCHMAMNEnable + // + ; + result = hasSignaller; + if (!result) + { + // + LogMessage("XAU5 doesn't enable any Signaller ..."); + + // + return result; + } + + // + // Initialize Indicator/Oscillator Handlers ... + ResetLastError(); + + // + // XTM Init ... + result = XTMInitHandlers(); + if (!result) + { + return result; + } + + // + // XAMA Init ... + result = XAMAInitHandlers(); + if (!result) + { + return result; + } + + // + // XLH Init ... + result = XLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XTD Init ... + result = XTDInitHandlers(); + if (!result) + { + return result; + } + + // + // XFI Init ... + result = XFIInitHandlers(); + if (!result) + { + return result; + } + + // + // XTS Init ... + result = XTSInitHandlers(); + if (!result) + { + return result; + } + + // + // XRSI Init ... + result = XRSIInitHandlers(); + if (!result) + { + return result; + } + + // + // XOBD Init ... + result = XOBDInitHandlers(); + if (!result) + { + return result; + } + + // + // XCLH Init ... + result = XCHLHInitHandlers(); + if (!result) + { + return result; + } + + // + // XCHMA Init ... + result = XCHMAInitHandlers(); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +// Release Indicators ... +void XAU5ReleaseIndicators() +{ + // + // Release Handlers ... + XTMReleaseHandlers(); + XAMAReleaseHandlers(); + XLHReleaseHandlers(); + XTDReleaseHandlers(); + XFIReleaseHandlers(); + XTSReleaseHandlers(); + XRSIReleaseHandlers(); + XOBDReleaseHandlers(); + XCHMAReleaseHandlers(); + XCHLHReleaseHandlers(); +} + +// +// Handle Reading Buffers ... +void XAU5HandleReadingBuffers() +{ + // + // Reading Calculated Bars for a Simple Handler ... + xAU5CalculatedBars = BarsCalculated(xTMHandler); + + // + // Read Indicators Buffers ... + XTMReadBuffers(xAU5NumberOfItemsPerTick); + XAMAReadBuffers(xAU5NumberOfItemsPerTick); + XLHReadBuffers(xAU5NumberOfItemsPerTick); + XTDReadBuffers(xAU5NumberOfItemsPerTick); + XFIReadBuffers(xAU5NumberOfItemsPerTick); + XTSReadBuffers(xAU5NumberOfItemsPerTick); + XRSIReadBuffers(xAU5NumberOfItemsPerTick); + XOBDReadBuffers(xAU5NumberOfItemsPerTick); + XCHMAReadBuffers(xAU5NumberOfItemsPerTick); + XCHLHReadBuffers(xAU5NumberOfItemsPerTick); + + // + xAU5Provider.ReadConditions(); +} + +// +// +// START Combination Functions ... +// +// + +// +// Can Open Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XAU5CanOpenLongTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XAU5HasLongSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + xAU5Provider.ClearConditions(); + } + + // + return result; +} + +// +// Can Close Long Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Long Signals ... +bool XAU5CanCloseLongTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// Can Open Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XAU5CanOpenShortTrade( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + info.tp = 0; + info.sl = 0; + ArrayResize( + info.signallers, + 0); + + // + bool hasSignal = XAU5HasShortSignal(info); + + // + result = + // + hasSignal + // + ; + + // + if (result) + { + xAU5Provider.ClearConditions(); + } + + // + return result; +} + +// +// Can Close Short Trade ... +// this is a Function will Check all market Conditions and get all +// Strategy requirement Verifications for Short Signals ... +bool XAU5CanCloseShortTrade() +{ + // + bool result = false; + + // + return result; +} + +// +// +// END Combination Functions ... +// +// + +// +// +// START Combination Signaling ... +// +// + +// +// Check Market Conditions by Combination of Power of All tools for LONGs ... +bool XAU5HasLongSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XAU5XTDHasLongSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XAU5XTAMHasLongSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XAU5XSIHasLongSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XTSFI ... + bool isXTSFIHasSignal = XAU5XTSFIHasLongSignal(); + if (isXTSFIHasSignal) + { + // + Add( + EnumToString(XTSFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XAU5XOBDLHHasLongSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XAU5XCHMACCHasLongSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMAMNHasSignal = XAU5XCHMAMNHasLongSignal(); + if (isXCHMAMNHasSignal) + { + // + Add( + EnumToString(XCHMAMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMAMXHasSignal = XAU5XCHMAMXHasLongSignal(); + if (isXCHMAMXHasSignal) + { + // + Add( + EnumToString(XCHMAMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXTSFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMAMNHasSignal + // + || + // + isXCHMAMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xAU5IsTestMode || xAU5EnableSignalAlerts) + { + // + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + string message = xAU5Provider.GenerateConditionsString(mConditions); + + // + LogMessage( + "Long Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// Check Market Conditions by Combination of Power of All tools for SHORTs ... +bool XAU5HasShortSignal( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // XTD ... + bool isXTDHasSignal = XAU5XTDHasShortSignal(); + if (isXTDHasSignal) + { + // + Add( + EnumToString(XTD), + info.signallers); + } + + // + // XTAM ... + bool isXTAMHasSignal = XAU5XTAMHasShortSignal(); + if (isXTAMHasSignal) + { + // + Add( + EnumToString(XTAM), + info.signallers); + } + + // + // XSI ... + bool isXSIHasSignal = XAU5XSIHasShortSignal(); + if (isXSIHasSignal) + { + // + Add( + EnumToString(XSI), + info.signallers); + } + + // + // XTSFI ... + bool isXTSFIHasSignal = XAU5XTSFIHasShortSignal(); + if (isXTSFIHasSignal) + { + // + Add( + EnumToString(XTSFI), + info.signallers); + } + + // + // XOBD XLH ... + bool isXOBDLHHasSignal = XAU5XOBDLHHasShortSignal(); + if (isXOBDLHHasSignal) + { + // + Add( + EnumToString(XOBDLH), + info.signallers); + } + + // + // XCHMA Cycles Cross ... + bool isXCHMACCHasSignal = XAU5XCHMACCHasShortSignal(); + if (isXCHMACCHasSignal) + { + // + Add( + EnumToString(XCHMACC), + info.signallers); + } + + // + // XCHMA Cycles Min ... + bool isXCHMAMNHasSignal = XAU5XCHMAMNHasShortSignal(); + if (isXCHMAMNHasSignal) + { + // + Add( + EnumToString(XCHMAMN), + info.signallers); + } + + // + // XCHMA Cycles Max + bool isXCHMAMXHasSignal = XAU5XCHMAMXHasShortSignal(); + if (isXCHMAMXHasSignal) + { + // + Add( + EnumToString(XCHMAMX), + info.signallers); + } + + // + result = + // + isXTDHasSignal + // + || + // + isXTAMHasSignal + // + || + // + isXSIHasSignal + // + || + // + isXTSFIHasSignal + // + || + // + isXOBDLHHasSignal + // + || + // + isXCHMACCHasSignal + // + || + // + isXCHMAMNHasSignal + // + || + // + isXCHMAMXHasSignal + // + ; + + // + if (result) + { + // + // Only Log Signals Time Market Conditions if is in Testing Mode ... + if (xAU5IsTestMode || xAU5EnableSignalAlerts) + { + // + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + string message = xAU5Provider.GenerateConditionsString(mConditions); + + // + LogMessage( + "Short Signal Provided by: \n" + + info.signallers[ArraySize(info.signallers) - 1] + "\n" + + "Pusher: " + (string)ArraySize(info.signallers) + "\n" + + "Market Conditions: " + message); + } + } + + // + return result; +} + +// +// +// END Combination Signaling ... +// +// + +// +// START Signal Providers ... +// + +// +// Disbale All Signallers Longs ... +void XAU5DisableLongSignallers() +{ + // + // XTD ... + if (xAU5MXTDEnableSignaller) + { + // + xAU5Provider.DisbaleXTDLongs(); + xAU5MXTDAllowLongSignals = false; + } + + // + // XTAM ... + if (xAU5MXTAMEnableSignaller) + { + // + xAU5Provider.DisbaleXTAMLongs(); + xAU5MXTAMAllowLongSignals = false; + } + + // + // XSI ... + if (xAU5MXSIEnableSignaller) + { + // + xAU5Provider.DisbaleXSILongs(); + xAU5MXSIAllowLongSignals = false; + } + + // + // XTSFI ... + if (xAU5MXTSFIEnableSignaller) + { + // + xAU5Provider.DisbaleXTSFILongs(); + xAU5MXTSFIAllowLongSignals = false; + } + + // + // XOBDLH ... + if (xAU5MXOBDLHEnableSignaller) + { + // + xAU5Provider.DisbaleXOBDLHLongs(); + xAU5MXOBDLHAllowLongSignals = false; + } + + // + // XCHMACC ... + if (xAU5MXCHMACCEnableSignaller) + { + // + xAU5Provider.DisbaleXCHMACCLongs(); + xAU5MXCHMACCAllowLongSignals = false; + } + + // + // XCHMAMX ... + if (xAU5MXCHMAMXEnableSignaller) + { + // + xAU5Provider.DisbaleXCHMAMXLongs(); + xAU5MXCHMAMXAllowLongSignals = false; + } + + // + // XCHMAMN ... + if (xAU5MXCHMAMNEnableSignaller) + { + // + xAU5Provider.DisbaleXCHMAMNLongs(); + xAU5MXCHMAMNAllowLongSignals = false; + } +} + +// +// Enable All Signallers Longs ... +// Only if they are Configured as Enable at Settings ... +void XAU5EnableLongSignallers() +{ + // + // XTD ... + if (xAU5MXTDEnableSignaller) + { + // + xAU5MXTDAllowLongSignals = + xAU5XTDAllowLongSignals + ? true + : xAU5MXTDAllowLongSignals; + + // + if (xAU5MXTDAllowLongSignals) + { + xAU5Provider.EnableXTDLongs(); + } + } + + // + // XTAM ... + if (xAU5MXTAMEnableSignaller) + { + // + xAU5MXTAMAllowLongSignals = + xAU5XTAMAllowLongSignals + ? true + : xAU5MXTAMAllowLongSignals; + + // + if (xAU5MXTAMAllowLongSignals) + { + xAU5Provider.EnableXTAMLongs(); + } + } + + // + // XSI ... + if (xAU5MXSIEnableSignaller) + { + // + xAU5MXSIAllowLongSignals = + xAU5XSIAllowLongSignals + ? true + : xAU5MXSIAllowLongSignals; + + // + if (xAU5MXSIAllowLongSignals) + { + xAU5Provider.EnableXSILongs(); + } + } + + // + // XTSFI ... + if (xAU5MXTSFIEnableSignaller) + { + // + xAU5MXTSFIAllowLongSignals = + xAU5XTSFIAllowLongSignals + ? true + : xAU5MXTSFIAllowLongSignals; + + // + if (xAU5MXTSFIAllowLongSignals) + { + xAU5Provider.EnableXTSFILongs(); + } + } + + // + // XOBDLH ... + if (xAU5MXOBDLHEnableSignaller) + { + // + xAU5MXOBDLHAllowLongSignals = + xAU5XOBDLHAllowLongSignals + ? true + : xAU5MXOBDLHAllowLongSignals; + + // + if (xAU5MXOBDLHAllowLongSignals) + { + xAU5Provider.EnableXOBDLHLongs(); + } + } + + // + // XCHMACC ... + if (xAU5MXCHMACCEnableSignaller) + { + // + xAU5MXCHMACCAllowLongSignals = + xAU5XCHMACCAllowLongSignals + ? true + : xAU5MXCHMACCAllowLongSignals; + + // + if (xAU5MXCHMACCAllowLongSignals) + { + xAU5Provider.EnableXCHMACCLongs(); + } + } + + // + // XCHMAMX ... + if (xAU5MXCHMAMXEnableSignaller) + { + // + xAU5MXCHMAMXAllowLongSignals = + xAU5XCHMAMXAllowLongSignals + ? true + : xAU5MXCHMAMXAllowLongSignals; + + // + if (xAU5MXCHMAMXAllowLongSignals) + { + xAU5Provider.EnableXCHMAMXLongs(); + } + } + + // + // XCHMAMN ... + if (xAU5MXCHMAMNEnableSignaller) + { + // + xAU5MXCHMAMNAllowLongSignals = + xAU5XCHMAMNAllowLongSignals + ? true + : xAU5MXCHMAMNAllowLongSignals; + + // + if (xAU5MXCHMAMNAllowLongSignals) + { + xAU5Provider.EnableXCHMAMNLongs(); + } + } +} + +// +// Disable All Signallers Shorts ... +void XAU5DisableShortSignallers() +{ + // + // XTD ... + if (xAU5MXTDEnableSignaller) + { + // + xAU5Provider.DisableXTDShorts(); + xAU5MXTDAllowShortSignals = false; + } + + // + // XTAM ... + if (xAU5MXTAMEnableSignaller) + { + // + xAU5Provider.DisableXTAMShorts(); + xAU5MXTAMAllowShortSignals = false; + } + + // + // XSI ... + if (xAU5MXSIEnableSignaller) + { + // + xAU5Provider.DisableXSIShorts(); + xAU5MXSIAllowShortSignals = false; + } + + // + // XTSFI ... + if (xAU5MXTSFIEnableSignaller) + { + // + xAU5Provider.DisableXTSFIShorts(); + xAU5MXTSFIAllowShortSignals = false; + } + + // + // XOBDLH ... + if (xAU5MXOBDLHEnableSignaller) + { + // + xAU5Provider.DisableXOBDLHShorts(); + xAU5MXOBDLHAllowShortSignals = false; + } + + // + // XCHMACC ... + if (xAU5MXCHMACCEnableSignaller) + { + // + xAU5Provider.DisableXCHMACCShorts(); + xAU5MXCHMACCAllowShortSignals = false; + } + + // + // XCHMAMX ... + if (xAU5MXCHMAMXEnableSignaller) + { + // + xAU5Provider.DisableXCHMAMXShorts(); + xAU5MXCHMAMXAllowShortSignals = false; + } + + // + // XCHMAMN ... + if (xAU5MXCHMAMNEnableSignaller) + { + // + xAU5Provider.DisableXCHMAMNShorts(); + xAU5MXCHMAMNAllowShortSignals = false; + } +} + +// +// Enable All Signallers Shorts ... +// Only if they are Configured as Enable at Settings ... +void XAU5EnableShortSignallers() +{ + // + // XTD ... + if (xAU5MXTDEnableSignaller) + { + // + xAU5MXTDAllowShortSignals = + xAU5XTDAllowShortSignals + ? true + : xAU5MXTDAllowShortSignals; + + // + if (xAU5MXTDAllowShortSignals) + { + xAU5Provider.EnableXTDShorts(); + } + } + + // + // XTAM ... + if (xAU5MXTAMEnableSignaller) + { + // + xAU5MXTAMAllowShortSignals = + xAU5XTAMAllowShortSignals + ? true + : xAU5MXTAMAllowShortSignals; + + // + if (xAU5MXTAMAllowShortSignals) + { + xAU5Provider.EnableXTAMShorts(); + } + } + + // + // XSI ... + if (xAU5MXSIEnableSignaller) + { + // + xAU5MXSIAllowShortSignals = + xAU5XSIAllowShortSignals + ? true + : xAU5MXSIAllowShortSignals; + + // + if (xAU5MXSIAllowShortSignals) + { + xAU5Provider.EnableXSIShorts(); + } + } + + // + // XTSFI ... + if (xAU5MXTSFIEnableSignaller) + { + // + xAU5MXTSFIAllowShortSignals = + xAU5XTSFIAllowShortSignals + ? true + : xAU5MXTSFIAllowShortSignals; + + // + if (xAU5MXTSFIAllowShortSignals) + { + xAU5Provider.EnableXTSFIShorts(); + } + } + + // + // XOBDLH ... + if (xAU5MXOBDLHEnableSignaller) + { + // + xAU5MXOBDLHAllowShortSignals = + xAU5XOBDLHAllowShortSignals + ? true + : xAU5MXOBDLHAllowShortSignals; + + // + if (xAU5MXOBDLHAllowShortSignals) + { + xAU5Provider.EnableXOBDLHShorts(); + } + } + + // + // XCHMACC ... + if (xAU5MXCHMACCEnableSignaller) + { + // + xAU5MXCHMACCAllowShortSignals = + xAU5XCHMACCAllowShortSignals + ? true + : xAU5MXCHMACCAllowShortSignals; + + // + if (xAU5MXCHMACCAllowShortSignals) + { + xAU5Provider.EnableXCHMACCShorts(); + } + } + + // + // XCHMAMX ... + if (xAU5MXCHMAMXEnableSignaller) + { + // + xAU5MXCHMAMXAllowShortSignals = + xAU5XCHMAMXAllowShortSignals + ? true + : xAU5MXCHMAMXAllowShortSignals; + + // + if (xAU5MXCHMAMXAllowShortSignals) + { + xAU5Provider.EnableXCHMAMXShorts(); + } + } + + // + // XCHMAMN ... + if (xAU5MXCHMAMNEnableSignaller) + { + // + xAU5MXCHMAMNAllowShortSignals = + xAU5XCHMAMNAllowShortSignals + ? true + : xAU5MXCHMAMNAllowShortSignals; + + // + if (xAU5MXCHMAMNAllowShortSignals) + { + xAU5Provider.EnableXCHMAMNShorts(); + } + } +} + +// +// +// + +// +// XTD Long Signal Checking ... +bool XAU5XTDHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTDEnableSignaller || + !xAU5MXTDAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTDHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTDBearishVale && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDBullOverBear && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedUnderFarest) + // + || + // + ( + (mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentMax) && + ( + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMALCTrendsDown && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTDBullOverBear && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + || + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBullish) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXCHMALCTrendsDown && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverFarest && + mConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXLHLLDecreased && + mConditions.isXCHMAMCTrendsDown && + (mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow)) + // + || + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXAMANeutural) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXLHHHDecreased && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXFIOverZero && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTDBearishVale && + mConditions.isXLHPriceCrossedUnderSignal) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXLHLLIncreased) + // + || + // + // Check if LC Fast Over Slow .. + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check if LC Fast Over Slow .. + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXAMAStartBullish && + mConditions.isXTSCurrentUnderFarest) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXTSCurrentMax && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXCHMALCTrendsUp) + // + || + // + (mConditions.isXAMABearish && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLIncreased && + mConditions.isXTMStartBullish && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXAMAVale && + mConditions.isXAMABearish && + mConditions.isXTSCurrentMax && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMALCVale) + // + || + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverFarest && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + mConditions.isXRSICrossedOverLongExit + // + || + // + // XTD Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCVale && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXTDBearishVale && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderNearest) + // + ) + // + ) + // + || + // + // Check LC Fast Over Slow ... + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLIncreased && + mConditions.isXTDBearishVale && + mConditions.isXCHMALCTrendsDown && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + ((mConditions.isXCHMALCPeak && + mConditions.isXCHMALCTrendsDown) && + ( + // + (mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + (mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHLHSameHHs && + mConditions.isXTSCurrentMax && + mConditions.isXCHMASCCrossedOverMax) + // + || + // + (mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXLHPriceCrossedOverSignal && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + ((mConditions.isXTSCurrentUnderNearest || + mConditions.isXTSCurrentCrossedUnderNearest) && + (mConditions.isXTSCurrentUnderMediest || + mConditions.isXTSCurrentCrossedUnderMediest)) + // + || + // + ((mConditions.isXLHLLIncreased && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + mConditions.isXTSCurrentCrossedUnderFarest + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBearishVale && + mConditions.isXTSCurrentUnderNearest) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXCHMASCCrossedOverMin && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLDecreased && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedUnderFarest && + mConditions.isXTSCurrentCrossedUnderMediest) + // + || + // + ((mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale) && + ( + // + (mConditions.isXFIUnderZero && + mConditions.isXTSCurrentUnderMediest) + // + || + // + (mConditions.isXTSCurrentUnderNearest && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + ((mConditions.isXTMNeutural && + mConditions.isXAMANeutural) && + ( + // + (mConditions.isXTSCurrentMax && + mConditions.isXFICrossedOverZero && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + ((mConditions.isXTDBearishVale && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame) && + ( + // + mConditions.isXTSCurrentMax + // + || + // + mConditions.isXTSCurrentUnderFarest + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + // Check LC Fast Over Slow ... + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXCHMASCOverMax && + mConditions.isXTSCurrentUnderNearest) + // + || + // + ((mConditions.isXTSCurrentMax && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTMStartBullish && + mConditions.isXAMAStartBullish && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + (mConditions.isXCHLHSameHHs && + mConditions.isXCHMASCOverMax && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentCrossedOverFarest && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHMASCOverMax && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSameHHs && + mConditions.isXTDBullOverBear && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + (mConditions.isXTSAllSame && + mConditions.isXLHHHIncreased) + // + || + // + (mConditions.isXTSCurrentMax && + ( + // + mConditions.isXLHHighAttachedHH + // + || + // + (mConditions.isXLHHHIncreased && + mConditions.isXCHMASCOverMax) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check if MC Fast Under Slow ... + ((mConditions.isXCHMAMCFastUnderSlow || + mConditions.isXCHMAMCFastCrossedUnderSlow) && + ( + // + (mConditions.isXAMAEndBullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMAMCTrendsUp) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedUnderNearest) + // + || + (mConditions.isXCHMALCVale && + mConditions.isXTMStartBullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXAMAStartBullish && + mConditions.isXLHHighAttachedHH && + mConditions.isXFICrossedOverZero) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXCHMAMCPeak && + mConditions.isXAMABullish && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax) && + ( + // + (mConditions.isXFIOverZero && + mConditions.isXLHLLDecreased && + mConditions.isXCHLHSCMCHHSame) + // + || + // + (mConditions.isXTDSignalCrossedOverBear && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHLHSCMCHHSame) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCLLSame) + // + ) + // + ) + // + || + // + ((mConditions.isXCHLHSCMCHHSame && + mConditions.isXLHHighAttachedHH && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + mConditions.isXCHLHMCLCLLSame + // + || + // + (mConditions.isXCHMAMCPeak && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXCHMASCOverMin && + mConditions.isXCHMASCUnderMax && + mConditions.isXCHMALCTrendsDown) + // + || + // + (mConditions.isXCHMASCOverMax && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + ((mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale) && + ( + // + (mConditions.isXTMNeutural && + mConditions.isXTMEndBullish && + mConditions.isXTSCurrentMin && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentCrossedUnderFarest) + // + || + // + ((mConditions.isXTMNeutural && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) && + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXFICrossedOverZero && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTSCurrentCrossedOverFarest && + mConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHSCMCLLSame && + mConditions.isXTSCurrentUnderFarest && + mConditions.isXTSCurrentUnderMediest) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXTMStartBullish && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXCHMAMCPeak && + mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXCHMALCTrendsDown && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMASCCrossedOverMax && + mConditions.isXTSCurrentUnderNearest && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax && + mConditions.isXTDSignalCrossedOverBear) && + ( + // + (mConditions.isXCHMASCCrossedOverMin && + mConditions.isXTSCurrentCrossedOverNearest) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXLHPriceCrossedOverSignal) + // + || + // + (mConditions.isXCHMAMCPeak && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCHHSame) + // + || + // + (mConditions.isXCHMALCTrendsDown && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check LC Fast Over Slow ... + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTSCurrentMax && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalCrossedOverBear) + // + || + // + (mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXCHMALCPeak && + mConditions.isXCHLHSameLLs && + mConditions.isXTSCurrentMax && + mConditions.isXLHHighAttachedHH && + (mConditions.isXTDBullOverBear || + mConditions.isXTDSignalCrossedOverBear)) + // + ) + // + ) + // + || + // + // Check LC Fast Under Slow ... + ((mConditions.isXCHMALCFastUnderSlow || + mConditions.isXCHMALCFastCrossedUnderSlow) && + ( + // + ((mConditions.isXTMBullish && + mConditions.isXAMABullish && + mConditions.isXTSCurrentMax) && + ( + // + (mConditions.isXLHHighAttachedHH && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHLHSameHHs) + // + || + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest && + mConditions.isXTSCurrentCrossedOverMediest) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDBearishVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDSignalCrossedOverBear && + mConditions.isXTSCurrentCrossedOverNearest) + // + ) + // + ) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXLHLLIncreased && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTDSignalCrossedOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXAMANeutural && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTSCurrentUnderFarest) + // + ) + // + ) + // + || + // + // XTD Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTD Short Signal Checking ... +bool XAU5XTDHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTDEnableSignaller || + !xAU5MXTDAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTDHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if SC Fast Over Slow ... + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMax && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXTSCurrentMax && + mConditions.isXAMAEndBullish && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMASCTrendsUp) + // + ) + // + ) + // + || + // + // Check if MC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXTSCurrentOverFarest) + // + || + // + (mConditions.isXCHMALCVale && + ( + // + mConditions.isXCHMALCTrendsDown + // + || + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullOverBear) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if MC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverNearest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check if MC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHLHSameLLs && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullOverBear && + mConditions.isXCHMAMCTrendsUp && + mConditions.isXLHLowAttachedLL) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + (mConditions.isXTMNeutural && + mConditions.isXAMANeutural && + mConditions.isXTDBullOverBear && + mConditions.isXCHMASCTrendsDown && + mConditions.isXTSCurrentOverNearest && + mConditions.isXCHMASCFastCrossedUnderSlow) + // + || + // + // Check if SC Fast Over Slow ... + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverNearest) + // + || + // + (mConditions.isXTMEndBearish && + mConditions.isXAMAEndBearish && + mConditions.isXTSCurrentOverNearest) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXTSCurrentMin && + mConditions.isXLHHHDecreased && + mConditions.isXTDBullOverBear) + // + || + // + (mConditions.isXTMBearish && + mConditions.isXAMABearish && + mConditions.isXCHMASCPeak && + mConditions.isXLHHHDecreased && + mConditions.isXTDBullOverBear && + mConditions.isXTSCurrentOverFarest) + // + || + // + ((mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXTMStartBearish && + mConditions.isXTDBullOverBear && + mConditions.isXAMAStartBearish) && + ( + // + (mConditions.isXCHLHMCLCLLSame && + mConditions.isXCHMAMCTrendsDown) + // + || + // + (mConditions.isXCHLHSCMCHHSame && + mConditions.isXCHMAMCTrendsDown && + mConditions.isXTDSignalCrossedUnderBear) + // + || + // + (mConditions.isXCHMASCPeak && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTDSignalCrossedUnderBear && + mConditions.isXTSCurrentCrossedUnderFarest && + mConditions.isXTSCurrentCrossedUnderMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check if MC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMASCPeak && + mConditions.isXAMANeutural && + mConditions.isXTSCurrentMin && + mConditions.isXTDBullOverBear && + mConditions.isXCHMALCTrendsDown && + mConditions.isXLHPriceCrossedUnderSignal) + // + ) + // + ) + // + || + // + // Check LC Fast Over Slow ... + ((mConditions.isXCHMALCFastOverSlow || + mConditions.isXCHMALCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCPeak && + mConditions.isXTDBullOverBear && + mConditions.isXTMStartBearish && + mConditions.isXAMAStartBearish && + mConditions.isXTSCurrentOverNearest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check if SC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + ((mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCHHSame && + mConditions.isXAMAStartBearish) && + ( + // + mConditions.isXTSCurrentOverFarest + // + || + // + (mConditions.isXTSCurrentMin && + mConditions.isXCHMALCTrendsUp) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if SC Fast Over Slow ... + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXTDBullOverBear && + mConditions.isXCHLHMCLCLLSame && + mConditions.isXTSCurrentOverFarest) + // + ) + // + ) // + ) + // + ) + // + || + // + // XTD Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + // + // Check if SC Fast Over Slow ... + ((mConditions.isXCHMASCFastOverSlow || + mConditions.isXCHMASCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMALCVale && + mConditions.isXCHLHSCMCHHSame && + mConditions.isXTSCurrentOverFarest && + mConditions.isXTSCurrentOverMediest) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + // + // Check if MC Fast Over Slow ... + ((mConditions.isXCHMAMCFastOverSlow || + mConditions.isXCHMAMCFastCrossedOverSlow) && + ( + // + (mConditions.isXCHMAMCPeak && + mConditions.isXCHMAMCTrendsUp) + // + || + // + (mConditions.isXCHMALCVale && + mConditions.isXTSCurrentMin && + mConditions.isXLHHHIncreased && + mConditions.isXTDBullOverBear && + mConditions.isXCHMALCTrendsDown) + // + ) + // + ) + // + ) + // + ) + // + || + // + // XTD Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTD Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTD Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTAM Long Signal Checking ... +bool XAU5XTAMHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTAMEnableSignaller || + !xAU5MXTAMAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTAMHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTAM Short Signal Checking ... +bool XAU5XTAMHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTAMEnableSignaller || + !xAU5MXTAMAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTAMHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTAM Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTAM Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XSI Long Signal Checking ... +bool XAU5XSIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXSIEnableSignaller || + !xAU5MXSIAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XSIHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XSI Short Signal Checking ... +bool XAU5XSIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXSIEnableSignaller || + !xAU5MXSIAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XSIHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XSI Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XSI Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTSFI Long Signal Checking ... +bool XAU5XTSFIHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTSFIEnableSignaller || + !xAU5MXTSFIAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTSFIHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XTSFI Short Signal Checking ... +bool XAU5XTSFIHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXTSFIEnableSignaller || + !xAU5MXTSFIAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XTSFIHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XTSFI Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XTSFI Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XOBDLH Long Signal Checking ... +bool XAU5XOBDLHHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXOBDLHEnableSignaller || + !xAU5MXOBDLHAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XOBDLHHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XOBDLH Short Signal Checking ... +bool XAU5XOBDLHHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXOBDLHEnableSignaller || + !xAU5MXOBDLHAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XOBDLHHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XOBDLH Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XOBDLH Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMACC Long Signal Checking ... +bool XAU5XCHMACCHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMACCEnableSignaller || + !xAU5MXCHMACCAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMACCHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMACC Short Signal Checking ... +bool XAU5XCHMACCHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMACCEnableSignaller || + !xAU5MXCHMACCAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMACCHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMACC Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMACC Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMN Long Signal Checking ... +bool XAU5XCHMAMNHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMAMNEnableSignaller || + !xAU5MXCHMAMNAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMAMNHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMN Short Signal Checking ... +bool XAU5XCHMAMNHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMAMNEnableSignaller || + !xAU5MXCHMAMNAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMAMNHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMN Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMN Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMX Long Signal Checking ... +bool XAU5XCHMAMXHasLongSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMAMXEnableSignaller || + !xAU5MXCHMAMXAllowLongSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMAMXHasLongConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Long ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Long ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Long ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Long ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Long ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// XCHMAMX Short Signal Checking ... +bool XAU5XCHMAMXHasShortSignal() +{ + // + bool result = false; + + // + // Validate Args ... + if (!xAU5MXCHMAMXEnableSignaller || + !xAU5MXCHMAMXAllowShortSignals) + { + return result; + } + + // + // Retrieve Market Condition ... + XMarketConditions mConditions = xAU5Provider.GetLastMarketCondition(); + + // + // Start Analysing Market based On Conditions ... + result = + // + // Base Condition: + xAU5Provider.XCHMAMXHasShortConditions() + // + && + // + // Exceptions: + // there some commonly Exceptions which makes our choice incorrect, + // here we are combined knownly Exceptions ... + !( + // + // for Exception we used XLH Conditions as follow ... + // + // Check Conditions if Price In Signal Range ... + (mConditions.isXLHPriceInSignalRange && + // + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Short ... + // PriceInSignalRange ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceInSignalRange ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceInSignalRange ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceInSignalRange ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Under Signal ... + ( + // + ((mConditions.isXLHPriceUnderSignal || + mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Short ... + // PriceUnderSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceUnderSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceUnderSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceUnderSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is Over Signal ... + ( + // + ((mConditions.isXLHPriceOverSignal || + mConditions.isXLHPriceCrossedOverSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Short ... + // PriceOverSignal ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceOverSignal ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceOverSignal ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceOverSignal ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + || + // + // Check Conditions if Price is not has clear state ... + ( + // + ((!mConditions.isXLHPriceOverSignal && + !mConditions.isXLHPriceUnderSignal && + !mConditions.isXLHPriceInSignalRange && + !mConditions.isXLHPriceCrossedOverSignal && + !mConditions.isXLHPriceCrossedUnderSignal) && + ( + // + // Next Step is to Check LL and HH Same Style ... + // + // XCHMAMX Short ... + // PriceFree ... + // Check if Both LL and HH Same In Length ... + ((mConditions.isXLHLLSameInLength && + mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceFree ... + // Check If LL Same In Length ... + ((mConditions.isXLHLLSameInLength && + !mConditions.isXLHHHSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceFree ... + // Check If HH is Same In Length ... + ((mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + || + // + // XCHMAMX Short ... + // PriceFree ... + // Not Same LL or HH in Lenght ... + ((!mConditions.isXLHHHSameInLength && + !mConditions.isXLHLLSameInLength) && + // + ( + false) + // + ) + // + ) + // + ) + // + ) + // + ) + // + ; + + // + return result; +} + +// +// END Signal Providers ... +// diff --git a/Providers/x-saherelm.xau5.provider.inputs.lib.mq5 b/Providers/x-saherelm.xau5.provider.inputs.lib.mq5 new file mode 100644 index 00000000..3989003f --- /dev/null +++ b/Providers/x-saherelm.xau5.provider.inputs.lib.mq5 @@ -0,0 +1,283 @@ +/////////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAU5 Signal Provider Library Inputs +// ----------------------------------------------------------- +// +// 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 Logger ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Classes ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +input group "XAU5 Provider"; + +// +// Commonly Used Configurations ... +input group "XAU5 Common"; +// +// Provider ... +input bool xAU5EnableProvider = true; // Enable Provider +input int xAU5NumberOfItemsPerTick = 30; // Number Of items Readed In Each Tick +// +// Alerts ... +input bool xAU5EnableAlerts = true; // Enable Events Alert +input bool xAU5EnableHourlyAlerts = false; // Send Alert on each new Hour +input bool xAU5EnableDailyAlerts = true; // Send Alert on each new Day +input bool xAU5EnableWeeklyAlerts = true; // Send Alert on each new Week +input bool xAU5EnableMonthlyAlerts = true; // Send Alert on each new Month +// +// Reports ... +input bool xAU5EnableDailyReports = false; // Send Report on each new Day +input bool xAU5EnableWeeklyReports = false; // Send Report on each new Week +input bool xAU5EnableMonthlyReports = false; // Send Report on each new Month + +// +// Trader and Expert Specific Configurations ... +input group "XAU5 Trader"; +input int xAU5MagicNumber = 16940561; // Trader MagicNumber +input int xAU5Slippage = 10; // Trader Slippage + +// +// Trades Management Configurations ... +input group "XAU5 Trade Management"; +input bool xAU5AllowLongTrades = true; // Allow Long Trades +input bool xAU5AllowShortTrades = true; // Allow Short Trades + +// +// Risk Management Configurations ... +input group "XAU5 Risk Management"; +// +// Trade Count ... +input int xAU5MaxAllowedTrades = 10; // Max Allowed Trades at Same Time +input ENUM_X_CROSS_SIGNAL_METHOD xAU5CrossSignalsMethod = X_CROSS_SIGNAL_REGULAR; // Handle Cross Signals Method +// +// Max Allowed Trade Age ... +input int xAU5MaxAllowedTradeAge = 1800; // Detect Long Time Trades +input ENUM_X_GUARD_ACTIONS xAU5OldTradesAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1; // What to do with Old Trades +// +// Trade Volume Specific Configurations ... +input double xAU5StaticVolumeFactor = 0.0002; // Static Volume baesd on Balance +input ENUM_STATIC_VOLUME_METHODS xAU5StaticVolumeMethod = X_STATIC_VOLUME_BASED_ON_BALANCE; // How to Calculate Static Volume +input double xAU5VolumeMultiplier = 0; // Volume Increase Multiplier +input double xAU5ApplyVolumeMultiplierFactor = 0; // Apply Volume Multiplier Rate based on Balance +input double xAU5MaxSupportedVolumePerTradeFactor = 0; // Max Supported Volume Per Trade Factor based on Balance +input double xAU5IncreasedMaxSupportedVolumeRate = 0; // Increase Max Supported Volume based on Balance +// +// Trade Profits ... +input double xAU5MinRewardInPips = 150; // Minimum Reward Per Trade in Pips +input double xAU5RiskFreeStepInPips = 60; // Make Trades Risk Free Steps in Pips +input double xAU5RiskFreeRate = 0.6; // Volume Multiplier for Risk Free Trades +// +// Guard Riskable Money and Profits ... +input double xAU5CriticalDrawDownFactor = 0.30; // Critical Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xAU5CriticalGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5; // Specify Guard Action on Critical Drawdown +input double xAU5MaxAllowedDrawDownFactor = 0.40; // Max Allowed Drawdown Factor based on Balance +input ENUM_X_GUARD_ACTIONS xAU5MaxAllowedGuardAction = X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10; // Specify Guard Action on Max Allowed Drawdown +input int xAU5GuardStopoutFiredAfterTouches = 5; // Guard Stopout all Trades if Max Allowed Drawdown touched + +// +// Account Conditions for Trading ... +input double xAU5BalanceFactorForOpenTrades = 0.5; // Minimum Balance for Open Trades +input double xAU5FreeMarginFactorForOpenTrades = 0.8; // Minimum Free Margin for Open Trades + +// +// May be Used Later as Input Params ... +bool xAU5UseVirtualTPSl = false; // Use Virtual TP SL +bool xAU5EnableSignalAlerts = false; // Send Signal Alert + +// +// Validate Inputs before Initialization ... +bool XAU5ValidateInputs() +{ + // + bool result = false; + + // + // Implement Other Verifications ... + + // + // Check Trading Availability ... + bool isTradeAvailable = xAU5AllowLongTrades || xAU5AllowShortTrades; + if (!isTradeAvailable) + { + LogMessage("XAU5 => Warning: Trading disabled ..."); + } + + // + // Chekc Number of reading items per tick ... + result = xAU5NumberOfItemsPerTick >= 5; + if (!result) + { + // + LogMessage("XAU5 invalid Number of items Reading Per Tick ..."); + + // + return result; + } + + // + // Check Max Allowed Trades Count ... + result = isTradeAvailable && xAU5MaxAllowedTrades >= 1; + if (!result) + { + // + LogMessage("XAU5 Number of Trades not valid ..."); + + // + return result; + } + + // + // Check Free Margin ... + result = + isTradeAvailable && + xAU5FreeMarginFactorForOpenTrades > 0 && + xAU5FreeMarginFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XAU5 Invalid Free Margin ..."); + + // + return result; + } + + // + // Check min Balance for Open Trades ... + result = + isTradeAvailable && + xAU5BalanceFactorForOpenTrades > 0 && + xAU5BalanceFactorForOpenTrades < 1; + if (!result) + { + // + LogMessage("XAU5 Invalid Min Balance for Open Trades ..."); + + // + return result; + } + + // + // Check Min Reward Per Trade ... + result = xAU5MinRewardInPips > 0; + if (!result) + { + // + LogMessage("XAU5 Invalid Min Reward Per Trade ..."); + + // + return result; + } + + // + // Check Trades Volume ... + result = xAU5StaticVolumeFactor > 0; + if (!result) + { + // + LogMessage("XAU5 Invalid Static Volume ..."); + + // + return result; + } + + // + // Check Volume Multiplier ... + result = xAU5VolumeMultiplier >= 0; + if (!result) + { + // + LogMessage("XAU5 Invalid Volume Multiplier ..."); + + // + return result; + } + + // + result = + xAU5CriticalDrawDownFactor == 0 || (xAU5CriticalDrawDownFactor > 0 && + xAU5CriticalDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XAU5 Invalid Critical DrawDown Factor ..."); + + // + return result; + } + + // + result = + xAU5MaxAllowedDrawDownFactor == 0 || (xAU5MaxAllowedDrawDownFactor > 0 && + xAU5MaxAllowedDrawDownFactor < 1); + if (!result) + { + // + LogMessage("XAU5 Invalid Max Allowed DrawDown Factor ..."); + + // + return result; + } + + // + // Check Guard Actions ... + // + result = + xAU5CriticalDrawDownFactor > 0 && + xAU5CriticalDrawDownFactor < 1 && + xAU5MaxAllowedDrawDownFactor > 0 && + xAU5MaxAllowedDrawDownFactor < 1; + if (!result) + { + // + LogMessage("XAU5 For Critical Drawdown, you have to Specify Max Drawdown also ..."); + + // + return result; + } + + // + result = xAU5CriticalDrawDownFactor > 0 && xAU5CriticalDrawDownFactor < xAU5MaxAllowedDrawDownFactor; + if (!result) + { + // + LogMessage("XAU5 Critical Drawdown must Smaller than Max Drawdown ..."); + + // + return result; + } + + // + if (xAU5CriticalDrawDownFactor > 0 && xAU5CriticalGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XAU5 IMPORTANT you Specified Critical Drawdown, but there is no any Guard Action ..."); + } + + // + if (xAU5MaxAllowedDrawDownFactor > 0 && xAU5MaxAllowedGuardAction == X_GUARD_DO_NOTHING) + { + LogMessage("XAU5 IMPORTANT you Specified Max Allowed Drawdown, but there is no any Guard Action ..."); + } + + // + result = true; + + // + return result; +} \ No newline at end of file diff --git a/Providers/x-saherelm.xau5.provider.lib.mq5 b/Providers/x-saherelm.xau5.provider.lib.mq5 new file mode 100644 index 00000000..96e5fdbd --- /dev/null +++ b/Providers/x-saherelm.xau5.provider.lib.mq5 @@ -0,0 +1,1373 @@ +//////////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 XAU5 Signal Provider Library +// -------------------------------------------------------- +// Name: XAU5SignalProvider +// Description: XAU5 based 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 + +#define XAU5ProviderName "XAU5" + +// +// START Inputs ... +// + +#include "x-saherelm.xau5.provider.inputs.lib.mq5"; + +// +// END Inputs ... +// + +// +// Include Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Include Logger Library ... +#include "../Libraries/x-saherelm.log.lib.mq5" + +// +// Include Alert Library ... +#include "../Libraries/x-saherelm.alert.lib.mq5" + +// +// Include Draw Library ... +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Include Class Libraries ... +#include "../Classes/x-saherelm.class.lib.mq5" + +// +// START Global Definitions: Variables, Properties and etc ... +// + +// +XCGuard *xAU5Guard; +XCTrade *xAU5Trader; +XCReporter *xAU5Reporter; +XCCollector *xAU5Collector; +XCAccountInfo *xAU5AccountInfo; +XCVolumeManager *xAU5VolumeManager; + +// +#include "x-saherelm.xau5.provider.indicators.lib.mq5" + +// +// Controlling Variables ... +bool xAU5MEnableProvider = false; +bool xAU5MAllowLongTrades = false; +bool xAU5MAllowShortTrades = false; + +// +double xAU5Deposit = 0; +double xAU5Balance = 0; +double xAU5MinReward = 0; +double xAU5FreeMargin = 0; +double xAU5BalanceForOpenTrades = 0; +double xAU5FreeMarginForOpenTrades = 0; + +// +// Guard ... +double xAU5CriticalDrawDown = 0; +double xAU5MaxAllowedDrawDown = 0; + +// +double xAU5MaxDrawUp = 0; +double xAU5MaxDrawDown = 0; + +// +int NOT_ENOUGH_MONEY_ERROR = 4756; +const string XAU5_SUPPORT_ID = "SP"; + +// +// END Global Definitions: Variables, Properties and etc ... +// + +// +// START Provided Functions ... +// + +// +// Initial Library if required ... +bool XAU5InitSignalProviderLibrary() +{ + // + bool result = false; + + // + if (!xAU5EnableProvider) + { + return result; + } + + // + // Controlling Variables ... + xAU5MEnableProvider = xAU5EnableProvider; + xAU5MAllowLongTrades = xAU5AllowLongTrades; + xAU5MAllowShortTrades = xAU5AllowShortTrades; + + // + // Validate Inputs ... + result = XAU5ValidateInputs(); + if (!result) + { + return result; + } + + // + // Init Indicators ... + result = XAU5InitIndicators(); + if (!result) + { + return result; + } + + // + xAU5Reporter = new XCReporter(); + xAU5Collector = new XCCollector(); + xAU5AccountInfo = new XCAccountInfo(); + + // + // Calculate Account Deposit ... + xAU5Deposit = xAU5AccountInfo.GetInitialBalance(); + + // + // Prepare Min Reward ... + if (xAU5MinRewardInPips > 0) + { + xAU5MinReward = PipsToPrice(xAU5MinRewardInPips); + } + + // + // Calculate Min Balance for Trades ... + if (xAU5BalanceFactorForOpenTrades > 0) + { + xAU5BalanceForOpenTrades = xAU5BalanceFactorForOpenTrades * xAU5Deposit; + } + + // + // Claculate Min Free Marging for Trades ... + if (xAU5FreeMarginFactorForOpenTrades > 0) + { + xAU5FreeMarginForOpenTrades = xAU5FreeMarginFactorForOpenTrades * xAU5Deposit; + } + + // + // Calculate Init Time Critical DrawDown Value ... + if (xAU5CriticalDrawDownFactor > 0) + { + xAU5CriticalDrawDown = xAU5CriticalDrawDownFactor * xAU5Deposit; + } + + // + // Calculate Init Time Max Allowed DrawDown Value ... + if (xAU5MaxAllowedDrawDownFactor > 0) + { + xAU5MaxAllowedDrawDown = xAU5MaxAllowedDrawDownFactor * xAU5Deposit; + } + + // + // Instant Volume Manager ... + xAU5VolumeManager = new XCVolumeManager( + xAU5StaticVolumeFactor, + xAU5StaticVolumeMethod, + xAU5VolumeMultiplier, + xAU5ApplyVolumeMultiplierFactor, + xAU5MaxSupportedVolumePerTradeFactor, + xAU5IncreasedMaxSupportedVolumeRate); + + // + // Make XCTrader instance ... + xAU5Trader = new XCTrade( + XAU5ProviderName, + _Symbol, + xAU5Slippage, + xAU5MagicNumber, + xAU5UseVirtualTPSl, + xAU5MaxAllowedTrades, + xAU5FreeMarginForOpenTrades, + xAU5BalanceForOpenTrades); + + // + // Instantiate Account Guard ... + xAU5Guard = new XCGuard( + // + // Old Trades ... + xAU5MaxAllowedTradeAge, + xAU5OldTradesAction, + // + // Critical DrawDown ... + xAU5CriticalDrawDownFactor, + xAU5CriticalGuardAction, + // + // Max Allowed DrawDown ... + xAU5MaxAllowedDrawDownFactor, + xAU5MaxAllowedGuardAction, + xAU5GuardStopoutFiredAfterTouches, + // + // xAU5GuardSupportMethod + X_SUPPORT_DO_NOTHING + // + ); + + // + // Reset Calculations Buffers and Variables ... + XAU5ResetCollectors(); + + // + XAU5UpdateReports(); + + // + result = true; + + // + // Logging State ... + XAU5IssueInitializationSucceedAlert(); + + // + return result; +} + +// +// DeInitial Library if required ... +void XAU5DeinitSignalProviderLibrary(const int reason) +{ + // + // Release Handlers ... + XAU5ReleaseIndicators(); + + // + // Logging State ... + XAU5IssueDeinitializationSucceedAlert(); +} + +// +// this is a Globally Function which do all of +// checkings and positions handling ... +void XAU5SignalProviderHandleTick() +{ + // + // Check Provider is Enable or Not ... + if (!xAU5MEnableProvider) + { + return; + } + + // + XAU5SignalProviderDoControlState(); + + // + // Reading Indicator Buffers ... + XAU5HandleReadingBuffers(); + if (xAU5CalculatedBars < xAU5MaxLengthOfInputs) + { + return; + } + + // + // Handle Open Trades ... + XAU5HandleOpenTrades(); + + // + // Handle Close Trades ... + XAU5HandleCloseTrades(); + + // + // DrawDown and DrawUp ... + XAU5HandleCalculateDrawDownUp(); +} + +// +// Do Control Checks here ... +void XAU5SignalProviderDoControlState() +{ + // + // Update account Balance ... + xAU5Balance = xAU5AccountInfo.GetBalance(); + xAU5FreeMargin = xAU5AccountInfo.GetFreeMargin(); + + // + // Check Provider is Enable or Not ... + if (!xAU5MEnableProvider) + { + return; + } + + // + // Protect Account by Guarding Maximum Drawdown ... + // TODO: add Guard Result here ... + string guardMessage = ""; + XGuardHandlerResult guardHandlerResult; + bool isGuarded = xAU5Guard.Guard( + guardHandlerResult, + guardMessage, + xAU5Trader, + _Period); + if (isGuarded) + { + // + // Criticals ... + int criticalsCount = ArraySize(guardHandlerResult.criticals); + if (criticalsCount > 0) + { + // + for (int i = 0; i < criticalsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.criticals[i]; + + // + XAU5OnGuard( + iSignal, + X_GUARDED_CRITICAL, + guardMessage); + } + } + + // + // Maxes ... + int maxesCount = ArraySize(guardHandlerResult.maxes); + if (maxesCount > 0) + { + // + for (int i = 0; i < maxesCount; i++) + { + // + XSignal iSignal = guardHandlerResult.maxes[i]; + + // + XAU5OnGuard( + iSignal, + X_GUARDED_MAX, + guardMessage, + guardHandlerResult.isStopOut); + } + } + + // + // Olds ... + int oldsCount = ArraySize(guardHandlerResult.olds); + if (oldsCount > 0) + { + // + for (int i = 0; i < oldsCount; i++) + { + // + XSignal iSignal = guardHandlerResult.olds[i]; + + // + XAU5OnGuard( + iSignal, + X_GUARDED_OLD, + guardMessage); + } + } + } + + // + // Signal Protection ... + XSignal protectSupports[]; + bool isSupported = xAU5Guard.ProtectSignals( + protectSupports, + xAU5Trader); + if (isSupported) + { + // + LogMessage("Guard do Support Trdae ..."); + } + + // + // Handling Signals ... + XTraderHandlerResult signalHandlerResult; + xAU5Trader.HandleSignals( + signalHandlerResult, + false // Ignore Risk Free Trdaes + ); + + // + // Handle Sl Reports ... + int handledSLsCount = ArraySize(signalHandlerResult.sl); + if (handledSLsCount > 0) + { + // + for (int i = 0; i < handledSLsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.sl[i]; + XAU5OnSL(iSignal); + } + } + + // + // Handle TP Reports ... + int handledTPsCount = ArraySize(signalHandlerResult.tp); + if (handledTPsCount > 0) + { + // + for (int i = 0; i < handledTPsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.tp[i]; + XAU5OnTP(iSignal); + } + } + + // + // Handle RFs as TP Reports ... + int handledRFsCount = ArraySize(signalHandlerResult.rf); + if (handledRFsCount > 0) + { + // + for (int i = 0; i < handledRFsCount; i++) + { + // + XSignal iSignal = signalHandlerResult.rf[i]; + XAU5OnRF(iSignal); + } + } +} + +// +// Handle Trades when OnTrade Event Hnadler Calls ... +void XAU5SignalProviderHandleTrade() +{ + // + // Check Provider Enabled ... + if (!xAU5MEnableProvider) + { + return; + } + + // + // Handle OnTrade Event ... + XOnTradeHandlerResult result = {}; + xAU5Trader.HandleOnTradeEvent( + result); + + // + // Detected TP or SL ... + if (result.hasNewDeal) + { + // + XDeal last = xAU5Trader.GetLastDeal(); + + // + if (last.reason == DEAL_REASON_SL) + { + xAU5Reporter.AddTradeSLInReports(); + } + else if (last.reason == DEAL_REASON_TP) + { + xAU5Reporter.AddTradeTPInReports(); + } + } +} + +// +// Handle Open Trades ... +void XAU5HandleOpenTrades() +{ + // + // Check Can Trade ... + bool canTrade = xAU5MAllowLongTrades || xAU5MAllowShortTrades; + if (!canTrade) + { + return; + } + + // + // Check Max Open Trades ... + int openSignals = xAU5Trader.Count(); + bool canOpenPositions = openSignals < xAU5MaxAllowedTrades; + if (!canOpenPositions) + { + return; + } + + // + // Check Signals Exists ... + XProvidedSignal longSignalInfo; + XProvidedSignal shortSignalInfo; + bool hasLongSignal = XAU5CanOpenLongTrade(longSignalInfo); + bool hasShortSignal = XAU5CanOpenShortTrade(shortSignalInfo); + if (!hasLongSignal && !hasShortSignal) + { + return; + } + + // + // Update Reports ... + XAU5UpdateReports(); + + // + xAU5WaitUntilNextCandle = true; + + // + // Open Long Trades ... + if ( + // + hasLongSignal && + xAU5MAllowLongTrades) + { + // + bool isOpened = XAU5OpenLongPosition(longSignalInfo); + } + + // + // Open Short Trades ... + if ( + // + hasShortSignal && + xAU5MAllowShortTrades) + { + // + bool isOpened = XAU5OpenShortPosition(shortSignalInfo); + } +} + +// +// Handle Close Trades ... +void XAU5HandleCloseTrades() +{ + // + // Force Close Long Trades ... + bool isClosedLongTrades = false; + bool canCloseLongTrades = XAU5CanCloseLongTrade(); + if (xAU5MAllowLongTrades && canCloseLongTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_LONG; + + // + XSignal closed[]; + xAU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedLongTrades = closedTradesCount > 0; + if (isClosedLongTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XAU5OnFC(iSignal); + } + } + } + + // + // Force Close Short Trades ... + bool isClosedShortTrades = false; + bool canCloseShortTrades = XAU5CanCloseShortTrade(); + if (xAU5MAllowShortTrades && canCloseShortTrades) + { + // + ENUM_X_SIGNAL_TYPE type = X_SIGNAL_SHORT; + + // + XSignal closed[]; + xAU5Trader.CloseSignals( + closed, + type); + + // + int closedTradesCount = ArraySize(closed); + isClosedShortTrades = closedTradesCount > 0; + if (isClosedShortTrades) + { + // + for (int i = 0; i < closedTradesCount; i++) + { + // + XSignal iSignal = closed[i]; + XAU5OnFC(iSignal); + } + } + } +} + +// +// Open Long Position ... +bool XAU5OpenLongPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_LONG); + double sl = info.sl > 0 ? info.sl : 0; + // entry - (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry + xAU5MinReward; + double riskFreeRate = xAU5RiskFreeRate; + double riskFreeStep = xAU5RiskFreeStepInPips; + double volume = XAU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xAU5Trader.GenerateSignal( + X_SIGNAL_LONG, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xAU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xAU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XAU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xAU5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xAU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + // + // Update Reports ... + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xAU5Trader.GetSignal(signal.ticket); + + // + XAU5OnSignal( + tSignal, + providers); + } + else + { + XAU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Open Short Position ... +bool XAU5OpenShortPosition( + XProvidedSignal &info // Retrieve Signal Additional Info on this Object +) +{ + // + bool result = false; + + // + // Calculate Required Data for Position ... + double entry = GetEntry(_Symbol, X_SIGNAL_SHORT); + double sl = info.sl > 0 ? info.sl : 0; + // entry + (200 * _Point); + // info.sl > 0 ? info.sl : 0; + double tp = info.tp > 0 ? info.tp : entry - xAU5MinReward; + double riskFreeRate = xAU5RiskFreeRate; + double riskFreeStep = xAU5RiskFreeStepInPips; + double volume = XAU5CalculateVolume(ArraySize(info.signallers)); + + // + XSignal signal = {}; + signal = xAU5Trader.GenerateSignal( + X_SIGNAL_SHORT, + tp, + sl, + volume, + riskFreeStep, + riskFreeRate); + bool isValidSignal = IsValid( + signal, + xAU5MagicNumber); + if (!isValidSignal) + { + return result; + } + + // + int signalsCount = xAU5Trader.Count(); + bool isCross = signalsCount >= 1; + if (isCross) + { + // + // Handle Cross Signals ... + XAU5HnadleCrossSignal(signal); + } + + // + // Retrieve Can Execute Signal or not ... + bool canExecuteSignal = + !isCross + // + || + // + ( + // + isCross && + xAU5CrossSignalsMethod != X_CROSS_SIGNAL_DO_NOTHING + // + ); + if (!canExecuteSignal) + { + return result; + } + + // + // Execute Signal ... + ENUM_EXECUTION_SIGNAL_RESULT executionResult = xAU5Trader.ExecuteSignal( + signal, + false, // Ignore Number of Trades ... + true // Check Account Conditions ... + ); + result = executionResult == X_TRADER_SUCCEED_EXECUTION; + if (result) + { + string providers[]; + ArrayCopy( + providers, + info.signallers + ); + + // + XSignal tSignal = xAU5Trader.GetSignal(signal.ticket); + + // + XAU5OnSignal( + tSignal, + providers); + } + else + { + XAU5IssueSignalExecutionError(executionResult); + } + + // + return result; +} + +// +// Apply Cross Signal Actions ... +void XAU5HnadleCrossSignal( + XSignal &signal // Specified Signal ... +) +{ + // + // Check Cross Signal Handling Enabled ... + if (xAU5CrossSignalsMethod == X_CROSS_SIGNAL_DO_NOTHING) + { + return; + } + + // + // First We have to Change Cross Signals Comment ... + string comment = xAU5Trader.GenerateSignalComment( + signal, + true); + + // + signal.comment = comment; + + // + // If Every thing is Regular, prevent any changes here ... + if (xAU5CrossSignalsMethod == X_CROSS_SIGNAL_REGULAR) + { + return; + } + + // + // Retrieve Max in Drawdown Signal ... + XSignal maxInDDSignal = xAU5Trader.GetMaxInDrawdownSignal(); + + // + // Validate Signal ... + bool isValidSignal = + maxInDDSignal.ticket > 0 && + maxInDDSignal.symbol == signal.symbol && + IsValid(maxInDDSignal, xAU5MagicNumber); + if (!isValidSignal) + { + return; + } + + // + double volume = signal.volume; + bool isDirectional = maxInDDSignal.type == signal.type; + + // + // Prevent any changes on Regular Conditions ... + bool isRegular = + isDirectional + ? ( + // + xAU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR || + xAU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT + // + ) + : ( + // + xAU5CrossSignalsMethod == X_CROSS_SIGNAL_INDIRECTION_REGULAR || + xAU5CrossSignalsMethod == X_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR + // + ); + if (isRegular) + { + return; + } + + // + // Important Act needs to Multiply volume by 2 ... + volume *= 2; + + // + // Set Volume of signal ... + signal.volume = volume; +} + +// +// Calculate Usefull data ... +void XAU5HandleCalculateDrawDownUp() +{ + // + XSignal signals[]; + xAU5Trader.GetSignals(signals); + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + double profit = 0; + double volume = 0; + XCollector collector = {}; + double maxAllowedVolume = xAU5VolumeManager.GetMaxAllowedVolume(); + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = signals[i]; + + // + profit += iSignal.profit; + + // + volume = + volume == 0 || + volume < iSignal.volume + ? iSignal.volume + : volume; + } + + // + if (profit < 0) + { + // + xAU5MaxDrawDown = + xAU5MaxDrawDown == 0 || + xAU5MaxDrawDown > MathAbs(profit) + ? MathAbs(profit) + : xAU5MaxDrawDown; + + // + // Update Buffers ... + datetime time = iTime(_Symbol, _Period, 0); + + // + // Calculate Max Allowed Drawdown ... + // + collector.time = time; + collector.volume = volume; + collector.maxDrawDown = xAU5MaxDrawDown; + collector.maxAllowedVolume = maxAllowedVolume; + collector.minBalanceForOpenTrade = xAU5Trader.GetMinBalanceForOpenTrades(); + } + else + { + // + xAU5MaxDrawUp = + xAU5MaxDrawUp == 0 || + xAU5MaxDrawUp < profit + ? profit + : xAU5MaxDrawUp; + } + + // + // Update Collector ... + xAU5Collector.Add(collector); + + // + // Update Reports ... + xAU5Reporter.UpdateMaxDrawUpInReports(xAU5MaxDrawUp); + xAU5Reporter.UpdateMaxDrawDownInReports(xAU5MaxDrawDown); + xAU5Reporter.UpdateMaxSameTimeTradesInReports(signalsCount); +} + +// +// START Event Handlers ... +// + +// +// Runs When a Signal Successfully Executed ... +void XAU5OnSignal( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + // Issue Propper Alert ... + XAU5IssueSignalExecutionAlert( + signal, + providers); + + // + // Add Signal To Supports on Guard ... + xAU5Guard.AddSupport(signal); + + // + // Update Reports ... + xAU5Reporter.AddSignalToReports( + signal, + providers); +} + +// +// Runs when a Position Got Take Profit ... +void XAU5OnTP( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XAU5IssueTPAlert(signal); + + // + // Remove Signal From Guard Protector ... + xAU5Guard.Remove(signal.ticket); + xAU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xAU5Reporter.AddTradeTPInReports(); + XAU5UpdateReports(); +} + +// +// Runs when a Position Got Stop Loss ... +void XAU5OnSL( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XAU5IssueSLAlert(signal); + + // + // Remove Signal From Guard Protector ... + xAU5Guard.Remove(signal.ticket); + xAU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xAU5Reporter.AddTradeSLInReports(); + XAU5UpdateReports(); +} + +// +// Runs when a Position Risk Free ... +void XAU5OnRF( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XAU5IssueRFAlert(signal); + + // + // Remove Signal From Guard Protector ... + // since RiskFree Signals has SL ... + xAU5Guard.Remove(signal.ticket); + xAU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xAU5Reporter.AddTradeSLInReports(); + XAU5UpdateReports(); +} + +// +// Runs when a Position Force Closed ... +void XAU5OnFC( + XSignal &signal // Specified Signal +) +{ + // + // Issue Propper Alert ... + XAU5IssueFCAlert(signal); + + // + // Remove Signal From Guard Protector ... + xAU5Guard.Remove(signal.ticket); + xAU5Guard.RemoveSupport(signal.ticket); + + // + // Update Reports ... + xAU5Reporter.AddTradeSLInReports(); + XAU5UpdateReports(); +} + +// +// Runs when a Position Guarded ... +void XAU5OnGuard( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Reason of Guard Applied + string message, // Guard Returned Message + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + // Chekc StopOut ... + if (isStopOut) + { + // + LogMessage(message); + + // + xAU5MEnableProvider = false; + } + + // + // Issue Propper Alert ... + XAU5IssueGuardAlert(signal, reason, isStopOut); + + // + // Update Reports ... + xAU5Reporter.AddTradeSLInReports(); + XAU5UpdateReports(); +} + +// +// END Event Handlers ... +// + +// +// END Provided Functions ... +// + +// +// START Private Functions ... +// + +// +// START Volume Baseed Functions ... +// + +// +// Calculating Volume for Tradings ... +double XAU5CalculateVolume( + double forceMultiplier = 0 // some times we get more than one signal at the same time, here we increase volume using this ... +) +{ + // + // Check Open Trades ... + int openSignals = xAU5Trader.Count(); + + // + double result = xAU5VolumeManager.CalculateVolume( + openSignals, + _Symbol); + + // + result *= forceMultiplier; + + // + // Normalize Volume ... + result = NormalizeVolume(result, _Symbol, 2); + + // + return result; +} + +// +// END Volume Baseed Functions ... +// + +// +// START Report/Collect and Guard Functions ... +// + +// +// Update Report Info ... +void XAU5UpdateReports() +{ + // + double staticVolume = xAU5VolumeManager.GetStaticVolume(); + string staticVolumeCalculationMethod = EnumToString(xAU5StaticVolumeMethod); + double maxAllowedVolume = xAU5VolumeManager.GetMaxAllowedVolume(); + double volumeIncreaseMultiplier = xAU5VolumeManager.GetVolumeMultiplier(); + double balanceGowingToApplyMultiplier = xAU5VolumeManager.GetIncreaseMultiplierBalance(); + + double balanceGrowingToIncreaseMaxAllowedVolume = xAU5VolumeManager.GetIncreaseMaxAllowedVolumeBalance(); + + // + // Update Reports Volume Info ... + xAU5Reporter.UpdateReportsVolumeInfo( + staticVolume, + staticVolumeCalculationMethod, + maxAllowedVolume, + volumeIncreaseMultiplier, + balanceGowingToApplyMultiplier, + balanceGrowingToIncreaseMaxAllowedVolume); + + // + // Calculate Max Allowed Drawdown ... + double minBalanceForTradeBasedOnBalance = xAU5Trader.GetMinBalanceForOpenTrades(); + xAU5Reporter.UpdateMinBalanceForOpenTradesInReports(minBalanceForTradeBasedOnBalance); +} + +// +// Reset XAU5 Info Buffers ... +void XAU5ResetCollectors() +{ + // + // Reset Calculations Buffers and Variables ... + xAU5MaxDrawUp = 0; + xAU5MaxDrawDown = 0; + + // + xAU5Trader.Reset(); + xAU5Reporter.Reset(); + xAU5Collector.Reset(); + xAU5VolumeManager.ResetForceVolumeMultiplier(); +} + +// +// END Report/Collect and Guard Functions ... +// + +// +// START Alert Functions ... +// + +// +// Send Alert ... +void XAU5IssueAlert(string message) +{ + // + // Validate Args ... + if (StringLen(message) <= 0) + { + return; + } + + // + if (xAU5EnableAlerts) + { + SendAlert(message); + } + else + { + LogMessage(message); + } +} + +// +// Send Take Profit Alert on Specific Signal ... +void XAU5IssueTPAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xAU5Trader.GenerateSignalTPComment(signal); + + // + XAU5IssueAlert(message); +} + +// +// Send Stop Loss Alert on Specific Signal ... +void XAU5IssueSLAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xAU5Trader.GenerateSignalSLComment(signal); + + // + XAU5IssueAlert(message); +} + +// +// Send Force Close Alert on Specific Signal ... +void XAU5IssueFCAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xAU5Trader.GenerateSignalForceCloseComment(signal); + + // + XAU5IssueAlert(message); +} + +// +// Send Risk Free Alert on Specific Signal ... +void XAU5IssueRFAlert( + XSignal &signal // Specified Signal +) +{ + // + string message = ""; + + // + message = xAU5Trader.GenerateSignalRFComment(signal, 0); + + // + XAU5IssueAlert(message); +} + +// +// Send Guard Alert on Specific Signal ... +void XAU5IssueGuardAlert( + XSignal &signal, // Specified Signal + ENUM_X_GUARD_REASONS reason, // Specified Guard Reason + bool isStopOut = false // Specified StopOut Fired or not +) +{ + // + string message = ""; + + // + message = xAU5Guard.GenerateGuardedSignalComment( + signal, + reason); + + // + XAU5IssueAlert(message); +} + +// +// Send Initialization Succeed Alert ... +void XAU5IssueInitializationSucceedAlert() +{ + // + string message = "Initializion of (" + XAU5ProviderName + " Provider" + " _ " + _Symbol + " _ " + EnumToString(_Period) + ") Succeeded ..."; + XAU5IssueAlert(message); +} + +// +// Send De Initialization Succeed Alert ... +void XAU5IssueDeinitializationSucceedAlert() +{ + // + string message = "De Initializion of (" + XAU5ProviderName + " Provider" + ") Succeeded ..."; + XAU5IssueAlert(message); +} + +// +// Send Signal Successfully Execution Alert ... +void XAU5IssueSignalExecutionAlert( + XSignal &signal, // Specified Signal + string &providers[] // Signal Providers +) +{ + // + string message = xAU5Trader.ToString(signal); + + // + string providersMsg = ToString(providers); + if (StringLen(providersMsg) > 0) + { + message += ", Providers: " + providersMsg; + } + + // + XAU5IssueAlert(message); +} + +// +// Send Signal Execution Alert ... +void XAU5IssueSignalExecutionError(int error) +{ + // + string message = GetSignalExecutionError(error); + if (StringLen(message) == 0) + { + return; + } + + // + XAU5IssueAlert(message); +} + +// +// END Alert Functions ... +// + +// +// END Private Functions ... +//