diff --git a/BKPS/14030412/Classes/x-saherelm.base.class.ex5 b/BKPS/14030412/Classes/x-saherelm.base.class.ex5 new file mode 100644 index 0000000..e3c7f9c Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.base.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.base.class.mq5 b/BKPS/14030412/Classes/x-saherelm.base.class.mq5 new file mode 100644 index 0000000..8425c50 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.base.class.mq5 @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// -------------------------------------- +// Name: XBaseClass +// Description: provides all based 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 + +// +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// XBase Class ... +class XSCBase +{ + // + // Public ... +public: + // + // Protected ... + + // + // Represent Basic Unique Tag ... + virtual string GetTag(); + + // + // Retrieve Class Token ... + virtual string GetToken(); + +protected: + // + // Private ... +private: +}; + +// +template +string GenerateSpecifiedCommonSummary( + T &mItem, + string separator = "\n", + bool includeScores = true, + bool setLabel = false // +) +{ + // + string result = NULL; + + // + result = + // + (!setLabel + ? "" + : "Commons:" + separator) + + "---------------" + separator + + "Symbol: " + mItem.symbol + separator + + "Period: " + ToString(mItem.period) + separator + + "Time: " + ToString(mItem.time) + separator + + "" + // + ; + + // + return result; +} + +// diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.class.ex5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.class.ex5 new file mode 100644 index 0000000..bd97b37 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.x121.setup.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.class.mq5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.class.mq5 new file mode 100644 index 0000000..0a29db5 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.x121.setup.class.mq5 @@ -0,0 +1,4433 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121Setup +// Description: provides implementation of X121 +// Setup ... +// +// +// 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 + +// +// Imports ... + +// +#include "../Libraries/x-saherelm.xtrade.lib.mq5" +#include "../Classes/x-saherelm.xalert.class.mq5" + +// +#include "../Helpers/x-saherelm.xrl.helper.mq5" +#include "../Helpers/x-saherelm.xmc.helper.mq5" +#include "../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Helpers/x-saherelm.xtd.helper.mq5" +#include "../Helpers/x-saherelm.xhk.helper.mq5" +#include "../Helpers/x-saherelm.xsln.helper.mq5" +#include "../Helpers/x-saherelm.xstr.helper.mq5" +#include "../Helpers/x-saherelm.xche.helper.mq5" +#include "../Helpers/x-saherelm.xich.helper.mq5" +#include "../Helpers/x-saherelm.xmrb.helper.mq5" +#include "../Helpers/x-saherelm.xosc.helper.mq5" +#include "../Helpers/x-saherelm.xvlm.helper.mq5" +#include "../Helpers/x-saherelm.xhtd.helper.mq5" +#include "../Helpers/x-saherelm.xchma.helper.mq5" +#include "../Helpers/x-saherelm.xatsl.helper.mq5" +#include "../Helpers/x-saherelm.xdmnt.helper.mq5" +#include "../Helpers/x-saherelm.xasct.helper.mq5" +#include "../Helpers/x-saherelm.xsslc.helper.mq5" +#include "../Helpers/x-saherelm.xhull.helper.mq5" +#include "../Helpers/x-saherelm.xadxtd.helper.mq5" + +// +// Definitions ... + +// +enum ENUM_X121_SIGNAL_PROVIDER +{ + // + PROVIDER_UNKNOWN = 0, + PROVIDER_XMC = 1, + PROVIDER_XSARD = 2, + PROVIDER_XADXTD = 3, + PROVIDER_XSTR = 4, + PROVIDER_XCHE = 5, + PROVIDER_XTD = 6, + PROVIDER_XSI = 7, + PROVIDER_XCI = 8, + PROVIDER_XMCD = 9, + PROVIDER_XICH = 10, + PROVIDER_XHK = 11, + PROVIDER_XSMHK = 12, + PROVIDER_XMRB = 13, + PROVIDER_XSSLC = 14, + PROVIDER_XHULL = 15, + PROVIDER_XASCT = 16, + PROVIDER_XVLM = 17, + PROVIDER_XPVF = 18, + PROVIDER_XPVSAR = 19, + PROVIDER_XHTSRD = 20, + PROVIDER_XATSL = 21, + PROVIDER_XHTD = 22, + PROVIDER_XSLN = 23 +}; + +// +string ToString(ENUM_X121_SIGNAL_PROVIDER value) +{ + // + string result = NULL; + + // + string vStr = EnumToString(value); + if (!IsValid(vStr)) + { + return result; + } + + // + string parts[]; + int partsCount = SplitContent( + parts, + vStr, + "_" + // + ); + if (partsCount <= 0) + { + return result; + } + + // + bool hasLastPart = GetLastItem( + result, + parts + // + ); + if (!hasLastPart) + { + return result; + } + + // + return result; +} + +// +ENUM_X121_SIGNAL_PROVIDER FromString(string value) +{ + // + ENUM_X121_SIGNAL_PROVIDER result = PROVIDER_UNKNOWN; + + // + if (!IsValid(value)) + { + return result; + } + + // + if (Contains(value, (EnumToString(PROVIDER_XMC)))) + { + result = PROVIDER_XMC; + } + else if (Contains(value, (EnumToString(PROVIDER_XSARD)))) + { + result = PROVIDER_XSARD; + } + else if (Contains(value, (EnumToString(PROVIDER_XADXTD)))) + { + result = PROVIDER_XADXTD; + } + else if (Contains(value, (EnumToString(PROVIDER_XSTR)))) + { + result = PROVIDER_XSTR; + } + else if (Contains(value, (EnumToString(PROVIDER_XCHE)))) + { + result = PROVIDER_XCHE; + } + else if (Contains(value, (EnumToString(PROVIDER_XTD)))) + { + result = PROVIDER_XTD; + } + else if (Contains(value, (EnumToString(PROVIDER_XSI)))) + { + result = PROVIDER_XSI; + } + else if (Contains(value, (EnumToString(PROVIDER_XCI)))) + { + result = PROVIDER_XCI; + } + else if (Contains(value, (EnumToString(PROVIDER_XMCD)))) + { + result = PROVIDER_XMCD; + } + else if (Contains(value, (EnumToString(PROVIDER_XICH)))) + { + result = PROVIDER_XICH; + } + else if (Contains(value, (EnumToString(PROVIDER_XHK)))) + { + result = PROVIDER_XHK; + } + else if (Contains(value, (EnumToString(PROVIDER_XSMHK)))) + { + result = PROVIDER_XSMHK; + } + else if (Contains(value, (EnumToString(PROVIDER_XMRB)))) + { + result = PROVIDER_XMRB; + } + else if (Contains(value, (EnumToString(PROVIDER_XSSLC)))) + { + result = PROVIDER_XSSLC; + } + else if (Contains(value, (EnumToString(PROVIDER_XHULL)))) + { + result = PROVIDER_XHULL; + } + else if (Contains(value, (EnumToString(PROVIDER_XASCT)))) + { + result = PROVIDER_XASCT; + } + else if (Contains(value, (EnumToString(PROVIDER_XVLM)))) + { + result = PROVIDER_XVLM; + } + else if (Contains(value, (EnumToString(PROVIDER_XPVF)))) + { + result = PROVIDER_XPVF; + } + else if (Contains(value, (EnumToString(PROVIDER_XPVSAR)))) + { + result = PROVIDER_XPVSAR; + } + else if (Contains(value, (EnumToString(PROVIDER_XHTSRD)))) + { + result = PROVIDER_XHTSRD; + } + + // + return result; +} + +// +// Inputs ... +struct X121SetupInputs +{ + // + // Commons ... + string symbol; // Symbol + ENUM_TIMEFRAMES period; // Time Frame + + // + // Helpers Inputs ... + XRLInputs rlInputs; // XRL Inputs + XMCInputs mcInputs; // XMC Inputs + XPVInputs pvInputs; // XPV Inputs + XTDInputs tdInputs; // XTD Inputs + XHKInputs hkInputs; // XHK Inputs + XHTDInputs htdInputs; // XHTD Inputs + XCHEInputs cheInputs; // XCHE Inputs + XICHInputs ichInputs; // XICH Inputs + XSTRInputs strInputs; // XSTR Inputs + XMRBInputs mrbInputs; // XMRB Inputs + XOSCInputs oscInputs; // XOSC Inputs + XVLMInputs vlmInputs; // XVLM Inputs + XSLNInputs slnInputs; // XSLN Inputs + XCHMAInputs chmaInputs; // XCHMA Inputs + XATSLInputs atslInputs; // XATSL Inputs + XDMNTInputs dmntInputs; // XDMNT Inputs + XASCTInputs asctInputs; // XASCT Inputs + XSSLCInputs sslcInputs; // XSSLC Inputs + XHULLInputs hullInputs; // XHULL Inputs + XADXTDInputs adxtdInputs; // XADXTD Inputs + + // + // Constructor ... + void X121SetupInputs() + { + Clean(); + } + + // + bool Init() + { + // + Default(); + + // + bool result = IsValid(); + + // + return result; + } + bool Init( + string _symbol, // Symbol + ENUM_TIMEFRAMES _period, // Time Frame + XRLInputs &_rlInputs, // XRL Inputs + XMCInputs &_mcInputs, // XMC Inputs + XPVInputs &_pvInputs, // XPV Inputs + XTDInputs &_tdInputs, // XTD Inputs + XHKInputs &_hkInputs, // XHK Inputs + XHTDInputs &_htdInputs, // XHTD Inputs + XCHEInputs &_cheInputs, // XCHE Inputs + XICHInputs &_ichInputs, // XICH Inputs + XSTRInputs &_strInputs, // XSTR Inputs + XMRBInputs &_mrbInputs, // XMRB Inputs + XOSCInputs &_oscInputs, // XOSC Inputs + XVLMInputs &_vlmInputs, // XVLM Inputs + XSLNInputs &_slnInputs, // XSLN Inputs + XCHMAInputs &_chmaInputs, // XCHMA Inputs + XATSLInputs &_atslInputs, // XATSL Inputs + XDMNTInputs &_dmntInputs, // XDMNT Inputs + XASCTInputs &_asctInputs, // XASCT Inputs + XSSLCInputs &_sslcInputs, // XSSLC Inputs + XHULLInputs &_hullInputs, // XHULL Inputs + XADXTDInputs &_adxtdInputs // XADXTD Inputs + ) + { + // + this.symbol = _symbol; + this.period = _period; + + // + // Helpers Inputs ... + this.mcInputs = _mcInputs; + this.pvInputs = _pvInputs; + this.tdInputs = _tdInputs; + this.hkInputs = _hkInputs; + this.htdInputs = _htdInputs; + this.cheInputs = _cheInputs; + this.ichInputs = _ichInputs; + this.strInputs = _strInputs; + this.mrbInputs = _mrbInputs; + this.oscInputs = _oscInputs; + this.vlmInputs = _vlmInputs; + this.chmaInputs = _chmaInputs; + this.atslInputs = _atslInputs; + this.dmntInputs = _dmntInputs; + this.asctInputs = _asctInputs; + this.sslcInputs = _sslcInputs; + this.hullInputs = _hullInputs; + this.adxtdInputs = _adxtdInputs; + + // + bool result = IsValid(); + + // + return result; + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + period = NULL; + + // + rlInputs.Clean(); + mcInputs.Clean(); + pvInputs.Clean(); + tdInputs.Clean(); + hkInputs.Clean(); + cheInputs.Clean(); + ichInputs.Clean(); + strInputs.Clean(); + mrbInputs.Clean(); + oscInputs.Clean(); + vlmInputs.Clean(); + slnInputs.Clean(); + htdInputs.Clean(); + chmaInputs.Clean(); + atslInputs.Clean(); + asctInputs.Clean(); + sslcInputs.Clean(); + hullInputs.Clean(); + dmntInputs.Clean(); + adxtdInputs.Clean(); + } + + // + // Default ... + void Default() + { + // + rlInputs.Default(); + mcInputs.Default(); + pvInputs.Default(); + tdInputs.Default(); + hkInputs.Default(); + cheInputs.Default(); + ichInputs.Default(); + strInputs.Default(); + mrbInputs.Default(); + oscInputs.Default(); + vlmInputs.Default(); + slnInputs.Default(); + htdInputs.Default(); + chmaInputs.Default(); + atslInputs.Default(); + asctInputs.Default(); + sslcInputs.Default(); + hullInputs.Default(); + dmntInputs.Default(); + adxtdInputs.Default(); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(symbol) && + IsValid(period) + // + ; + if (!result) + { + return result; + } + + // + result = rlInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = tdInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = slnInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = pvInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = hkInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = cheInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = ichInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = strInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = mrbInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = oscInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = vlmInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = mcInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = asctInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = sslcInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = hullInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = adxtdInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = htdInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = chmaInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = atslInputs.IsValid(); + if (!result) + { + return result; + } + + // + result = dmntInputs.IsValid(); + if (!result) + { + return result; + } + + // + return result; + } +}; + +// +// Conditions ... +struct X121SetupConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Conditions ... + XRLConditions rlConditions; + XMCConditions mcConditions; + XPVConditions pvConditions; + XTDConditions tdConditions; + XHKConditions hkConditions; + XCHEConditions cheConditions; + XICHConditions ichConditions; + XSTRConditions strConditions; + XMRBConditions mrbConditions; + XVLMConditions vlmConditions; + XHTDConditions htdConditions; + XSLNConditions slnConditions; + XCHMAConditions chmaConditions; + XATSLConditions atslConditions; + XASCTConditions asctConditions; + XSSLCConditions sslcConditions; + XHULLConditions hullConditions; + XDMNTConditions dmntConditions; + XADXTDConditions adxtdConditions; + + // + // Oscillators ... + double cci[]; + double rsi[]; + double macd[]; + double macdSignal[]; + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + time = NULL; + symbol = NULL; + period = NULL; + + // + Clean(cci); + Clean(rsi); + Clean(macd); + Clean(macdSignal); + + // + rlConditions.Clean(); + mcConditions.Clean(); + tdConditions.Clean(); + hkConditions.Clean(); + cheConditions.Clean(); + ichConditions.Clean(); + strConditions.Clean(); + mrbConditions.Clean(); + vlmConditions.Clean(); + slnConditions.Clean(); + htdConditions.Clean(); + chmaConditions.Clean(); + atslConditions.Clean(); + asctConditions.Clean(); + sslcConditions.Clean(); + hullConditions.Clean(); + dmntConditions.Clean(); + adxtdConditions.Clean(); + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + double tempBullishScore = 0; + double tempBearishScore = 0; + + // + rlConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + mcConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + pvConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + slnConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + adxtdConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + strConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + cheConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + asctConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + tdConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + ichConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + hkConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + mrbConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + vlmConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + sslcConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + hullConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + htdConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + atslConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + chmaConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + dmntConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + + // + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string pvSummary = pvConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string rlSummary = rlConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string mcSummary = mcConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string tdSummary = tdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string hkSummary = hkConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string strSummary = strConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string cheSummary = cheConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string ichSummary = ichConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string mrbSummary = mrbConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string vlmSummary = vlmConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string slnSummary = slnConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string htdSummary = htdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string chmaSummary = chmaConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string atslSummary = atslConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string asctSummary = asctConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string sslcSummary = sslcConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string hullSummary = hullConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string dmntSummary = dmntConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string adxtdSummary = adxtdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + + // + string conditionsStr = + // + pvSummary + separator + + rlSummary + separator + + mcSummary + separator + + tdSummary + separator + + hkSummary + separator + + ichSummary + separator + + mrbSummary + separator + + vlmSummary + separator + + slnSummary + separator + + strSummary + separator + + cheSummary + separator + + asctSummary + separator + + sslcSummary + separator + + hullSummary + separator + + adxtdSummary + separator + + htdSummary + separator + + atslSummary + separator + + dmntSummary + separator + + chmaSummary + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + // Add Combine Conditions ... + + // + bool IsTrendBullish() + { + // + bool result = false; + + // + result = + // + (strConditions.isTrendSwitchedToBullish && + slnConditions.isBullish && + htdConditions.isBullish && + atslConditions.isBullish && + cheConditions.isStrongBullish) + // + || + // + (slnConditions.isSwitchedToBullish && + strConditions.isTrendBullish && + htdConditions.isBullish && + atslConditions.isBullish && + cheConditions.isStrongBullish) + // + || + // + (htdConditions.isSwitchedToBullish && + strConditions.isTrendBullish && + slnConditions.isBullish && + atslConditions.isBullish && + cheConditions.isStrongBullish) + // + || + // + (atslConditions.isSwitchedToBullish && + strConditions.isTrendBullish && + htdConditions.isBullish && + slnConditions.isBullish && + cheConditions.isStrongBullish) + // + || + // + (cheConditions.isStrongSwitchedToBullish && + strConditions.isTrendBullish && + htdConditions.isBullish && + slnConditions.isBullish && + atslConditions.isBullish) + // + ; + + // + return result; + } + + // + bool IsTrendBearish() + { + // + bool result = false; + + // + result = + // + (strConditions.isTrendSwitchedToBearish && + slnConditions.isBearish && + htdConditions.isBearish && + atslConditions.isBearish && + cheConditions.isStrongBearish) + // + || + // + (slnConditions.isSwitchedToBearish && + strConditions.isTrendBearish && + htdConditions.isBearish && + atslConditions.isBearish && + cheConditions.isStrongBearish) + // + || + // + (htdConditions.isSwitchedToBearish && + strConditions.isTrendBearish && + slnConditions.isBearish && + atslConditions.isBearish && + cheConditions.isStrongBearish) + // + || + // + (atslConditions.isSwitchedToBearish && + strConditions.isTrendBearish && + htdConditions.isBearish && + slnConditions.isBearish && + cheConditions.isStrongBearish) + // + || + // + (cheConditions.isStrongSwitchedToBearish && + strConditions.isTrendBearish && + htdConditions.isBearish && + slnConditions.isBearish && + atslConditions.isBearish) + // + ; + + // + return result; + } + + // + string GetTag() + { + return "X121Setup"; + } +}; + +// +// Condition Parser ... +struct X121SignalGenerator +{ + // + // Symbol Parser Instance ... + XSymbolParser symbolParser; + + // + // Constructor ... + void X121SignalGenerator() + { + } + + // + // Check Conditions for Generating Possible Signals ... + bool HasSignal( + X121SetupConditions &conditions, // Conditions + XSignal &signal, // Signal if Exists + int &pusher, // Pushers + string &provider, // Signal Provider Name + double &tp, // Provided TP + double &sl, // Provided SL + bool _useSupport, // Generate Support Signals + bool _allowLong, // Allow Long Signals + bool _allowShort, // Allow Short Signals + double _volume = 0.01, // Volume + double _slPoint = 0, // SL Point + bool _ignoreSL = false, // Ignore Calculated SL + double _tpPoint = 30, // TP Point + bool _ignoreTP = false // Ignore Calculated TP + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = _allowLong || _allowShort; + if (!result) + { + return result; + } + + // + bool hasLong = false; + bool hasShort = false; + + // + if (_allowLong) + { + // + hasLong = + HasLongConditions( + conditions, + pusher, + provider, + tp, + sl // + ); + + // + if (hasLong) + { + // + hasLong = FilterLongConditions( + conditions, + pusher, + provider // + ); + } + } + + // + if (_allowShort && !hasLong) + { + // + hasShort = + HasShortConditions( + conditions, + pusher, + provider, + tp, + sl // + ); + + // + if (hasShort) + { + // + hasShort = FilterShortConditions( + conditions, + pusher, + provider // + ); + } + } + + // + result = hasLong || hasShort; + if (!result) + { + return result; + } + + // + string mProvider = + IsValid(provider) + ? provider + : GetTag(); + + // + // Prepare Signals ... + ENUM_POSITION_TYPE mType = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double mEntry = GetEntry( + conditions.symbol, + mType // + ); + + // + double mSL = 0; + double mTP = 0; + double mPointValue = + GetPoints(conditions.symbol); + result = CalculateTPSLByPoint( + mSL, + mTP, + mType, + mEntry, + mPointValue, + 1, + _slPoint, + _tpPoint // + ); + if (!result) + { + return result; + } + + // + result = signal.Prepare( + conditions.symbol, + mProvider, + conditions.period, + mType, + X_ORDER_MODE_MARKET, + mEntry, + _volume, + _ignoreSL + ? 0 + : mSL, + _ignoreTP + ? 0 + : mTP // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Long Specified Functions ... + + // + // Check Market Conditions for Long Signals ... + bool HasLongConditions( + X121SetupConditions &conditions, // Conditions + int &pusher, // Pushers + string &provider, // Provider + double &tp, // Provided TP + double &sl // Provided SL + ) + { + // + bool result = false; + + // + tp = 0; + sl = 0; + pusher = 0; + + // + bool isOSCShortVerified = IsOSCShortVerified(conditions); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + // XMC ... + bool long1 = + // + // Starting Conditions ... + conditions.mcConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.tdConditions.isBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long1) + { + // + pusher++; + provider = ToString(PROVIDER_XMC); + } + + // + // XSARD ... + bool long2 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.tdConditions.isBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long2) + { + // + pusher++; + provider = ToString(PROVIDER_XSARD); + } + + // + // XADXTD ... + bool long3 = + // + // Starting Conditions ... + conditions.adxtdConditions.isStrongSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.tdConditions.isBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long3) + { + // + pusher++; + provider = ToString(PROVIDER_XADXTD); + } + + // + // XSTR ... + bool long4 = + // + // Starting Conditions ... + conditions.strConditions.isTrendSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.cheConditions.isStrongBullish && + conditions.tdConditions.isBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long4) + { + // + pusher++; + provider = ToString(PROVIDER_XSTR); + } + + // + // XCHE ... + bool long5 = + // + // Starting Conditions ... + conditions.cheConditions.isStrongSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.tdConditions.isBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long5) + { + // + pusher++; + provider = ToString(PROVIDER_XCHE); + } + + // + // XTD ... + bool long6 = + // + // Starting Conditions ... + conditions.tdConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long6) + { + // + pusher++; + provider = ToString(PROVIDER_XTD); + } + + // + // XSI ... + bool long7 = + // + // Starting Conditions ... + conditions.rsi[cIndex] > 30 && + conditions.rsi[pIndex] <= 30 && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long7) + { + // + pusher++; + provider = ToString(PROVIDER_XSI); + } + + // + // XCI ... + bool long8 = + // + // Starting Conditions ... + conditions.cci[cIndex] > -100 && + conditions.cci[pIndex] <= -100 && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long8) + { + // + pusher++; + provider = ToString(PROVIDER_XCI); + } + + // + // XMCD ... + bool long9 = + // + // Starting Conditions ... + conditions.macd[cIndex] > 0 && + conditions.macd[cIndex] > conditions.macdSignal[cIndex] && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long9) + { + // + pusher++; + provider = ToString(PROVIDER_XMCD); + } + + // + // XICH ... + bool long10 = + // + // Starting Conditions ... + conditions.ichConditions.HasLongConditions() && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long10) + { + // + pusher++; + provider = ToString(PROVIDER_XICH); + } + + // + // XHK ... + bool long11 = + // + // Starting Conditions ... + conditions.hkConditions.isHKSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long11) + { + // + pusher++; + provider = ToString(PROVIDER_XHK); + } + + // + // XSMHK ... + bool long12 = + // + // Starting Conditions ... + conditions.hkConditions.isSMHKSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long12) + { + // + pusher++; + provider = ToString(PROVIDER_XSMHK); + } + + // + // XMRB ... + bool long13 = + // + // Starting Conditions ... + conditions.mrbConditions.isFastCrossedOverSlow && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.sslcConditions.isBullish && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long13) + { + // + pusher++; + provider = ToString(PROVIDER_XMRB); + } + + // + // XSSLC ... + bool long14 = + // + // Starting Conditions ... + conditions.sslcConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long14) + { + // + pusher++; + provider = ToString(PROVIDER_XSSLC); + } + + // + // XHULL ... + bool long15 = + // + // Starting Conditions ... + conditions.hullConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long15) + { + // + pusher++; + provider = ToString(PROVIDER_XHULL); + } + + // + // XASCT ... + bool long16 = + // + // Starting Conditions ... + conditions.asctConditions.isLongSignal && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long16) + { + // + pusher++; + provider = ToString(PROVIDER_XASCT); + } + + // + // XVLM ... + bool long17 = + // + // Starting Conditions ... + conditions.vlmConditions.isVolumeChangedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long17) + { + // + pusher++; + provider = ToString(PROVIDER_XVLM); + } + + // + // XPVF ... + bool long18 = + // + // Starting Conditions ... + conditions.pvConditions.isFiboIncreased && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long18) + { + // + pusher++; + provider = ToString(PROVIDER_XPVF); + } + + // + // XPVSAR ... + bool long19 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBullish && + conditions.pvConditions.vales[zIndex] == conditions.mcConditions.psar[zIndex] && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long19) + { + // + pusher += 2; + provider = ToString(PROVIDER_XPVSAR); + } + + // + // XHTSRD ... + bool long20 = + // + // Starting Conditions ... + conditions.IsTrendBullish() && + conditions.dmntConditions.isBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long20) + { + // + pusher++; + provider = ToString(PROVIDER_XHTSRD); + } + + // + // XATSL ... + bool long21 = + // + // Starting Conditions ... + conditions.atslConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.htdConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long21) + { + // + pusher++; + provider = ToString(PROVIDER_XATSL); + } + + // + // XHTD ... + bool long22 = + // + // Starting Conditions ... + conditions.htdConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.slnConditions.isBullish + // + ; + if (long22) + { + // + pusher++; + provider = ToString(PROVIDER_XHTD); + } + + // + // XSLN ... + bool long23 = + // + // Starting Conditions ... + conditions.slnConditions.isSwitchedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.mcConditions.isBullish && + conditions.mcConditions.isSARBullish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBullish && + conditions.strConditions.isTrendBullish && + conditions.cheConditions.isStrongBullish && + conditions.hkConditions.isHKBullish && + conditions.hkConditions.isSMHKBullish && + conditions.mrbConditions.isFastOverSlow && + conditions.hullConditions.isBullish && + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish && + conditions.atslConditions.isBullish && + conditions.htdConditions.isBullish + // + ; + if (long23) + { + // + pusher++; + provider = ToString(PROVIDER_XSLN); + } + + // + result = + // + pusher >= 1 && + ( + // + long1 + // + || + // + long2 + // + || + // + long3 + // + || + // + long4 + // + || + // + long5 + // + || + // + long6 + // + || + // + long7 + // + || + // + long8 + // + || + // + long9 + // + || + // + long10 + // + || + // + long11 + // + || + // + long12 + // + || + // + long13 + // + || + // + long14 + // + || + // + long15 + // + || + // + long16 + // + || + // + long17 + // + || + // + long18 + // + || + // + long19 + // + || + // + long20 + // + || + // + long21 + // + || + // + long22 + // + || + // + long23 + // + ) + // + ; + + // + return result; + } + + // + // Filter Long Conditions ... + bool FilterLongConditions( + X121SetupConditions &conditions, // Conditions + int pusher, // Pushers + string provider // Provider + ) + { + // + bool result = false; + + // + // Generating Conditions Score ... + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol); + + // + bool isM5Period = conditions.period == PERIOD_M5; + bool isM15Period = conditions.period == PERIOD_M15; + bool isH1Period = conditions.period == PERIOD_H1; + bool isH4Period = conditions.period == PERIOD_H4; + + // + // Set Default Result to True ... + result = true; + + // + // Apply Filter ... + // Based On Symbol and Period ... + // if necessary ... + if (isGBPUSD) + { + // + // MEDIUM ... + if (isH1Period) + { + } + } + + // + return result; + } + + // + // Retrieve Long Verifications ... + bool HasLongVerifications( + X121SetupConditions &conditions[] // Conditions Collection + ) + { + // + bool result = false; + + // + int count = ArraySize(conditions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // Loop through Conditions to Get Verifications ... + for (int i = count - 1; i >= 0; i--) + { + // + X121SetupConditions iConditions = conditions[i]; + + // + result = IsConditionsValidForLong(iConditions); + if (!result) + { + break; + } + } + + // + return result; + } + + // + // Count Number of Long Validations ... + int CountLongValidations( + X121SetupConditions &conditions // Conditions + ) + { + // + int result = 0; + + // + // 1 + // XTD ... + bool isTDPassed = + // + conditions.tdConditions.isBullish || + conditions.tdConditions.isSwitchedToBullish + // + ; + if (isTDPassed) + { + result++; + } + + // + // 2 + // XHK ... + bool isHKPassed = + // + (conditions.hkConditions.isHKBullish || + conditions.hkConditions.isHKSwitchedToBullish) + // + || + // + (conditions.hkConditions.isSMHKBullish || + conditions.hkConditions.isSMHKSwitchedToBullish) + // + ; + if (isHKPassed) + { + result++; + } + + // + // 3 + // XCHE ... + bool isCHEPassed = + // + conditions.cheConditions.isBullish || + conditions.cheConditions.isStrongBullish || + conditions.cheConditions.isSwitchedToBullish || + conditions.cheConditions.isStrongSwitchedToBullish + // + ; + if (isCHEPassed) + { + result++; + } + + // + // 4 + // XICH ... + bool isICHPassed = + // + (conditions.ichConditions.isTenkanSenOverKijunSen || + conditions.ichConditions.isTenkanSenCrossedOverKijunSen) + // + && + // + (conditions.ichConditions.isSenkouSpanAOverB || + conditions.ichConditions.isSenkouSpanAOverLast || + conditions.ichConditions.isSenkouSpanACrossedOverB || + conditions.ichConditions.isSenkouSpanACrossedOverLast) + // + && + // + (conditions.ichConditions.isFutureSenkouSpanAOverB || + conditions.ichConditions.isFutureSenkouSpanAOverLast || + conditions.ichConditions.isFutureSenkouSpanACrossedOverB || + conditions.ichConditions.isFutureSenkouSpanACrossedOverLast) + // + ; + if (isICHPassed) + { + result++; + } + + // + // 5 + // XSTR ... + bool isSTRPassed = + // + conditions.strConditions.isTrendBullish || + conditions.strConditions.isTrendSwitchedToBullish + // + ; + if (isSTRPassed) + { + result++; + } + + // + // 6 + // XMRB ... + bool isMRBPassed = + // + conditions.mrbConditions.isFastOverSlow || + conditions.mrbConditions.isFastCrossedOverSlow + // + ; + if (isMRBPassed) + { + result++; + } + + // + // 7 + // XVLM ... + bool isVLMPassed = + // + conditions.vlmConditions.isVolumeBullish || + conditions.vlmConditions.isVolumeOverLast || + conditions.vlmConditions.isVolumeChangedToBullish + // + ; + if (isVLMPassed) + { + result++; + } + + // + // 8 + // XSSLC ... + bool isSSLCPassed = + // + conditions.sslcConditions.isBullish || + conditions.sslcConditions.isSwitchedToBullish + // + ; + if (isSSLCPassed) + { + result++; + } + + // + // 9 + // XHULL ... + bool isHULLPassed = + // + conditions.hullConditions.isBullish || + conditions.hullConditions.isUpBullish || + conditions.hullConditions.isDownBullish || + conditions.hullConditions.isSwitchedToBullish + // + ; + if (isHULLPassed) + { + result++; + } + + // + // 10 + // XADX ... + bool isADXTDPassed = + // + conditions.adxtdConditions.isBullish || + conditions.adxtdConditions.isSwitchedToBullish || + conditions.adxtdConditions.isStrongSwitchedToBullish + // + ; + if (isADXTDPassed) + { + result++; + } + + // + // 11 + // XMC ... + bool isMCPassed = + // + ((conditions.mcConditions.isBullish || + conditions.mcConditions.isSwitchedToBullish) + // + || + // + ((conditions.mcConditions.isFastOverVerifier || + conditions.mcConditions.isFastCrossedOverVerifier) + // + && + // + (conditions.mcConditions.isSlowOverVerifier || + conditions.mcConditions.isSlowCrossedOverVerifier))) + // + || + // + (conditions.mcConditions.isSARBullish || + conditions.mcConditions.isSARSwitchedToBullish) + // + ; + if (isMCPassed) + { + result++; + } + + // + // 12 + // XSLN ... + bool isXSLNPassed = + // + (conditions.slnConditions.isBullish || + conditions.slnConditions.isSwitchedToBullish) + // + ; + if (isXSLNPassed) + { + result++; + } + + // + // 13 + // XHTD ... + bool isXHTDPassed = + // + (conditions.htdConditions.isBullish || + conditions.htdConditions.isSwitchedToBullish) + // + ; + if (isXHTDPassed) + { + result++; + } + + // + // 14 + // XATSL ... + bool isXATSLPassed = + // + (conditions.atslConditions.isBullish || + conditions.atslConditions.isSwitchedToBullish) + // + ; + if (isXATSLPassed) + { + result++; + } + + // + return result; + } + + // + bool IsConditionsValidForLong( + X121SetupConditions &conditions, // Conditions + int verifications = 10 // Number of Verifications + ) + { + // + bool result = false; + + // + int signs = CountLongValidations(conditions); + + // + result = + // + verifications <= 0 + ? signs > 0 + : signs >= verifications + // + ; + + // + return result; + } + + // + // Retrieve OSC Based Long Verifications ... + bool IsOSCLongVerified( + X121SetupConditions &conditions // Conditions + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + result = + // + // CCI ... + conditions.cci[cIndex] < 96 && + conditions.cci[cIndex] > conditions.cci[pIndex] + // + && + // + // RSI ... + conditions.rsi[cIndex] < 70 && + conditions.rsi[cIndex] > conditions.rsi[pIndex] + // + && + // + // MACD ... + conditions.macd[cIndex] > 0 && + conditions.macdSignal[cIndex] > 0 && + conditions.macd[cIndex] > conditions.macdSignal[cIndex] + // + ; + + // + return result; + } + + // + // Short Specified Functions ... + + // + // Check Market Conditions for Short Signals ... + bool HasShortConditions( + X121SetupConditions &conditions, // Conditions + int &pusher, // Pushers + string &provider, // Provider + double &tp, // Provided TP + double &sl // Provided SL + ) + { + // + bool result = false; + + // + tp = 0; + sl = 0; + pusher = 0; + + // + bool isOSCLongVerified = IsOSCLongVerified(conditions); + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + // XMC ... + bool short1 = + // + // Starting Conditions ... + conditions.mcConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short1) + { + // + pusher++; + provider = ToString(PROVIDER_XMC); + } + + // + // XSARD ... + bool short2 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short2) + { + // + pusher++; + provider = ToString(PROVIDER_XSARD); + } + + // + // XADXTD ... + bool short3 = + // + // Starting Conditions ... + conditions.adxtdConditions.isStrongSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short3) + { + // + pusher++; + provider = ToString(PROVIDER_XADXTD); + } + + // + // XSTR ... + bool short4 = + // + // Starting Conditions ... + conditions.strConditions.isTrendSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short4) + { + // + pusher++; + provider = ToString(PROVIDER_XSTR); + } + + // + // XCHE ... + bool short5 = + // + // Starting Conditions ... + conditions.cheConditions.isStrongSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short5) + { + // + pusher++; + provider = ToString(PROVIDER_XCHE); + } + + // + // XTD ... + bool short6 = + // + // Starting Conditions ... + conditions.tdConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short6) + { + // + pusher++; + provider = ToString(PROVIDER_XTD); + } + + // + // XSI ... + bool short7 = + // + // Starting Conditions ... + conditions.rsi[cIndex] < 70 && + conditions.rsi[pIndex] >= 70 && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short7) + { + // + pusher++; + provider = ToString(PROVIDER_XSI); + } + + // + // XCI ... + bool short8 = + // + // Starting Conditions ... + conditions.cci[cIndex] < 100 && + conditions.cci[pIndex] >= 100 && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short8) + { + // + pusher++; + provider = ToString(PROVIDER_XCI); + } + + // + // XMCD ... + bool short9 = + // + // Starting Conditions ... + conditions.macd[cIndex] < 0 && + conditions.macd[cIndex] < conditions.macdSignal[cIndex] && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short9) + { + // + pusher++; + provider = ToString(PROVIDER_XMCD); + } + + // + // XICH ... + bool short10 = + // + // Starting Conditions ... + conditions.ichConditions.HasShortConditions() && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short10) + { + // + pusher++; + provider = ToString(PROVIDER_XICH); + } + + // + // XHK ... + bool short11 = + // + // Starting Conditions ... + conditions.hkConditions.isHKSwitchedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short11) + { + // + pusher++; + provider = ToString(PROVIDER_XHK); + } + + // + // XSMHK ... + bool short12 = + // + // Starting Conditions ... + conditions.hkConditions.isSMHKSwitchedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short12) + { + // + pusher++; + provider = ToString(PROVIDER_XSMHK); + } + + // + // XMRB ... + bool short13 = + // + // Starting Conditions ... + conditions.mrbConditions.isFastCrossedUnderSlow && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short13) + { + // + pusher++; + provider = ToString(PROVIDER_XMRB); + } + + // + // XSSLC ... + bool short14 = + // + // Starting Conditions ... + conditions.sslcConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short14) + { + // + pusher++; + provider = ToString(PROVIDER_XSSLC); + } + + // + // XHULL ... + bool short15 = + // + // Starting Conditions ... + conditions.hullConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short15) + { + // + pusher++; + provider = ToString(PROVIDER_XHULL); + } + + // + // XASCT ... + bool short16 = + // + // Starting Conditions ... + conditions.asctConditions.isShortSignal && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.hullConditions.isBearish && + conditions.sslcConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short16) + { + // + pusher++; + provider = ToString(PROVIDER_XASCT); + } + + // + // XVLM ... + bool short17 = + // + // Starting Conditions ... + conditions.vlmConditions.isVolumeChangedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.hullConditions.isBearish && + conditions.sslcConditions.isBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short17) + { + // + pusher++; + provider = ToString(PROVIDER_XVLM); + } + + // + // XPVF ... + bool short18 = + // + // Starting Conditions ... + conditions.pvConditions.isFiboDecreased && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.mcConditions.isBearish && + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.hullConditions.isBearish && + conditions.sslcConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short18) + { + // + pusher++; + provider = ToString(PROVIDER_XPVF); + } + + // + // XPVSAR ... + bool short19 = + // + // Starting Conditions ... + conditions.mcConditions.isSARSwitchedToBearish && + conditions.pvConditions.peaks[zIndex] == conditions.mcConditions.psar[zIndex] && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short19) + { + // + pusher += 2; + provider = ToString(PROVIDER_XPVSAR); + } + + // + // XHTSRD ... + bool short20 = + // + // Starting Conditions ... + conditions.IsTrendBearish() && + conditions.dmntConditions.isBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short20) + { + // + pusher++; + provider = ToString(PROVIDER_XHTSRD); + } + + // + // XATSL ... + bool short21 = + // + // Starting Conditions ... + conditions.atslConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.mcConditions.isBearish && + conditions.htdConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short21) + { + // + pusher++; + provider = ToString(PROVIDER_XATSL); + } + + // + // XHTD ... + bool short22 = + // + // Starting Conditions ... + conditions.htdConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.mcConditions.isBearish && + conditions.atslConditions.isBearish && + conditions.atslConditions.isBearish && + conditions.slnConditions.isBearish + // + ; + if (short22) + { + // + pusher++; + provider = ToString(PROVIDER_XHTD); + } + + // + // XSLN ... + bool short23 = + // + // Starting Conditions ... + conditions.slnConditions.isSwitchedToBearish && + // + // Verifications ... + conditions.mcConditions.isSARBearish && + conditions.adxtdConditions.isStrong && + conditions.adxtdConditions.isBearish && + conditions.strConditions.isTrendBearish && + conditions.cheConditions.isStrongBearish && + conditions.tdConditions.isBearish && + conditions.hkConditions.isHKBearish && + conditions.hkConditions.isSMHKBearish && + conditions.mrbConditions.isFastUnderSlow && + conditions.sslcConditions.isBearish && + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish && + conditions.mcConditions.isBearish && + conditions.atslConditions.isBearish && + conditions.atslConditions.isBearish && + conditions.htdConditions.isBearish + // + ; + if (short23) + { + // + pusher++; + provider = ToString(PROVIDER_XSLN); + } + + // + result = + // + pusher >= 1 && + ( + // + short1 + // + || + // + short2 + // + || + // + short3 + // + || + // + short4 + // + || + // + short5 + // + || + // + short6 + // + || + // + short7 + // + || + // + short8 + // + || + // + short9 + // + || + // + short10 + // + || + // + short11 + // + || + // + short12 + // + || + // + short13 + // + || + // + short14 + // + || + // + short15 + // + || + // + short16 + // + || + // + short17 + // + || + // + short18 + // + || + // + short19 + // + || + // + short20 + // + || + // + short21 + // + || + // + short22 + // + || + // + short23 + // + ) + // + ; + + // + return result; + } + + // + // Filter Short Conditions ... + bool FilterShortConditions( + X121SetupConditions &conditions, // Conditions + int pusher, // Pushers + string provider // Provider + ) + { + // + bool result = false; + + // + // Generating Conditions Score ... + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol); + + // + bool isM5Period = conditions.period == PERIOD_M5; + bool isM15Period = conditions.period == PERIOD_M15; + bool isH1Period = conditions.period == PERIOD_H1; + bool isH4Period = conditions.period == PERIOD_H4; + + // + // Set Default Result to True ... + result = true; + + // + // Apply Filter ... + // Based On Symbol and Period ... + // if necessary ... + if (isGBPUSD) + { + // + // MEDIUM ... + if (isH1Period) + { + } + } + + // + return result; + } + + // + // Retrieve Short Verifications ... + bool HasShortVerifications( + X121SetupConditions &conditions[] // Conditions Collection + ) + { + // + bool result = false; + + // + int count = ArraySize(conditions); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // Loop through Conditions to Get Verifications ... + for (int i = count - 1; i >= 0; i--) + { + // + X121SetupConditions iConditions = conditions[i]; + + // + result = IsConditionsValidForShort(iConditions); + if (!result) + { + break; + } + } + + // + return result; + } + + // + int CountShortValidations( + X121SetupConditions &conditions // Conditions + ) + { + // + int result = 0; + + // + // 1 + // XTD ... + bool isTDPassed = + // + conditions.tdConditions.isBearish || + conditions.tdConditions.isSwitchedToBearish + // + ; + if (isTDPassed) + { + result++; + } + + // + // 2 + // XHK ... + bool isHKPassed = + // + (conditions.hkConditions.isHKBearish || + conditions.hkConditions.isHKSwitchedToBearish) + // + || + // + (conditions.hkConditions.isSMHKBearish || + conditions.hkConditions.isSMHKSwitchedToBearish) + // + ; + if (isHKPassed) + { + result++; + } + + // + // 3 + // XCHE ... + bool isCHEPassed = + // + conditions.cheConditions.isBearish || + conditions.cheConditions.isStrongBearish || + conditions.cheConditions.isSwitchedToBearish || + conditions.cheConditions.isStrongSwitchedToBearish + // + ; + if (isCHEPassed) + { + result++; + } + + // + // 4 + // XICH ... + bool isICHPassed = + // + (conditions.ichConditions.isTenkanSenUnderKijunSen || + conditions.ichConditions.isTenkanSenCrossedUnderKijunSen) + // + && + // + (conditions.ichConditions.isSenkouSpanAUnderB || + conditions.ichConditions.isSenkouSpanAUnderLast || + conditions.ichConditions.isSenkouSpanACrossedUnderB || + conditions.ichConditions.isSenkouSpanACrossedUnderLast) + // + && + // + (conditions.ichConditions.isFutureSenkouSpanAUnderB || + conditions.ichConditions.isFutureSenkouSpanAUnderLast || + conditions.ichConditions.isFutureSenkouSpanACrossedUnderB || + conditions.ichConditions.isFutureSenkouSpanACrossedUnderLast) + // + ; + if (isICHPassed) + { + result++; + } + + // + // 5 + // XSTR ... + bool isSTRPassed = + // + conditions.strConditions.isTrendBearish || + conditions.strConditions.isTrendSwitchedToBearish + // + ; + if (isSTRPassed) + { + result++; + } + + // + // 6 + // XMRB ... + bool isMRBPassed = + // + conditions.mrbConditions.isFastUnderSlow || + conditions.mrbConditions.isFastCrossedUnderSlow + // + ; + if (isMRBPassed) + { + result++; + } + + // + // 7 + // XVLM ... + bool isVLMPassed = + // + conditions.vlmConditions.isVolumeBearish || + conditions.vlmConditions.isVolumeUnderLast || + conditions.vlmConditions.isVolumeChangedToBearish + // + ; + if (isVLMPassed) + { + result++; + } + + // + // 8 + // XSSLC ... + bool isSSLCPassed = + // + conditions.sslcConditions.isBearish || + conditions.sslcConditions.isSwitchedToBearish + // + ; + if (isSSLCPassed) + { + result++; + } + + // + // 9 + // XHULL ... + bool isHULLPassed = + // + conditions.hullConditions.isBearish || + conditions.hullConditions.isUpBearish || + conditions.hullConditions.isDownBearish || + conditions.hullConditions.isSwitchedToBearish + // + ; + if (isHULLPassed) + { + result++; + } + + // + // 10 + // XADX ... + bool isADXTDPassed = + // + conditions.adxtdConditions.isBearish || + conditions.adxtdConditions.isSwitchedToBearish || + conditions.adxtdConditions.isStrongSwitchedToBearish + // + ; + if (isADXTDPassed) + { + result++; + } + + // + // 11 + // XMC ... + bool isMCPassed = + // + ((conditions.mcConditions.isBearish || + conditions.mcConditions.isSwitchedToBearish) + // + || + // + ((conditions.mcConditions.isFastUnderVerifier || + conditions.mcConditions.isFastCrossedUnderVerifier) + // + && + // + (conditions.mcConditions.isSlowUnderVerifier || + conditions.mcConditions.isSlowCrossedUnderVerifier))) + // + || + // + (conditions.mcConditions.isSARBearish || + conditions.mcConditions.isSARSwitchedToBearish) + // + ; + if (isMCPassed) + { + result++; + } + + // + // 12 + // XSLN ... + bool isXSLNPassed = + // + (conditions.slnConditions.isBearish || + conditions.slnConditions.isSwitchedToBearish) + // + ; + if (isXSLNPassed) + { + result++; + } + + // + // 13 + // XHTD ... + bool isXHTDPassed = + // + (conditions.htdConditions.isBearish || + conditions.htdConditions.isSwitchedToBearish) + // + ; + if (isXHTDPassed) + { + result++; + } + + // + // 14 + // XATSL ... + bool isXATSLPassed = + // + (conditions.atslConditions.isBearish || + conditions.atslConditions.isSwitchedToBearish) + // + ; + if (isXATSLPassed) + { + result++; + } + + // + return result; + } + + // + bool IsConditionsValidForShort( + X121SetupConditions &conditions, // Conditions + int verifications = 10 // Number of Verifications + ) + { + // + bool result = false; + + // + int signs = CountShortValidations(conditions); + + // + result = + // + verifications <= 0 + ? signs > 0 + : signs >= verifications + // + ; + + // + return result; + } + + // + // Retrieve OSC Based Short Verifications ... + bool IsOSCShortVerified( + X121SetupConditions &conditions // Conditions + ) + { + // + bool result = false; + + // + int zIndex = 0; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + + // + result = + // + // CCI ... + conditions.cci[cIndex] > -96 && + conditions.cci[cIndex] < conditions.cci[pIndex] + // + && + // + // RSI ... + conditions.rsi[cIndex] > 30 && + conditions.rsi[cIndex] < conditions.rsi[pIndex] + // + && + // + // MACD ... + conditions.macd[cIndex] < 0 && + conditions.macdSignal[cIndex] < 0 && + conditions.macd[cIndex] < conditions.macdSignal[cIndex] + // + ; + + // + return result; + } + + // + // Custom Functions ... + + // + string GetTag() + { + return "X121"; + } +}; + +// +// Class ... +class XSCX121Setup : public XSCBaseAlert +{ + // + // Public ... +public: + // + // Props ... + XSCXRLHelper *rlHelper; + XSCXMCHelper *mcHelper; + XSCXPVHelper *pvHelper; + XSCXTDHelper *tdHelper; + XSCXHKHelper *hkHelper; + XSCXCHEHelper *cheHelper; + XSCXICHHelper *ichHelper; + XSCXSTRHelper *strHelper; + XSCXMRBHelper *mrbHelper; + XSCXOSCHelper *oscHelper; + XSCXVLMHelper *vlmHelper; + XSCXSLNHelper *slnHelper; + XSCXHTDHelper *hdtHelper; + XSCXCHMAHelper *chmaHelper; + XSCXATSLHelper *atslHelper; + XSCXASCTHelper *asctHelper; + XSCXSSLCHelper *sslcHelper; + XSCXHULLHelper *hullHelper; + XSCXDMNTHelper *dmntHelper; + XSCXADXTDHelper *adxtdHelper; + + // + // Constructor(s) ... + void XSCX121Setup() {} + + // + // Deconstructor ... + void ~XSCX121Setup() + { + // + delete rlHelper; + delete mcHelper; + delete pvHelper; + delete tdHelper; + delete hkHelper; + delete cheHelper; + delete ichHelper; + delete strHelper; + delete mrbHelper; + delete oscHelper; + delete vlmHelper; + delete hdtHelper; + delete asctHelper; + delete sslcHelper; + delete hullHelper; + delete atslHelper; + delete dmntHelper; + delete adxtdHelper; + } + + // + // Getter(s) / Setter(s) ... + + // + string GetSymbol() + { + return inputs.symbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return inputs.period; + } + + // + // Tools ... + + // + bool Init( + X121SetupInputs &_inputs // Configurations + ) + { + // + bool result = false; + + // + result = _inputs.IsValid(); + if (!result) + { + return result; + } + + // + inputs = _inputs; + + // + // Initialize Helpers ... + + // + // XPV ... + pvHelper = new XSCXPVHelper(); + result = pvHelper.Init( + inputs.symbol, + inputs.period, + inputs.pvInputs // + ); + if (!result) + { + return result; + } + + // + // XRL ... + rlHelper = new XSCXRLHelper(); + result = rlHelper.Init( + inputs.symbol, + inputs.period, + inputs.rlInputs // + ); + if (!result) + { + return result; + } + + // + // XSLN ... + slnHelper = new XSCXSLNHelper(); + result = slnHelper.Init( + inputs.symbol, + inputs.period, + inputs.slnInputs // + ); + if (!result) + { + return result; + } + + // + // XTD ... + tdHelper = new XSCXTDHelper(); + result = tdHelper.Init( + inputs.symbol, + inputs.period, + inputs.tdInputs // + ); + if (!result) + { + return result; + } + + // + // XHTD ... + hdtHelper = new XSCXHTDHelper(); + result = hdtHelper.Init( + inputs.symbol, + inputs.period, + inputs.htdInputs // + ); + if (!result) + { + return result; + } + + // + // XCHMA ... + chmaHelper = new XSCXCHMAHelper(); + result = chmaHelper.Init( + inputs.symbol, + inputs.period, + inputs.chmaInputs // + ); + if (!result) + { + return result; + } + + // + // XATSL ... + atslHelper = new XSCXATSLHelper(); + result = atslHelper.Init( + inputs.symbol, + inputs.period, + inputs.atslInputs // + ); + if (!result) + { + return result; + } + + // + // XDMNT ... + dmntHelper = new XSCXDMNTHelper(); + result = dmntHelper.Init( + inputs.symbol, + inputs.period, + inputs.dmntInputs // + ); + if (!result) + { + return result; + } + + // + // XHK ... + hkHelper = new XSCXHKHelper(); + result = hkHelper.Init( + inputs.symbol, + inputs.period, + inputs.hkInputs // + ); + if (!result) + { + return result; + } + + // + // XCHE ... + cheHelper = new XSCXCHEHelper(); + result = cheHelper.Init( + inputs.symbol, + inputs.period, + inputs.cheInputs // + ); + if (!result) + { + return result; + } + + // + // XICH ... + ichHelper = new XSCXICHHelper(); + result = ichHelper.Init( + inputs.symbol, + inputs.period, + inputs.ichInputs // + ); + if (!result) + { + return result; + } + + // + // XSTR ... + strHelper = new XSCXSTRHelper(); + result = strHelper.Init( + inputs.symbol, + inputs.period, + inputs.strInputs // + ); + if (!result) + { + return result; + } + + // + // XMRB ... + mrbHelper = new XSCXMRBHelper(); + result = mrbHelper.Init( + inputs.symbol, + inputs.period, + inputs.mrbInputs // + ); + if (!result) + { + return result; + } + + // + // XOSC ... + oscHelper = new XSCXOSCHelper(); + result = oscHelper.Init( + inputs.symbol, + inputs.period, + inputs.oscInputs // + ); + if (!result) + { + return result; + } + + // + // XVLM ... + vlmHelper = new XSCXVLMHelper(); + result = vlmHelper.Init( + inputs.symbol, + inputs.period, + inputs.vlmInputs // + ); + if (!result) + { + return result; + } + + // + // XMC ... + mcHelper = new XSCXMCHelper(); + result = mcHelper.Init( + inputs.symbol, + inputs.period, + inputs.mcInputs // + ); + if (!result) + { + return result; + } + + // + // XASCT ... + asctHelper = new XSCXASCTHelper(); + result = asctHelper.Init( + inputs.symbol, + inputs.period, + inputs.asctInputs // + ); + if (!result) + { + return result; + } + + // + // XSSLC ... + sslcHelper = new XSCXSSLCHelper(); + result = sslcHelper.Init( + inputs.symbol, + inputs.period, + inputs.sslcInputs // + ); + if (!result) + { + return result; + } + + // + // XHULL ... + hullHelper = new XSCXHULLHelper(); + result = hullHelper.Init( + inputs.symbol, + inputs.period, + inputs.hullInputs // + ); + if (!result) + { + return result; + } + + // + // XADXTD ... + adxtdHelper = new XSCXADXTDHelper(); + result = adxtdHelper.Init( + inputs.symbol, + inputs.period, + inputs.adxtdInputs // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + X121SetupInputs GetInputs() + { + return inputs; + } + + // + bool SetInputs( + X121SetupInputs &_inputs // Configurations + ) + { + return Init(_inputs); + } + + // + bool GetConditions( + X121SetupConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = true; + + // + conditions.Clean(); + + // + conditions.symbol = GetSymbol(); + conditions.period = GetPeriod(); + conditions.time = TimeCurrent(); + + // + result = rlHelper.GetConditions( + conditions.rlConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = hdtHelper.GetConditions( + conditions.htdConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = slnHelper.GetConditions( + conditions.slnConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = chmaHelper.GetConditions( + conditions.chmaConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = atslHelper.GetConditions( + conditions.atslConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = dmntHelper.GetConditions( + conditions.dmntConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = pvHelper.GetConditions( + conditions.pvConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = tdHelper.GetConditions( + conditions.tdConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = hkHelper.GetConditions( + conditions.hkConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = cheHelper.GetConditions( + conditions.cheConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = ichHelper.GetConditions( + conditions.ichConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = strHelper.GetConditions( + conditions.strConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = mrbHelper.GetConditions( + conditions.mrbConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = mcHelper.GetConditions( + conditions.mcConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = asctHelper.GetConditions( + conditions.asctConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = vlmHelper.GetConditions( + conditions.vlmConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = sslcHelper.GetConditions( + conditions.sslcConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = hullHelper.GetConditions( + conditions.hullConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + result = adxtdHelper.GetConditions( + conditions.adxtdConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + + // + oscHelper.CopyCCI( + barIndex, + loopback, + conditions.cci // + ); + oscHelper.CopyRSI( + barIndex, + loopback, + conditions.rsi // + ); + oscHelper.CopyMACD( + barIndex, + loopback, + conditions.macd // + ); + oscHelper.CopyMACDSignal( + barIndex, + loopback, + conditions.macdSignal // + ); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + X121SetupInputs inputs; // Setup Configurations ... +}; + +// +// Tools ... + +// +int FindSignalConditionsIndex( + XSignal &signal, + X121SetupConditions &conditions[] // +) +{ + // + int result = -1; + + // + // Check Signal is Valid ... + if (!signal.IsValid()) + { + return result; + } + + // + // Check Conditions Count ... + int conditionsCount = ArraySize(conditions); + if (!IsValidSize(conditionsCount)) + { + return result; + } + + // + for (int i = 0; i < conditionsCount; i++) + { + // + X121SetupConditions iConditions = conditions[i]; + + // + if (signal.symbol == iConditions.symbol && + signal.period == iConditions.period) + { + // + result = i; + break; + } + } + + // + return result; +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.ex5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.ex5 new file mode 100644 index 0000000..a7607e1 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.mq5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.mq5 new file mode 100644 index 0000000..6fdd570 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.x121.setup.cycle.class.mq5 @@ -0,0 +1,828 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121SetupCycle +// Description: provides implementation of X121 +// Setup on Specified Market Cycle ... +// +// +// 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 + +// +// Imports ... + +// +#include +#include "../Classes/x-saherelm.x121.setup.class.mq5" + +// +// Definitions ... + +// +// Inputs ... +struct X121SetupCycleInputs +{ + // + // Props ... + + // + XMarketCycle cycle; // Market Cycle + + // + X121SetupInputs inputs; // Inputs + + // + XSCX121Setup *setup; // Setup + + // + // Constructor ... + void X121SetupCycleInputs() + { + } + + // + // Initialization ... + bool Init( + X121SetupInputs &_inputs, // Configurations + ENUM_TIMEFRAMES _hostPeriod, // Host Period + ENUM_X_MARKET_CYCLES _cycle, // Init Cycle + ENUM_X_PERIOD_METHOD _method, // Period Selection Method + ENUM_TIMEFRAMES _period, // Provided Period + string _prefix = "" // Prefix + ) + { + // + bool result = false; + + // + // Validate Inputs ... + result = + // + IsValid(_inputs.symbol) + // + ; + if (!result) + { + return result; + } + + // + // Init Cycle ... + result = cycle.Init( + inputs.symbol, + _hostPeriod, + _cycle, + _method, + _period, + _prefix // + ); + if (!result) + { + return result; + } + + // + cycle.Update(0); + + // + _inputs.period = cycle.period; + + // + result = _inputs.IsValid(); + if (!result) + { + return result; + } + + // + this.inputs = _inputs; + + // + setup = new XSCX121Setup(); + result = setup.Init( + inputs // + ); + + // + return result; + } + + // + // Tools ... + + // + string GetSymbol() + { + return inputs.symbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return inputs.period; + } + + // + bool CanProcessBar() + { + return cycle.barTracker.CanProcessBar(); + } + + // + void WaitsUntilNextBar() + { + cycle.barTracker.Waits(); + } + + // + bool GetConditions( + X121SetupConditions &conditions, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + result = cycle.Update( + barIndex // + ); + + // + result = setup.GetConditions( + conditions, + barIndex, + loopback // + ); + + // + return result; + } +}; + +// +// Class ... +class XSCX121SetupCycles : public XSCBaseAlert +{ + // + // Public ... +public: + // + // Props ... + X121SignalGenerator signalGenerator; + + // + X121SetupCycleInputs cCycle; // Current (Host) Cycle + X121SetupCycleInputs sCycle; // Short Cycle + X121SetupCycleInputs mCycle; // Medium Cycle + X121SetupCycleInputs lCycle; // Long Cycle + X121SetupCycleInputs hCycle; // Hind Cycle + + // + // Constructor(s) ... + void XSCX121SetupCycles() {} + + // + // Deconstructor ... + void ~XSCX121SetupCycles() {} + + // + // Initialized ... + bool Init( + X121SetupInputs &_inputs, // Configurations + string _symbol, // Trading Symbol + ENUM_TIMEFRAMES _hostPeriod, // Host Period + ENUM_X_PERIOD_METHOD _sMethod = X_PERIOD_AUTO, // Short Period Selection Method + ENUM_TIMEFRAMES _sPeriod = NULL, // Short Provided Period + ENUM_X_PERIOD_METHOD _mMethod = X_PERIOD_AUTO, // Medium Period Selection Method + ENUM_TIMEFRAMES _mPeriod = NULL, // Medium Provided Period + ENUM_X_PERIOD_METHOD _lMethod = X_PERIOD_AUTO, // Long Period Selection Method + ENUM_TIMEFRAMES _lPeriod = NULL, // Long Provided Period + ENUM_X_PERIOD_METHOD _hMethod = X_PERIOD_AUTO, // Hind Period Selection Method + ENUM_TIMEFRAMES _hPeriod = NULL // Hind Provided Period + ) + { + // + bool result = false; + + // + // Check Validation of Symbol and Period ... + result = + // + IsValid(_symbol) && + IsValid(_hostPeriod) + // + ; + if (!result) + { + return result; + } + + // + // Initialize Market Cycles ... + + // + // Current ... + _inputs.symbol = _symbol; + result = cCycle.Init( + _inputs, + _hostPeriod, + X_MARKET_CYCLE_SHORT, + X_PERIOD_MANUALLY, + _hostPeriod, + "CURR" // + ); + if (!result) + { + return result; + } + + // + result = cBarTracker.Init( + _inputs.symbol, + _hostPeriod // + ); + if (!result) + { + return result; + } + + // + // Short ... + result = sCycle.Init( + _inputs, + _hostPeriod, + X_MARKET_CYCLE_SHORT, + _sMethod, + _sPeriod // + ); + if (!result) + { + return result; + } + + // + result = sBarTracker.Init( + _inputs.symbol, + sCycle.cycle.period // + ); + if (!result) + { + return result; + } + + // + // Medium ... + result = mCycle.Init( + _inputs, + _hostPeriod, + X_MARKET_CYCLE_MEDIUM, + _mMethod, + _mPeriod // + ); + if (!result) + { + return result; + } + + // + result = mBarTracker.Init( + _inputs.symbol, + mCycle.cycle.period // + ); + if (!result) + { + return result; + } + + // + // Long ... + result = lCycle.Init( + _inputs, + _hostPeriod, + X_MARKET_CYCLE_LONG, + _lMethod, + _lPeriod // + ); + if (!result) + { + return result; + } + + // + result = lBarTracker.Init( + _inputs.symbol, + lCycle.cycle.period // + ); + if (!result) + { + return result; + } + + // + // Hind ... + result = hCycle.Init( + _inputs, + _hostPeriod, + X_MARKET_CYCLE_HIND, + _hMethod, + _hPeriod // + ); + if (!result) + { + return result; + } + + // + result = hBarTracker.Init( + _inputs.symbol, + hCycle.cycle.period // + ); + if (!result) + { + return result; + } + + // + _inputs.period = cCycle.GetPeriod(); + + // + this.inputs = _inputs; + result = inputs.IsValid(); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + X121SetupInputs GetInputs() + { + return this.inputs; + } + + // + bool SetInputs( + X121SetupInputs &_inputs // Cycles Configurations + ) + { + // + bool result = Init( + _inputs, + _inputs.symbol, + _inputs.period // + ); + + // + return result; + } + + // + string GetSymbol() + { + return cCycle.GetSymbol(); + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return cCycle.GetPeriod(); + } + + // + bool ForceState() + { + return forceState; + } + + // + void ForceState(bool value) + { + forceState = value; + } + + // + bool CanProcessBar( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN // + ) + { + // + bool result = false; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + result = sBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + result = mBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_LONG: + // + result = lBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_HIND: + // + result = hBarTracker.CanProcessBar(); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + result = cBarTracker.CanProcessBar(); + break; + } + + // + return result; + } + + // + datetime GetNextSignalTime( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN // + ) + { + // + datetime result = NULL; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + result = sNextValidSignal; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + result = mNextValidSignal; + break; + + // + case X_MARKET_CYCLE_LONG: + result = lNextValidSignal; + break; + + // + case X_MARKET_CYCLE_HIND: + result = hNextValidSignal; + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + result = cNextValidSignal; + break; + } + + // + return result; + } + + // + void WaitsUntilNextBar( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN // + ) + { + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + FillNextBarTime( + sNextValidSignal, + sBarTracker // + ); + sBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + FillNextBarTime( + mNextValidSignal, + mBarTracker // + ); + mBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_LONG: + // + FillNextBarTime( + lNextValidSignal, + lBarTracker // + ); + lBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_HIND: + // + FillNextBarTime( + hNextValidSignal, + hBarTracker // + ); + hBarTracker.Waits(); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + FillNextBarTime( + cNextValidSignal, + cBarTracker // + ); + cBarTracker.Waits(); + break; + } + } + + // + bool GetConditions( + X121SetupConditions &conditions, // + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + result = sCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + result = mCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_LONG: + // + result = lCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_HIND: + // + result = hCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + result = cCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + } + + // + return result; + } + + // + XSCZones *GetZones( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, // + int barIndex = 0, // + int numberOfZones = 10 // + ) + { + // + XSCZonesInput zInputs; + zInputs.numberOfZones = numberOfZones; + + // + int length = 0; + ENUM_TIMEFRAMES zPeriod = NULL; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + zPeriod = sCycle.GetPeriod(); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + zPeriod = mCycle.GetPeriod(); + break; + + // + case X_MARKET_CYCLE_LONG: + // + zPeriod = lCycle.GetPeriod(); + break; + + // + case X_MARKET_CYCLE_HIND: + // + zPeriod = hCycle.GetPeriod(); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + zPeriod = cCycle.GetPeriod(); + break; + } + + // + ENUM_TIMEFRAMES cPeriod = GetPeriod(); + length = (PeriodSeconds(zPeriod) / PeriodSeconds(cPeriod)) + 1; + + // + zInputs.length = length; + XSCZones *result = new XSCZones( + GetSymbol(), + cPeriod // + ); + if (!result.Init(zInputs)) + { + return NULL; + } + + // + return result; + } + + // + bool ProcessMarket( + XSignal &signal, + X121SetupConditions &conditions, + int &pushers, + string &provider, + double &tp, + double &sl, + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, + bool allowSupports = false, // Allow Support Signal Generating ... + bool allowLong = false, + bool allowShort = false, + double volume = 0.01, + double slPoint = 100, + bool ignoreSL = false, + double tpPoint = 100, + bool ignoreTP = false, + int barIndex = 0, + int loopback = 5 // + ) + { + // + bool result = false; + + // + result = CanProcessBar( + cycle // + ); + if (!result) + { + return result; + } + + // + result = GetConditions( + conditions, + cycle, // Current Market ... + barIndex, // Bar Index ... + loopback // Loop Back ... + ); + if (!result) + { + return result; + } + + // + // Parse Conditions for Signal ... + result = signalGenerator.HasSignal( + conditions, + signal, + pushers, + provider, + tp, + sl, + allowSupports, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP // + ); + + // + if (result) + { + // + WaitsUntilNextBar( + cycle // + ); + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + X121SetupInputs inputs; // Cycles Configurations + + // + bool forceState; // Force State + + // + // Bar Trackers ... + XBarTracker cBarTracker; + XBarTracker sBarTracker; + XBarTracker mBarTracker; + XBarTracker lBarTracker; + XBarTracker hBarTracker; + + // + datetime cNextValidSignal; + datetime sNextValidSignal; + datetime mNextValidSignal; + datetime lNextValidSignal; + datetime hNextValidSignal; + + // + void FillNextBarTime( + datetime &next, + XBarTracker &tracker // + ) + { + // + next = iTime( + tracker.symbol, + tracker.period, + 0) + + PeriodSeconds(tracker.period); + } +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.ex5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.ex5 new file mode 100644 index 0000000..e4e3a2b Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.mq5 b/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.mq5 new file mode 100644 index 0000000..99f687a --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.x121.setup.xea.mq5 @@ -0,0 +1,5771 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121SetupCycle +// Description: provides implementation of X121 +// Setup on Specified Market Cycle ... +// +// +// 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 + +// +// Imports ... + +// +#include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" +#include "../Classes/x-saherelm.xea.class.mq5" + +// +// Definitions ... + +// +// Model all Trades Data as this Structure ... +struct XTradeInfo +{ + // + int pushers; // Signal Pushers + datetime time; // Issue Time (Open Position) + string symbol; // Trading Symbol + double entry; // Entry Price + double volume; // Volume + string provider; // Signaller + ENUM_TIMEFRAMES period; // Trading Timeframe + ENUM_X_POSITION_TYPES type; // Position Type + + // + ulong ticket; // Position Ticket + double profit; // Profit on Close + double commission; // Commission + double swap; // Swap + string message; // Close Reason + datetime endTime; // End Time + + // + X121SetupConditions cConditions; // Generated Current Conditions + X121SetupConditions sConditions; // Generated Short Conditions + X121SetupConditions mConditions; // Generated Medium Conditions + X121SetupConditions lConditions; // Generated Long Conditions + X121SetupConditions hConditions; // Generated Hind Conditions + + // + // Constructor ... + void XTradeInfo() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + time = NULL; + type = NULL; + symbol = NULL; + period = NULL; + endTime = NULL; + message = NULL; + provider = NULL; + + // + swap = 0; + entry = 0; + ticket = 0; + profit = 0; + volume = 0; + pushers = 0; + commission = 0; + + // + cConditions.Clean(); + sConditions.Clean(); + mConditions.Clean(); + lConditions.Clean(); + hConditions.Clean(); + + // + ResetGrid(); + ResetSupport(); + ResetRecovery(); + } + + // + bool Fill( + const XSignal &_signal, + int _pushers, + bool _allowGrid, + bool _allowRecover, + bool _allowSupport, + X121SetupConditions &_cConditions, + X121SetupConditions &_sConditions, + X121SetupConditions &_mConditions, + X121SetupConditions &_lConditions, + X121SetupConditions &_hConditions // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_signal.symbol) && + IsValid(_signal.period) && + IsValid(_signal.provider) + // + ; + + // + if (!result) + { + return result; + } + + // + pushers = _pushers; + time = _signal.time; + entry = _signal.entry; + symbol = _signal.symbol; + period = _signal.period; + volume = _signal.volume; + provider = _signal.provider; + type = ToPositionType(_signal.type); + + // + cConditions = _cConditions; + sConditions = _sConditions; + mConditions = _mConditions; + lConditions = _lConditions; + hConditions = _hConditions; + + // + allowGrid = _allowGrid; + allowRecover = _allowRecover; + allowSupport = _allowSupport; + + // + return result; + } + + // + bool IsOwn( + ulong _ticket // + ) + { + // + bool result = false; + + // + result = _ticket == ticket; + + // + return result; + } + + // + bool IsOwn( + string _symbol, + string _provider, + ENUM_TIMEFRAMES _period // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_symbol) && + IsValid(_provider) && + IsValid(_period) && + // + symbol == _symbol && + provider == _provider && + period == _period + // + ; + + // + return result; + } + + // + // Data Collector ... + + // + bool IsValid() + { + // + bool result = false; + + // + result = + // + ticket > 0 && + IsValid(time) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } + + // + int GetAge() + { + // + int result = -1; + + // + if (!IsValid(symbol) || + !IsValid(time) || + !IsValid(endTime) || + !IsValid(period)) + { + return result; + } + + // + int startIndex = iBarShift( + symbol, + period, + time, + false // + ); + + // + int endIndex = iBarShift( + symbol, + period, + endTime, + false // + ); + + // + result = MathAbs(startIndex - endIndex); + + // + return result; + } + + // + string GetFileName() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = + // + symbol + "\\" + + ToString(type) + "\\" + + (profit >= 0 ? "Profit" : "Loss") + + "\\" + + provider + "_" + + ToString(ticket) + "_" + + ToString(period) + "_" + + ToFormatString(time) + // + ; + + // + return result; + } + + // + string GetSignalFileName() + { + // + string result = NULL; + + // + result = + // + symbol + "\\" + + ToString(type) + "\\" + + provider + "_" + + ToFormatString(time) + // + ; + + // + return result; + } + + // + string ToString( + bool onlySignals = false // + ) + { + // + string result = NULL; + + // + string cConditionsStr = cConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + double cBullishScore = 0; + double cBearishScore = 0; + cConditions.GenerateScore( + cBullishScore, + cBearishScore // + ); + + // + string sConditionsStr = sConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + double sBullishScore = 0; + double sBearishScore = 0; + sConditions.GenerateScore( + sBullishScore, + sBearishScore // + ); + + // + string mConditionsStr = mConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + double mBullishScore = 0; + double mBearishScore = 0; + mConditions.GenerateScore( + mBullishScore, + mBearishScore // + ); + + // + string lConditionsStr = lConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + double lBullishScore = 0; + double lBearishScore = 0; + lConditions.GenerateScore( + lBullishScore, + lBearishScore // + ); + + // + string hConditionsStr = hConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + double hBullishScore = 0; + double hBearishScore = 0; + hConditions.GenerateScore( + hBullishScore, + hBearishScore // + ); + + // + + // + int age = GetAge(); + + // + result = + // + (onlySignals ? "" : ToString("Ticket", ticket)) + + ToString("Symbol", symbol) + + ToString("Period", period) + + ToString("Entry", entry) + + ToString("Provider", provider) + + ToString("Type", ToString(type)) + + ToString("Time", time) + + ToString("Pushers", pushers) + + (onlySignals + ? "" + : + // + "-------------" + "\n" + + ToString("Volume", volume) + + ToString("Profit", profit) + + ToString("Commission", commission) + + ToString("Swap", swap) + + ToString("End Time", endTime) + + ToString("Age", age) + + ToString("Message", message) + // + ) + + "-------------" + "\n" + + "Conditions" + "\n" + + "-------------" + "\n" + + "-------------" + "\n" + + "CURRENT [" + ToString(cConditions.period) + "]" + "\n" + "\n" + + "Bullish: " + ToString(cBullishScore) + "\n" + + "Bearish: " + ToString(cBearishScore) + "\n" + + "-------------" + "\n" + + cConditionsStr + "\n" + + "-------------" + "\n" + + "SHORT [" + ToString(sConditions.period) + "]" + "\n" + "\n" + + "Bullish: " + ToString(sBullishScore) + "\n" + + "Bearish: " + ToString(sBearishScore) + "\n" + + "-------------" + "\n" + + sConditionsStr + "\n" + + "-------------" + "\n" + + "MEDIUM [" + ToString(mConditions.period) + "]" + "\n" + "\n" + + "Bullish: " + ToString(mBullishScore) + "\n" + + "Bearish: " + ToString(mBearishScore) + "\n" + + "-------------" + "\n" + + mConditionsStr + "\n" + + "-------------" + "\n" + + "LONG [" + ToString(lConditions.period) + "]" + "\n" + "\n" + + "Bullish: " + ToString(lBullishScore) + "\n" + + "Bearish: " + ToString(lBearishScore) + "\n" + + "-------------" + "\n" + + lConditionsStr + "\n" + + "-------------" + "\n" + + "HIND [" + ToString(hConditions.period) + "]" + "\n" + "\n" + + "Bullish: " + ToString(hBullishScore) + "\n" + + "Bearish: " + ToString(hBearishScore) + "\n" + + "-------------" + "\n" + + hConditionsStr + "\n" + + // + "" + // + ; + + // + return result; + } + + // + // These are Some Helpers for Trading Controls and do not relate to Main + // purpose of Trade Handler ... + + // + // Supporting ... + + // + bool allowSupport; // Allow Support + + // + void ResetSupport() + { + allowSupport = false; + } + + // + // Retrieve Support Signal ... + bool HasSupport( + XSignal &support // + ) + { + // + bool result = false; + + // + return result; + } + + // + // Grid System Calculations ... + + // + int gLevel; // Number of Grids + bool allowGrid; // Allow Grid + double gEntry; // Represents Next Grid Signal's Entry + double gVolume; // Represent Next Grid Signal's Volume + + // + void ResetGrid() + { + // + gEntry = 0; + gLevel = 0; + gVolume = 0; + + // + allowGrid = false; + } + + // + void SetGrid( + double nextEntry, + double nextVolume // + ) + { + // + gEntry = nextEntry; + gVolume = nextVolume; + } + + // + // Prepare Data For Next Grid ... + void PrepareNextGrid( + double distance, + double volumeMultiplier // + ) + { + // + bool isValid = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + bool isLong = IsLong(type); + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + double selectedEntry = + gEntry <= 0 + ? entry + : gEntry; + double selectedVolume = + gVolume <= 0 + ? volume + : gVolume; + + // + double nextEntry = + isLong + ? selectedEntry - distancePrice + : selectedEntry + distancePrice; + double nextVolume = selectedVolume * volumeMultiplier; + + // + SetGrid( + nextEntry, + nextVolume // + ); + } + + // + // Check if a Grid Signal Exists Prepared and + // Provide it ... + bool HasGrid( + XSignal &signal, // Result Signal + double distance, + double volumeMultiplier // + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = IsValid() && + distance > 0 && + volumeMultiplier > 0; + if (!result) + { + return result; + } + + // + bool isLong = IsLong(type); + + // + ENUM_POSITION_TYPE gType = + isLong ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; + + // + double cEntry = GetEntry( + symbol, + gType // + ); + + // + result = + isLong + ? cEntry <= gEntry + : cEntry >= gEntry; + if (!result) + { + return result; + } + + // + result = signal.Prepare( + symbol, + provider, + period, + gType, + X_ORDER_MODE_MARKET, + cEntry, + gVolume, + 0, // SL ... + 0 // TP ... + ); + + // + if (result) + { + // + // set Support Token ... + string comment = GenerateSupportTag(ticket); + signal.comment = comment; + + // + PrepareNextGrid( + distance, + volumeMultiplier // + ); + + // + gLevel++; + } + + // + return result; + } + + // + // Recovery Zone System ... + + // + bool allowRecover; // Allow Recover + ENUM_POSITION_TYPE rLastRecoveryType; // Last Executed Recovery Signal's Type + double rLongEntry; // Represent Next Recovery Long Signal's Entry + double rShortEntry; // Represent Next Recovery Short Signal's Entry + double rVolume; // Represent Next Recovery Signal's Volume + double rZoneUpper; // Zone Recovery Upper Bound + double rZoneLower; // Zone Recovery Lower Bound + int rLevel; // Number of Recoveries + + // + void ResetRecovery() + { + // + rLevel = 0; + rVolume = 0; + rLongEntry = 0; + rZoneUpper = 0; + rZoneLower = 0; + rShortEntry = 0; + + // + allowRecover = false; + } + + // + void SetRecovery( + double nextLongEntry, + double nextShortEntry, + double zoneUpper, + double zoneLower, + double nextVolume // + ) + { + // + rVolume = nextVolume; + rZoneUpper = zoneUpper; + rZoneLower = zoneLower; + rLongEntry = nextLongEntry; + rShortEntry = nextShortEntry; + } + + // + void PrepareNextRecovery( + double distance, // Define Target Based On Zones + double volumeMultiplier, // Volume Multiplier + ENUM_POSITION_TYPE lastType // Last Type + ) + { + // + bool isValid = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + + // + bool isLong = IsLong(lastType); + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + double selectedEntry = + isLong + ? rLongEntry <= 0 + ? entry + : rLongEntry + : rShortEntry <= 0 + ? entry + : rShortEntry; + double selectedVolume = + rVolume <= 0 + ? volume + : rVolume; + + // + double nextLongEntry = + isLong + ? selectedEntry + : selectedEntry + distancePrice; + double nextShortEntry = + isLong + ? selectedEntry - distancePrice + : selectedEntry; + + // + double nextVolume = selectedVolume * volumeMultiplier; + // rLevel % 2 == 1 + // ? volume + // : volume * volumeMultiplier; + + // + double zoneUpper = + rZoneUpper > 0 + ? rZoneUpper + : isLong + ? entry + distancePrice + : entry + (distancePrice * 2); + double zoneLower = + rZoneLower > 0 + ? rZoneLower + : isLong + ? entry + (distancePrice * 2) + : entry - distancePrice; + + // + SetRecovery( + nextLongEntry, + nextShortEntry, + zoneUpper, + zoneLower, + nextVolume // + ); + + // + rLastRecoveryType = lastType; + } + + // + // Check if a Recovery Signal Exists Prepared and + // Provide it ... + bool HasRecovery( + XSignal &signal, // Result Signal ... + double distance, + double volumeMultiplier // + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + if (!result) + { + return result; + } + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + bool isLong = IsLong(type); + bool isLastLong = IsLong(rLastRecoveryType); + + // + // Check For Long Recovery ... + double cLongEntry = GetEntry( + symbol, + POSITION_TYPE_BUY // + ); + bool hasLongRecovery = + !isLastLong && + rLongEntry > 0 && cLongEntry >= rLongEntry; + + // + // Check For Short Recovery ... + double cShortEntry = GetEntry( + symbol, + POSITION_TYPE_SELL // + ); + bool hasShortRecovery = + isLastLong && + rShortEntry > 0 && + cShortEntry <= rShortEntry; + + // + result = hasLongRecovery || hasShortRecovery; + if (!result) + { + return result; + } + + // + ENUM_POSITION_TYPE rType = + hasLongRecovery + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double rEntry = + hasLongRecovery + ? cLongEntry + : cShortEntry; + + // + double rTP = + hasLongRecovery + ? rZoneUpper + : rZoneLower; + + // + double rSL = + hasLongRecovery + ? rZoneLower + : rZoneUpper; + + // + result = signal.Prepare( + symbol, + provider, + period, + rType, + X_ORDER_MODE_MARKET, + rEntry, + rVolume, + 0, // rSL, // SL ... + 0 // rTP // TP ... + ); + if (result) + { + // + // set Support Token ... + string comment = GenerateSupportTag(ticket); + signal.comment = comment; + + // + rLevel++; + + // + PrepareNextRecovery( + distance, + volumeMultiplier, + rType // + ); + } + + // + return result; + } +}; + +// +// a Class For Read and Write Trade Info Data in Files ... +class XTradeInfoCollector +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XTradeInfoCollector( + string _path = NULL // Base Path + ) + { + // + mAccount = new XSCAccount(); + + // + if (IsValid(_path)) + { + mPath = _path; + } + else + { + mPath = "XTradeInfo" + "\\" + mAccount.GetCompany(); + } + } + + // + // Deconstructor ... + void ~XTradeInfoCollector() {} + + // + bool IsExists(XTradeInfo &item) + { + // + bool result = false; + + // + int mHandler = GetFileHandlerForRead(item); + result = mHandler != INVALID_HANDLE; + FileClose(mHandler); + + // + return result; + } + + // + bool Save(XTradeInfo &item) + { + // + bool result = false; + + // + // Check info is Valid ... + result = item.IsValid(); + if (!result) + { + return result; + } + + // + string content = item.ToString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + int mHandler = GetFileHandlerForWrite(item); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + bool SaveSignal(XTradeInfo &item) + { + // + bool result = false; + + // + string content = item.ToString(true); + result = IsValid(content); + if (!result) + { + return result; + } + + // + int mHandler = GetSignalFileHandlerForWrite(item); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + string mPath; // Base Path ... + + // + XSCAccount *mAccount; + + // + string GetFilePath(XTradeInfo &item) + { + // + string fileName = item.GetFileName(); + + // + return GetFilePath(fileName); + } + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + "Trades" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + string GetSignalFilePath(XTradeInfo &item) + { + // + string fileName = item.GetSignalFileName(); + + // + return GetSignalFilePath(fileName); + } + string GetSignalFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + "Signals" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + int GetFileHandlerForRead(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_TXT // + ); + + // + return result; + } + int GetFileHandlerForWrite(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } + + // + int GetSignalFileHandlerForRead(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetSignalFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_TXT // + ); + + // + return result; + } + int GetSignalFileHandlerForWrite(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetSignalFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } +}; + +// +// a Class for Holding all required data for Specified Trade +// such as: +// - Signal; +// - Position; +// - Conditions; +// - Scores; +// - etc ... +class XTradeHandler +{ + // +public: + // + // Props ... + + // + // Constructor ... + void XTradeHandler( + XSCTrade *trade // an Instance of Trader Class + ) + { + // + Clean(data); + SetSave(false); + mTrader = trade; + collector = new XTradeInfoCollector(); + } + + // + // Getter(s) / Setter(s) ... + + // + // Others ... + + // + bool GetSave() + { + return mSave; + } + + // + void SetSave(bool value) + { + mSave = value; + } + + // + bool GetSaveSignalsOnly() + { + return mSaveSignalsOnly; + } + + // + void SetSaveSignalsOnly(bool value) + { + mSaveSignalsOnly = value; + } + + // + // Hedging ... + + // + double MinProfitPerTrade() + { + return mMinProfitPerTrade; + } + + // + void MinProfitPerTrade(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinProfitPerTrade = value; + } + + // + double MinProfitPerVolumeFactor() + { + return mMinProfitPerVolumeFactor; + } + + // + void MinProfitPerVolumeFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + if (value > 0 && value < 0.01) + { + value = 0.01; + } + + // + mMinProfitPerVolumeFactor = value; + } + + // + // Trailling Stop ... + + // + bool AllowTrailStop() + { + return mAllowTrailStop; + } + + // + void AllowTrailStop(bool value) + { + mAllowTrailStop = value; + } + + // + bool DisableTrailingWhenOpposit() + { + return mDisableTrailingWhenOpposit; + } + + // + void DisableTrailingWhenOpposit(bool value) + { + mDisableTrailingWhenOpposit = value; + } + + // + double NextTrailPoint() + { + return mNextTrailPoint; + } + + // + void NextTrailPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mNextTrailPoint = value; + } + + // + double FirstTrailPoint() + { + return mFirstTrailPoint; + } + + // + void FirstTrailPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mFirstTrailPoint = value; + } + + // + double NextTrailDistance() + { + return mNextTrailDistance; + } + + // + void NextTrailDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mNextTrailDistance = value; + } + + // + double FirstTrailDistance() + { + return mFirstTrailDistance; + } + + // + void FirstTrailDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mFirstTrailDistance = value; + } + + // + bool EnableTrailling() + { + // + bool result = false; + + // + result = + // + AllowTrailStop() && + NextTrailPoint() > 0 && + FirstTrailPoint() > 0 && + NextTrailDistance() > 0 && + FirstTrailDistance() > 0 + // + ; + + // + return result; + } + + // + // Supporting ... + + // + bool AllowSupport() + { + return mAllowSupport; + } + + // + void AllowSupport(bool value) + { + mAllowSupport = value; + } + + // + bool SupportOnlyForces() + { + return mSupportOnlyForces; + } + + // + void SupportOnlyForces(bool value) + { + mSupportOnlyForces = value; + } + + // + double SupportDistance() + { + return mSupportDistance; + } + + // + void SupportDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mSupportDistance = value; + } + + // + int MaxNumberOfSupports() + { + return mMaxNumberOfSupports; + } + + // + void MaxNumberOfSupports(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfSupports = value; + } + + // + double SupportVolumeMultiplier() + { + return mSupportVolumeMultiplier; + } + + // + void SupportVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mSupportVolumeMultiplier = value; + } + + // + double MaxAllowedSupportVolume() + { + return mMaxAllowedSupportVolume; + } + + // + void MaxAllowedSupportVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedSupportVolume = value; + } + + // + bool EnableSupport() + { + // + bool result = false; + + // + result = + // + AllowSupport() && + SupportDistance() > 0 && + MaxNumberOfSupports() >= 0 && + SupportVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Grid ... + + // + bool AllowGrid() + { + return mAllowGrid; + } + + // + void AllowGrid(bool value) + { + mAllowGrid = value; + } + + // + bool GridOnlyForces() + { + return mGridOnlyForces; + } + + // + void GridOnlyForces(bool value) + { + mGridOnlyForces = value; + } + + // + int MaxNumberOfGrids() + { + return mMaxNumberOfGrids; + } + + // + void MaxNumberOfGrids(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfGrids = value; + } + + // + double GridDistance() + { + return mGridDistance; + } + + // + void GridDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mGridDistance = value; + } + + // + double GridVolumeMultiplier() + { + return mGridVolumeMultiplier; + } + + // + void GridVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mGridVolumeMultiplier = value; + } + + // + double MaxAllowedGridVolume() + { + return mMaxAllowedGridVolume; + } + + // + void MaxAllowedGridVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedGridVolume = value; + } + + // + // Check Grid Properties to Validate it's Enable or not ... + bool EnableGrid() + { + // + bool result = false; + + // + result = + // + AllowGrid() && + GridDistance() > 0 && + MaxNumberOfGrids() >= 0 && + GridVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Recovery System ... + + // + bool AllowRecovery() + { + return mAllowRecovery; + } + + // + void AllowRecovery(bool value) + { + mAllowRecovery = value; + } + + // + bool RecoverOnlyForces() + { + return mRecoverOnlyForces; + } + + // + void RecoverOnlyForces(bool value) + { + mRecoverOnlyForces = value; + } + + // + int MaxNumberOfRecoveries() + { + return mMaxNumberOfRecoveries; + } + + // + void MaxNumberOfRecoveries(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfRecoveries = value; + } + + // + double RecoveryDistance() + { + return mRecoveryDistance; + } + + // + void RecoveryDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRecoveryDistance = value; + } + + // + double RecoveryVolumeMultiplier() + { + return mRecoveryVolumeMultiplier; + } + + // + void RecoveryVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mRecoveryVolumeMultiplier = value; + } + + // + double MaxAllowedRecoveryVolume() + { + return mMaxAllowedRecoveryVolume; + } + + // + void MaxAllowedRecoveryVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedRecoveryVolume = value; + } + + // + // Check Recovery Properties to Validate it's Enable or not ... + bool EnableRecovery() + { + // + bool result = false; + + // + result = + // + AllowRecovery() && + RecoveryDistance() > 0 && + MaxNumberOfRecoveries() >= 0 && + RecoveryVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Tools ... + + // + int Count() + { + return ArraySize(data); + } + + // + int FindIndex(ulong ticket) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOwn = iInfo.IsOwn( + ticket // + ); + if (isOwn) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + int FindIndex(XSignal &signal) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOWN = + // + iInfo.time == signal.time && + iInfo.symbol == signal.symbol && + iInfo.volume == signal.volume && + iInfo.period == signal.period && + iInfo.provider == signal.provider && + iInfo.type == ToPositionType(signal.type) + // + ; + + // + if (isOWN) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void Add( + XSignal &signal, + int pushers, + bool allowGrid, + bool allowRecover, + bool allowSupport, + X121SetupConditions &cConditions, + X121SetupConditions &sConditions, + X121SetupConditions &mConditions, + X121SetupConditions &lConditions, + X121SetupConditions &hConditions // + ) + { + // + XTradeInfo info; + bool isFilled = info.Fill( + signal, + pushers, + allowGrid, + allowRecover, + allowSupport, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); + if (!isFilled) + { + return; + } + + // + AddRef( + info, + data // + ); + + // + if (GetSaveSignalsOnly()) + { + collector.SaveSignal(info); + } + } + + // + void Remove(XSignal &signal) + { + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + ArrayRemove( + data, + infoIDX, + 1 // + ); + } + + // + void Update(XSignal &signal) + { + // + if (!signal.IsValid() || !signal.IsExecuted()) + { + return; + } + + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].volume = signal.volume; + data[infoIDX].ticket = signal.positionId; + + // + // Find Orders for Accessing Commission ... + XDeal deals[]; + int dealsCount = mTrader.GetDeals( + deals, + signal.symbol, + signal.provider, + signal.period, + NULL, + DEAL_ENTRY_IN // Position Open Deal ... + ); + if (!IsValidSize(dealsCount)) + { + return; + } + + // + for (int i = 0; i < dealsCount; i++) + { + // + XDeal iDeal = deals[i]; + + // + if (iDeal.positionId == signal.positionId) + { + data[infoIDX].commission = iDeal.commission; + } + } + + // + // Check if Grid System Enable or Not ... + if (EnableGrid()) + { + // + // Here we Prepare Handler Structure for + // Next Grid Position ... + if (data[infoIDX].allowGrid) + { + // + data[infoIDX].PrepareNextGrid( + GridDistance(), + GridVolumeMultiplier() // + ); + } + } + + // + // Check if Recovery System Enable or Not ... + if (EnableRecovery()) + { + // + if (data[infoIDX].allowRecover) + { + // + data[infoIDX].PrepareNextRecovery( + GridDistance(), + GridVolumeMultiplier(), + signal.type // + ); + } + } + } + + // + void Update(XDeal &deal) + { + // + if (!deal.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(deal.positionId); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = deal.swap; + data[infoIDX].endTime = deal.time; + data[infoIDX].profit = deal.profit; + + // + string message = deal.reason == DEAL_REASON_TP ? "TP" : "SL"; + data[infoIDX].message = message; + + // + Finish(infoIDX); + } + + // + void Update(XPosition &position) + { + // + if (!position.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(position.ticket); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = position.swap; + data[infoIDX].endTime = TimeCurrent(); + data[infoIDX].profit = position.profit; + data[infoIDX].message = position.comment; + + // + Finish(infoIDX); + } + + // + // Sync ... + void Sync() + { + // + int count = Count(); + if (!IsValidSize(count)) + { + return; + } + + // + int mustRemoved[]; + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + if (iInfo.ticket > 0 && !mTrader.IsOpen(iInfo.ticket)) + { + // + AddSpecific( + i, + mustRemoved // + ); + } + } + + // + int mustRemovedCount = ArraySize(mustRemoved); + if (!IsValidSize(mustRemovedCount)) + { + return; + } + + // + for (int i = 0; i < mustRemovedCount; i++) + { + // + ArrayRemove( + data, + i, + 1 // + ); + } + } + + // + // Protection Handlers ... + + // + // Handle Do All Protecting ... + int DoProtect( + XSignal &signals[], // if PRotecting Generate Some Support Signals, Holds them here + XSCX121SetupCycles *&setups[] // Number of Setups + ) + { + // + int result = 0; + + // + // Calling Protection Algorithms ... + + // + // Trailling ... + if (EnableTrailling()) + { + int traillings = HandleTrailling(); + } + + // + if (AllowSupport()) + { + // + XSignal supports[]; + int supportsCount = RequestForSupport( + supports, + setups // + ); + + // + if (IsValidSize(supportsCount)) + { + // + Copy( + supports, + signals, + false // + ); + } + } + + // + // Grid ... + if (EnableGrid()) + { + // + XSignal grids[]; + int gridsCount = RequestForGrid(grids); + if (IsValidSize(gridsCount)) + { + // + Copy( + grids, + signals, + false // + ); + } + } + + // + // Recovery ... + if (EnableRecovery()) + { + // + XSignal recoveries[]; + int recoveriesCount = RequestForRecovery(recoveries); + if (IsValidSize(recoveriesCount)) + { + // + Copy( + recoveries, + signals, + false // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int GetBreakoutsSignals(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + double iEntry = data[i].entry; + string iSymbol = data[i].symbol; + ENUM_TIMEFRAMES iPeriod = data[i].period; + ENUM_X_POSITION_TYPES iType = data[i].type; + + // + bool isLong = IsLong(iType); + ENUM_POSITION_TYPE iPType = + isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double cEntry = GetEntry( + iSymbol, + iPType // + ); + + // + XOHCL cBar; + bool isInited = cBar.Init( + iSymbol, + iPeriod, + 1 // + ); + if (!isInited) + { + continue; + } + + // + bool isBullish = cBar.IsBullish(); + bool isBreakUp = cBar.IsBreakUp(iEntry); + + // + bool isBearish = cBar.IsBearish(); + bool isBreakDown = cBar.IsBreakDown(iEntry); + + // + bool isBreaked = + isLong + ? isBullish && + isBreakUp && + cEntry > iEntry + : isBearish && + isBreakDown && + cEntry < iEntry; + + // + if (isBreaked) + { + // + // Update Date of TradeInfo ... + data[i].entry = cEntry; + data[i].time = TimeCurrent(); + + // + // Generate Signal ... + XSignal iSignal; + bool isPrepared = iSignal.Prepare( + data[i].symbol, + data[i].provider, + data[i].period, + iPType, + X_ORDER_MODE_MARKET, + data[i].entry, + data[i].volume, + 0, + 0 // + ); + + // + // Add Signal to Result ... + if (isPrepared) + { + // + AddRef( + iSignal, + signals // + ); + } + } + + // // + // double hotLevels[]; + + // // + // AddSpecific( + // 0.25, + // hotLevels // + // ); + + // // + // AddSpecific( + // 0.20, + // hotLevels // + // ); + + // // + // AddSpecific( + // 0.12, + // hotLevels // + // ); + + // // + // XSCZonesInput zonesInput; + // zonesInput.length = 71; + // zonesInput.numberOfZones = 10; + // XSCZones *zones = new XSCZones( + // iSymbol, + // _Period // + // ); + + // // + // zonesInput.AddLevelColor( + // hotLevels[0], + // clrRed // + // ); + // zonesInput.AddLevelColor( + // hotLevels[1], + // clrOrange // + // ); + // zonesInput.AddLevelColor( + // hotLevels[2], + // clrLightCoral // + // ); + // bool canUseZones = zones.Init(zonesInput); + + // // + // XSCCFInput cfInputs; + // cfInputs.Default(); + // XSCCF *cf = new XSCCF( + // iSymbol, + // _Period // + // ); + // bool canUseCF = cf.Init(cfInputs); + + // // + // XSCTrendInput tInputs; + // tInputs.Default(); + // XSCTrend *trend = new XSCTrend( + // iSymbol, + // _Period // + // ); + // bool canUseTrend = trend.Init(tInputs); + + // if (canUseCF && canUseTrend && canUseZones) + // { + // // + // // cf.Draw(); + // trend.Draw(); + // // zones.Draw(); + // Print("Use CF ..."); + // // cf.Remove(); + // // trend.Remove(); + // // zones.Remove(); + // } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + XSCTrade *mTrader; + XTradeInfo data[]; + XTradeInfoCollector *collector; + + // + bool mSave; // Save Results ... + bool mSaveSignalsOnly; // Save Only Signals and COnditions + + // + // Hedging ... + double mMinProfitPerTrade; // Minimum Required Profit for Hedging + double mMinProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Volume + + // + // Trailling ... + bool mAllowTrailStop; // Enable Trailling Stop Losses + bool mDisableTrailingWhenOpposit; // Disable Trailling When has Opposite In Drawdown + double mNextTrailPoint; // Next Trailling Step + double mFirstTrailPoint; // First Stop Trail + double mFirstTrailDistance; // Start Trailling Distance + double mNextTrailDistance; // Next Trailling Distance + + // + // Supporting ... + bool mAllowSupport; // Allow Support Signals + bool mSupportOnlyForces; // Support Only Force Signals + double mSupportDistance; // Supporting Distance + int mMaxNumberOfSupports; // Max Number of Support Signals + double mSupportVolumeMultiplier; // Support Signals Volume Multiplier + double mMaxAllowedSupportVolume; // Max Allowed Support Signals Volume + + // + // Grid ... + bool mAllowGrid; // Allow Grid Signals + bool mGridOnlyForces; // Grid Only Force Signals + int mMaxNumberOfGrids; // Max Number of Grid Signals + double mGridDistance; // Grid Distance + double mGridVolumeMultiplier; // Grid Volume Multiplier + double mMaxAllowedGridVolume; // Max Allowed Grid Signals Volume + + // + // Recovery ... + bool mAllowRecovery; // Allow Recovery Signals + bool mRecoverOnlyForces; // Recover Only Force Signals + int mMaxNumberOfRecoveries; // Max Number of Recovery Signals + double mRecoveryDistance; // Recovery Distance + double mRecoveryVolumeMultiplier; // Recovery Volume Multiplier + double mMaxAllowedRecoveryVolume; // Max Allowed Recovery Signals Volume + + // + // Tools ... + + // + void Finish(int index) + { + // + XTradeInfo info = data[index]; + if (!info.IsValid()) + { + return; + } + + // + ArrayRemove( + data, + index, + 1 // + ); + + // + if (GetSave()) + { + collector.Save(info); + } + } + + // + // Protection Methods ... + + // + int HandleTrailling() + { + // + int result = 0; + + // + // Check Trailling is Enabled or not ... + if (!EnableTrailling()) + { + return result; + } + + // + // Do Synch Before Start Trailing ... + Sync(); + + // + // Since Trailing Done based On In Profit Positions ... + // First we Check if ... + XPosition positions[]; + XPosition inDPositions[]; + XPosition inPPositions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + int inDPositionsCount = ExtractInDrawdownPositions( + positions, + inDPositions // + ); + int inPPositionsCount = ExtractInProfitPositions( + positions, + inPPositions // + ); + if (!IsValidSize(inPPositionsCount)) + { + return result; + } + + // + for (int i = 0; i < inPPositionsCount; i++) + { + // + XPosition iPosition = inPPositions[i]; + + // + // ignore Support Positions ... + bool isSupport = IsSupport(iPosition.comment); + if (isSupport) + { + continue; + } + + // + // Only Trail Positions which they Hasnt any Support ... + bool hasSupport = mTrader.HasSupport(iPosition.ticket); + result = !hasSupport; + if (!result) + { + return result; + } + + // + // Find Positin Info Index ... + int idx = FindIndex(iPosition.ticket); + if (!IsValidIndex(idx)) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + + // + // Here we Select Price for SL Trailling ... + double usedPrice = 0; + if (iPosition.sl != 0) + { + // + if (isLong) + { + // + if (iPosition.sl < iPosition.entry) + { + usedPrice = iPosition.entry; + } + else + { + usedPrice = iPosition.sl; + } + } + else + { + // + if (iPosition.sl > iPosition.entry) + { + usedPrice = iPosition.entry; + } + else + { + usedPrice = iPosition.sl; + } + } + } + else + { + usedPrice = iPosition.entry; + } + + // + double nextTrailPoint = NextTrailPoint(); + double firstTrailPoint = FirstTrailPoint(); + double nextTrailDistance = NextTrailDistance(); + double firstTrailDistance = FirstTrailDistance(); + + // + bool isFirstTrail = usedPrice == iPosition.entry; + + // + double usedTrailDiff = + isFirstTrail + ? MathMax(firstTrailPoint, firstTrailDistance) + : MathMax(nextTrailPoint, nextTrailDistance); + + // + double iExit = GetExit( + iPosition.symbol, + iPosition.type // + ); + double iPriceDistance = MathAbs(usedPrice - iExit); + double iPriceDistanceInPoint = PriceToPoint( + iPriceDistance, + iPosition.symbol // + ); + + // + bool canTrail = iPriceDistanceInPoint >= usedTrailDiff; + if (!canTrail) + { + continue; + } + + // + // Check Opposit Side Position ... + // if Exists, dont Trail ... + if (DisableTrailingWhenOpposit() && IsValidSize(inDPositionsCount)) + { + // + bool canTrail = true; + ENUM_POSITION_TYPE oppositType = GetOpposit(iPosition.type); + for (int j = 0; j < inDPositionsCount; j++) + { + // + XPosition inDPosition = inDPositions[j]; + + // + bool isOpposit = + inDPosition.symbol == iPosition.symbol && + inDPosition.type == oppositType; + if (isOpposit) + { + // + canTrail = false; + break; + } + } + + // + if (!canTrail) + { + continue; + } + } + + // + usedTrailDiff = + isFirstTrail + ? MathMin(firstTrailPoint, firstTrailDistance) + : MathMin(nextTrailPoint, nextTrailDistance); + double usedTrailDiffPrice = PointToPrice( + usedTrailDiff, + iPosition.symbol // + ); + + // + double sl = + isLong + ? usedPrice + usedTrailDiffPrice + : usedPrice - usedTrailDiffPrice; + string comment = PrepareSLTrailTag(iPosition.comment); + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment // + ); + if (isModified) + { + result++; + } + } + + // + return result; + } + + // + int RequestForSupport( + XSignal &signals[], + XSCX121SetupCycles *&setups[] // + ) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!AllowSupport()) + { + return result; + } + + // + Sync(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSignal iSupport; + double iPivot = -1; + int iPivotIDX = -1; + bool hasSupport = data[i].HasSupport( + iSupport // + ); + if (hasSupport) + { + // + AddRef( + iSupport, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + // TODO: Complete this Later ... + return result; + + // + // Validate Setups Count ... + // int setupsCount = ArraySize(setups); + // if (!IsValidSize(setupsCount)) + // { + // return result; + // } + + // // + // // Implement Supporting Mechanism ... + + // // + // // Extracting In Drawdown Positions ... + // XPosition positions[]; + // int positionsCount = mTrader.GetInDrawdownPositions( + // positions // + // ); + // if (!IsValidSize(positionsCount)) + // { + // return result; + // } + + // // + // double supportDistance = SupportDistance(); + // int maxNUmberOfSupports = MaxNumberOfSupports(); + // double maxAllowedVolume = MaxAllowedSupportVolume(); + // double volumeMultiplier = SupportVolumeMultiplier(); + + // // + // X121SignalGenerator signalGenerator; + + // // + // for (int i = 0; i < positionsCount; i++) + // { + // // + // XPosition iPosition = positions[i]; + + // // + // // Check Position is not Support Position ... + // bool isSupport = IsSupport(iPosition.comment); + // if (isSupport) + // { + // continue; + // } + + // // + // // Find Related Setp ... + // int idx = FindSetupIndex( + // iPosition.symbol, + // setups // + // ); + // if (!IsValidIndex(idx)) + // { + // continue; + // } + + // // + // int index = FindIndex(iPosition.ticket); + // if (!IsValidIndex(index)) + // { + // continue; + // } + + // // + // // Check Position must atleast 20 Point in drawdown ... + + // // + // double onePointPrice = PointToPrice( + // 1, + // iPosition.symbol // + // ); + + // // + // double iExitPrice = GetExit( + // iPosition.symbol, + // iPosition.type // + // ); + + // // + // double priceDiff = MathAbs(iPosition.entry - iExitPrice); + // double priceDiffPoints = priceDiff / onePointPrice; + + // // + // bool isFarEnough = priceDiffPoints >= (supportDistance / 2); + // if (!isFarEnough) + // { + // continue; + // } + + // // + // // Check Support COunts and etc ... + // // implementing supporting mechanis ... + + // // + // } + + // // + // result = ArraySize(signals); + + // + return result; + } + + // + int RequestForGrid(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!EnableGrid()) + { + return result; + } + + // + int maxAllowed = MaxNumberOfGrids(); + double maxAllowedVolume = MaxAllowedGridVolume(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + // Check Count ... + bool isMaxPassed = + maxAllowed <= 0 + ? true + : data[i].gLevel < maxAllowed; + if (!isMaxPassed) + { + continue; + } + + // + XSignal iSignal; + bool hasGrid = data[i].HasGrid( + iSignal, + GridDistance(), + GridVolumeMultiplier() // + ); + + // + if (hasGrid) + { + // + // Check Max Volume ... + iSignal.volume = + maxAllowedVolume <= 0 + ? iSignal.volume + : MathMin(iSignal.volume, maxAllowedVolume); + + // + AddRef( + iSignal, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int RequestForRecovery(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!EnableRecovery()) + { + return result; + } + + // + int maxAllowed = MaxNumberOfRecoveries(); + double maxAllowedVolume = MaxAllowedRecoveryVolume(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + // Check Count ... + bool isMaxPassed = + maxAllowed <= 0 + ? true + : data[i].rLevel < maxAllowed; + if (!isMaxPassed) + { + continue; + } + + // + XSignal iSignal; + bool hasRecovery = data[i].HasRecovery( + iSignal, + RecoveryDistance(), + RecoveryVolumeMultiplier() // + ); + + // + if (hasRecovery) + { + // + // Check Max Volume ... + iSignal.volume = + maxAllowedVolume <= 0 + ? iSignal.volume + : MathMin(iSignal.volume, maxAllowedVolume); + + // + AddRef( + iSignal, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int FindSetupIndex( + string symbol, + XSCX121SetupCycles *&setups[] // + ) + { + // + int result = 0; + + // + if (!IsValid(symbol)) + { + return result; + } + + // + for (int i = 0; i < ArraySize(setups); i++) + { + // + if (setups[i].GetSymbol() == symbol) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void AddHotLevelsToZones( + XSCZones *zones // + ) + { + // + zones.AddLevelColor( + 0.25, + clrRed // + ); + zones.AddLevelColor( + 0.20, + clrOrange // + ); + zones.AddLevelColor( + 0.15, + clrYellow // + ); + } +}; + +// +// Class ... +class XSCX121SetupEA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + X121SignalGenerator signalGenerator; + + // + // Constructors ... + XSCX121SetupEA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + // + // XSCTrade Event Handlers ... + TOnSignal onSignal = NULL, // On Signal Recieved Event Handler + TOnModify onModifyPosition = NULL, // On Modify Position Event Handler + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnForceClose onForceClosePosition = NULL, // On Force Close Position Event Handler + TOnPartialClose onPartialClosePosition = NULL, // On Partial Close Position Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) : XSCBaseEA(slippage, + magicNumber, + onSignal, + onModifyPosition, + onStopLossTriggered, + onTakeProfitTriggered, + onForceClosePosition, + onPartialClosePosition, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler // + ) + { + // + mTradeHandler = new XTradeHandler(mTrader); + + // + // Implement Default Configs ... + DefaultConfigs(); + } + + // + // Deconstructor ... + ~XSCX121SetupEA() + { + // + delete mTradeHandler; + + // + Clean(mSetups); + } + + // + bool AddSetup(XSCX121SetupCycles *setup) + { + // + bool result = false; + + // + result = setup != NULL; + if (!result) + { + return result; + } + + // + Add( + setup, + mSetups // + ); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + /// Signals ... + + // + bool AllowLong() + { + return mAllowLong; + } + + // + void AllowLong(bool value) + { + mAllowLong = value; + } + + // + bool AllowShort() + { + return mAllowShort; + } + + // + void AllowShort(bool value) + { + mAllowShort = value; + } + + // + int DelayBetweenTwoSignal() + { + return mDelayBetweenTwoSignal; + } + + // + void DelayBetweenTwoSignal(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mDelayBetweenTwoSignal = value; + } + + // + int ReuiredSignalVerifications() + { + return mReuiredSignalVerifications; + } + + // + void ReuiredSignalVerifications(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mReuiredSignalVerifications = value; + } + + // + bool GetVerificationFromOtherTimeFrames() + { + return mGetVerificationFromOtherTimeFrames; + } + + // + void GetVerificationFromOtherTimeFrames(bool value) + { + mGetVerificationFromOtherTimeFrames = value; + } + + // + bool ExecuteSignalsOnBreakout() + { + return mExecuteSignalsOnBreakout; + } + + // + void ExecuteSignalsOnBreakout(bool value) + { + mExecuteSignalsOnBreakout = value; + } + + // + // Risk Management ... + + // + double Volume() + { + return mVolume; + } + + // + void Volume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mVolume = value; + } + + // + double TPPoint() + { + return mTPPoint; + } + + // + void TPPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mTPPoint = value; + } + + // + double SLPoint() + { + return mSLPoint; + } + + // + void SLPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mSLPoint = value; + } + + // + int MaxAllowedTrades() + { + return mMaxAllowedTrades; + } + + // + void MaxAllowedTrades(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedTrades = value; + // mTrader.SetMaxAllowedPositions(value); + } + + // + bool UseMaxAllowedPerDirection() + { + return mUseMaxAllowedPerDirection; + } + + // + void UseMaxAllowedPerDirection(bool value) + { + mUseMaxAllowedPerDirection = value; + } + + // + bool IgnoreTP() + { + return mIgnoreTP; + } + + // + void IgnoreTP(bool value) + { + mIgnoreTP = value; + } + + // + bool IgnoreSL() + { + return mIgnoreSL; + } + + // + void IgnoreSL(bool value) + { + mIgnoreSL = value; + } + + // + bool IncreaseNextSignalsVolume() + { + return mIncreaseNextSignalsVolume; + } + + // + void IncreaseNextSignalsVolume(bool value) + { + mIncreaseNextSignalsVolume = value; + } + + // + double IncreaseNextSignalsVolumeMultiplier() + { + return mIncreaseNextSignalsVolumeMultiplier; + } + + // + void IncreaseNextSignalsVolumeMultiplier(double value) + { + // + if (value <= 0) + { + value = 0; + } + + // + mIncreaseNextSignalsVolumeMultiplier = value; + } + + // + bool AcceptNextDirectionalSignalsWhenFirstInProfit() + { + return mAcceptNextDirectionalSignalsWhenFirstInProfit; + } + + // + void AcceptNextDirectionalSignalsWhenFirstInProfit(bool value) + { + mAcceptNextDirectionalSignalsWhenFirstInProfit = value; + } + + // + // Signalling ... + + // + int StartSignallingHoure() + { + return mStartSignallingHoure; + } + + // + void StartSignallingHoure(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mStartSignallingHoure = value; + } + + // + int EndSignallingHoure() + { + return mEndSignallingHoure; + } + + // + void EndSignallingHoure(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mEndSignallingHoure = value; + } + + // + int CloseOnSpecificTime() + { + return mCloseOnSpecificTime; + } + + // + void CloseOnSpecificTime(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mCloseOnSpecificTime = value; + } + + // + bool CloseOnOpposit() + { + return mCloseOnOpposit; + } + + // + void CloseOnOpposit(bool value) + { + mCloseOnOpposit = value; + } + + // + // Trailling ... + + // + bool AllowTrailStop() + { + return mTradeHandler.AllowTrailStop(); + } + + // + void AllowTrailStop(bool value) + { + mTradeHandler.AllowTrailStop(value); + } + + // + bool DisableTrailingWhenOpposit() + { + return mTradeHandler.DisableTrailingWhenOpposit(); + } + + // + void DisableTrailingWhenOpposit(bool value) + { + mTradeHandler.DisableTrailingWhenOpposit(value); + } + + // + double NextTrailPoint() + { + return mTradeHandler.NextTrailPoint(); + } + + // + void NextTrailPoint(double value) + { + mTradeHandler.NextTrailPoint(value); + } + + // + double FirstTrailPoint() + { + return mTradeHandler.FirstTrailPoint(); + } + + // + void FirstTrailPoint(double value) + { + mTradeHandler.FirstTrailPoint(value); + } + + // + double NextTrailDistance() + { + return mTradeHandler.NextTrailDistance(); + } + + // + void NextTrailDistance(double value) + { + mTradeHandler.NextTrailDistance(value); + } + + // + double FirstTrailDistance() + { + return mTradeHandler.FirstTrailDistance(); + } + + // + void FirstTrailDistance(double value) + { + mTradeHandler.FirstTrailDistance(value); + } + + // + // Supporting ... + + // + bool AllowSupport() + { + return mTradeHandler.AllowSupport(); + } + + // + void AllowSupport(bool value) + { + mTradeHandler.AllowSupport(value); + } + + // + bool SupportOnlyForces() + { + return mTradeHandler.SupportOnlyForces(); + } + + // + void SupportOnlyForces(bool value) + { + mTradeHandler.SupportOnlyForces(value); + } + + // + bool EnableSupport() + { + return mTradeHandler.EnableSupport(); + } + + // + double SupportDistance() + { + return mTradeHandler.SupportDistance(); + } + + // + void SupportDistance(double value) + { + mTradeHandler.SupportDistance(value); + } + + // + int MaxNumberOfSupports() + { + return mTradeHandler.MaxNumberOfSupports(); + } + + // + void MaxNumberOfSupports(int value) + { + mTradeHandler.MaxNumberOfSupports(value); + } + + // + double SupportVolumeMultiplier() + { + return mTradeHandler.SupportVolumeMultiplier(); + } + + // + void SupportVolumeMultiplier(double value) + { + mTradeHandler.SupportVolumeMultiplier(value); + } + + // + double MaxAllowedSupportVolume() + { + return mTradeHandler.MaxAllowedSupportVolume(); + } + + // + void MaxAllowedSupportVolume(double value) + { + mTradeHandler.MaxAllowedSupportVolume(value); + } + + // + // Grid ... + + // + bool AllowGrid() + { + return mTradeHandler.AllowGrid(); + } + + // + void AllowGrid(bool value) + { + mTradeHandler.AllowGrid(value); + } + + // + bool GridOnlyForces() + { + return mTradeHandler.GridOnlyForces(); + } + + // + void GridOnlyForces(bool value) + { + mTradeHandler.GridOnlyForces(value); + } + + // + bool EnableGrid() + { + return mTradeHandler.EnableGrid(); + } + + // + int MaxNumberOfGrids() + { + return mTradeHandler.MaxNumberOfGrids(); + } + + // + void MaxNumberOfGrids(int value) + { + mTradeHandler.MaxNumberOfGrids(value); + } + + // + double GridDistance() + { + return mTradeHandler.GridDistance(); + } + + // + void GridDistance(double value) + { + mTradeHandler.GridDistance(value); + } + + // + double GridVolumeMultiplier() + { + return mTradeHandler.GridVolumeMultiplier(); + } + + // + void GridVolumeMultiplier(double value) + { + mTradeHandler.GridVolumeMultiplier(value); + } + + // + double MaxAllowedGridVolume() + { + return mTradeHandler.MaxAllowedGridVolume(); + } + + // + void MaxAllowedGridVolume(double value) + { + mTradeHandler.MaxAllowedGridVolume(value); + } + + // + // Recovery System ... + + // + bool AllowRecovery() + { + return mTradeHandler.AllowRecovery(); + } + + // + void AllowRecovery(bool value) + { + mTradeHandler.AllowRecovery(value); + } + + // + bool RecoverOnlyForces() + { + return mTradeHandler.RecoverOnlyForces(); + } + + // + void RecoverOnlyForces(bool value) + { + mTradeHandler.RecoverOnlyForces(value); + } + + // + bool EnableRecovery() + { + return mTradeHandler.EnableRecovery(); + } + + // + int MaxNumberOfRecoveries() + { + return mTradeHandler.MaxNumberOfRecoveries(); + } + + // + void MaxNumberOfRecoveries(int value) + { + mTradeHandler.MaxNumberOfRecoveries(value); + } + + // + double RecoveryDistance() + { + return mTradeHandler.RecoveryDistance(); + } + + // + void RecoveryDistance(double value) + { + mTradeHandler.RecoveryDistance(value); + } + + // + double RecoveryVolumeMultiplier() + { + return mTradeHandler.RecoveryVolumeMultiplier(); + } + + // + void RecoveryVolumeMultiplier(double value) + { + mTradeHandler.RecoveryVolumeMultiplier(value); + } + + // + double MaxAllowedRecoveryVolume() + { + return mTradeHandler.MaxAllowedRecoveryVolume(); + } + + // + void MaxAllowedRecoveryVolume(double value) + { + mTradeHandler.MaxAllowedRecoveryVolume(value); + } + + // + // Others ... + + // + bool SaveResults() + { + return mTradeHandler.GetSave(); + } + + // + void SaveResults(bool value) + { + mTradeHandler.SetSave(value); + } + + // + bool SaveSignalsOnly() + { + return mTradeHandler.GetSaveSignalsOnly(); + } + + // + void SaveSignalsOnly(bool value) + { + mTradeHandler.SetSaveSignalsOnly(value); + } + + // + double MinFreeMargingForOpenTrades() + { + return mMinFreeMargingForOpenTrades; + } + + // + void MinFreeMargingForOpenTrades(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinFreeMargingForOpenTrades = value; + } + + // + double MaxAllowedDrawdownPercent() + { + return mMaxAllowedDrawdownPercent; + } + + // + void MaxAllowedDrawdownPercent(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + if (value > 50) + { + value = 50; + } + + // + mMaxAllowedDrawdownPercent = value; + } + + // + // Hedging ... + + // + double MinProfitPerTrade() + { + return mTradeHandler.MinProfitPerTrade(); + } + + // + void MinProfitPerTrade(double value) + { + // + MinRequiredProfitPerTrade(value); + mTradeHandler.MinProfitPerTrade(value); + } + + // + double MinProfitPerVolumeFactor() + { + return mTradeHandler.MinProfitPerVolumeFactor(); + } + + // + void MinProfitPerVolumeFactor(double value) + { + // + MinRequiredProfitPerVolumeFactor(value); + mTradeHandler.MinProfitPerVolumeFactor(value); + } + + // + // Overrides ... + + // + // Customize Token ... + string GetToken() override + { + return GetSpecificToken(this); + } + + // + string GetTag() override + { + return this.GetToken(); + } + + // + // Tools ... + + // + // Check Provider for any Guards ... + bool CheckForGuard(XGuard &guards[]) override + { + // + bool result = false; + + // + return result; + } + + // + // Request Provider to Collect all + // Potentially Signals and then + // filters theme here and passed them + // for Executing ... + int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) override + { + // + bool result = 0; + + // + Clean(signals); + + // + if (!IsEnable()) + { + return result; + } + + // + // IMPLEMENT ... + int count = CountSetups(); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // Current ... + double cTP = 0; + double cSL = 0; + XSignal cSignal; + int cPusher = 0; + bool cHasSignal = false; + string cProvider = NULL; + X121SetupConditions cConditions; + + // + // Short ... + double sTP = 0; + double sSL = 0; + XSignal sSignal; + int sPusher = 0; + bool sHasSignal = false; + string sProvider = NULL; + X121SetupConditions sConditions; + + // + // Medium ... + double mTP = 0; + double mSL = 0; + XSignal mSignal; + int mPusher = 0; + bool mHasSignal = false; + string mProvider = NULL; + X121SetupConditions mConditions; + + // + // Long ... + double lTP = 0; + double lSL = 0; + XSignal lSignal; + int lPusher = 0; + bool lHasSignal = false; + string lProvider = NULL; + X121SetupConditions lConditions; + + // + // Hind ... + double hTP = 0; + double hSL = 0; + XSignal hSignal; + int hPusher = 0; + bool hHasSignal = false; + string hProvider = NULL; + X121SetupConditions hConditions; + + // + bool canSupport = + // + EnableSupport() && + !SupportOnlyForces() + // + ; + bool canGrid = + // + EnableGrid() && + !GridOnlyForces() + // + ; + bool canRecover = + // + EnableRecovery() && + !RecoverOnlyForces() + // + ; + + // + double volume = Volume(); + double slPoint = SLPoint(); + double tpPoint = TPPoint(); + bool ignoreSL = IgnoreSL(); + bool ignoreTP = IgnoreTP(); + bool allowLong = AllowLong(); + bool allowShort = AllowShort(); + + // + bool useCMarket = true; + bool useSMarket = true; + bool useMMarket = true; + bool useLMarket = true; + bool useHMarket = true; + + // + for (int i = 0; i < count; i++) + { + // + // Current Market ... + + // + cPusher = 0; + cSignal.Clean(); + cProvider = NULL; + cHasSignal = false; + cConditions.Clean(); + + // + cHasSignal = + !useCMarket + ? false + : mSetups[i].ProcessMarket( + cSignal, + cConditions, + cPusher, + cProvider, + cTP, + cSL, + X_MARKET_CYCLE_UNKNOWN, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Short Market ... + + // + sPusher = 0; + sSignal.Clean(); + sProvider = NULL; + sHasSignal = false; + sConditions.Clean(); + + // + sHasSignal = + !useSMarket + ? false + : mSetups[i].ProcessMarket( + sSignal, + sConditions, + sPusher, + sProvider, + sTP, + sSL, + X_MARKET_CYCLE_SHORT, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Medium Market ... + + // + mPusher = 0; + mSignal.Clean(); + mProvider = NULL; + mHasSignal = false; + mConditions.Clean(); + + // + mHasSignal = !useMMarket + ? false + : mSetups[i].ProcessMarket( + mSignal, + mConditions, + mPusher, + mProvider, + mTP, + mSL, + X_MARKET_CYCLE_MEDIUM, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Long Market ... + + // + lPusher = 0; + lSignal.Clean(); + lProvider = NULL; + lHasSignal = false; + lConditions.Clean(); + + // + lHasSignal = !useLMarket + ? false + : mSetups[i].ProcessMarket( + lSignal, + lConditions, + lPusher, + lProvider, + lTP, + lSL, + X_MARKET_CYCLE_LONG, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Hind Market ... + + // + hPusher = 0; + hSignal.Clean(); + hProvider = NULL; + hHasSignal = false; + hConditions.Clean(); + + // + hHasSignal = !useHMarket + ? false + : mSetups[i].ProcessMarket( + hSignal, + hConditions, + hPusher, + hProvider, + hTP, + hSL, + X_MARKET_CYCLE_HIND, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Parse Signals and Add them for Executing ... + + // + // Check if there is a Signal or Not ... + bool hasSignal = cHasSignal || sHasSignal || mHasSignal || lHasSignal || hHasSignal; + if (hasSignal) + { + // + XSignal signal; + X121SetupConditions otherConditions[]; + + // + if (cHasSignal) + { + // + signal.Clean(); + signal = cSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + if (sHasSignal) + { + // + signal.Clean(); + signal = sSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + if (mHasSignal) + { + // + signal.Clean(); + signal = mSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + if (lHasSignal) + { + // + signal.Clean(); + signal = lSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + if (hHasSignal) + { + // + signal.Clean(); + signal = hSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + int pushers = cPusher + sPusher + mPusher + lPusher + hPusher; + + // + bool isLong = IsLong(signal.type); + + // + // Validate Signal ... + bool isValid = + // + // Handle Pusher Validations ... + (mReuiredSignalVerifications <= 0 + ? true + : pushers >= mReuiredSignalVerifications) + // + && + // + // Handle Other Conditions Validations ... + (!mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions)) + // + ; + + // + // bool forceState = mSetups[i].ForceState(); + bool forceState = mForce; + + // + if (isValid && !forceState) + { + // + // Add Signal to Execution Result ... + AddRef( + signal, + signals // + ); + + // + // Add new Signal Info ... + mTradeHandler.Add( + signal, + pushers, + canGrid, + canRecover, + canSupport, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); + } + else + { + // + // Clear Other Conditions ... + Clean(otherConditions); + + // + // Fill All Conditions to Other Conditions ... + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // If Recieved Any Unverified Signal + // we Passed it to EQM Manager ... + EQMHandleInvalidSignal( + signal, + pushers, + isValid, + otherConditions // + ); + } + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Here we Manage Signals for Executing ... + // - Check Policies based on their Signaller ... + // - Check Same Time Open Positions ... + // - Check Signal Age for new Trade ... + // and etc ... + int HandleSignalManagement(XSignal &signals[]) override + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signalsCount)) + { + return result; + } + + // + XSignal tmpSignals[]; + XSignal eSignals[]; // Must Executed + Copy( + signals, + tmpSignals // + ); + + // + Clean(signals); + + // + int maxAllowed = MaxAllowedTrades(); + bool perDirection = UseMaxAllowedPerDirection(); + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + bool hasPositions = IsValidSize(positionsCount); + + // + double minProfitPerTrade = MinProfitPerTrade(); + double minProfitPerTradeVolumeFactor = MinProfitPerVolumeFactor(); + + // + XSymbolPositions symbolPositions[]; + int smybolPositionsCount = ExtractSymbolPositions( + positions, + symbolPositions, + minProfitPerTrade, + minProfitPerTradeVolumeFactor // + ); + bool hasSymbolPositions = IsValidSize(smybolPositionsCount); + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = tmpSignals[i]; + + // + bool isLong = IsLong(iSignal.type); + + // + bool isSignalValid = false; + bool hasSameTypeSignal = false; + bool isFirstSymbolSignal = false; + + // + // Find Symbol Index ... + int symbolIDX = FindSymbolIndex( + iSignal.symbol, + symbolPositions // + ); + bool isValidSymbolIDX = IsValidIndex(symbolIDX); + if (!isValidSymbolIDX) + { + // + // We Sure it is First Signal of Smybol in a While ... + hasSameTypeSignal = false; + isFirstSymbolSignal = true; + } + else + { + // + // We Sure it isnt First Signal of Symbol at current State ... + isFirstSymbolSignal = false; + + // + // Check Has Same Type Signal or not ... + hasSameTypeSignal = + isLong + ? symbolPositions[symbolIDX].CountLongs() > 1 + : symbolPositions[symbolIDX].CountShorts() > 1; + } + + // + // New Signals Only Accepted when there is not any Support Signals + // on their types ... + if (hasSameTypeSignal) + { + // + isSignalValid = + isLong + ? symbolPositions[symbolIDX].CountLongSupports() <= 0 + : symbolPositions[symbolIDX].CountShortSupports() <= 0; + } + else + { + isSignalValid = true; + } + if (!isSignalValid) + { + continue; + } + + // + // Check Signal Delay Passed ... + isSignalValid = + !isValidSymbolIDX + ? true + : IsSignalDelayPassed( + iSignal, + symbolPositions[symbolIDX] // + ); + if (!isSignalValid) + { + continue; + } + + // + // Handle Close All Positions when Opposit Signal Recieved ... + if (mCloseOnOpposit) + { + // + // Close Opposit Positions ... + int oppositCount = + !isValidSymbolIDX + ? 0 + : isLong + ? symbolPositions[symbolIDX].CountShorts() + : symbolPositions[symbolIDX].CountLongs(); + bool hasOpposit = IsValidSize(oppositCount); + if (hasOpposit) + { + // + XPosition opposit[]; + if (isLong) + { + // + Copy( + symbolPositions[symbolIDX].shorts, + opposit // + ); + } + else + { + // + Copy( + symbolPositions[symbolIDX].longs, + opposit // + ); + } + + // + string comment = "Close due Opposit ..."; + + // + int closeds = Close( + opposit, + comment // + ); + if (IsValidSize(closeds)) + { + // + string message = XEQMSupportToken + " Closed " + ToString(oppositCount) + " due Opposit Signal ..."; + + // + Alert(message); + } + + // + Clean(opposit); + } + + // + // Close Opposit Supports ... + int oppositSupportCount = + !isValidSymbolIDX + ? 0 + : isLong + ? symbolPositions[symbolIDX].CountShortSupports() + : symbolPositions[symbolIDX].CountLongSupports(); + bool hasOppositSupport = IsValidSize(oppositSupportCount); + if (hasOppositSupport) + { + // + XPosition opposit[]; + if (isLong) + { + // + Copy( + symbolPositions[symbolIDX].shortSupports, + opposit // + ); + } + else + { + // + Copy( + symbolPositions[symbolIDX].longSupports, + opposit // + ); + } + + // + string comment = "Close due Opposit ..."; + + // + int closeds = Close( + opposit, + comment // + ); + if (IsValidSize(closeds)) + { + // + string message = XEQMSupportToken + " Closed " + ToString(oppositCount) + " due Opposit Signal ..."; + + // + Alert(message); + } + + // + Clean(opposit); + } + } + + // + // Filter Signals Based On Max Allowed ... + if (maxAllowed > 0) + { + // + int usedCount = + !isValidSymbolIDX + ? 0 + : !perDirection + ? symbolPositions[symbolIDX].Count() + : isLong + ? symbolPositions[symbolIDX].CountLongs() + : symbolPositions[symbolIDX].CountShorts(); + isSignalValid = !IsValidSize(usedCount) + ? true + : usedCount < maxAllowed; + } + else + { + isSignalValid = true; + } + if (!isSignalValid) + { + continue; + } + + // + // Only Accept Next Same Type when Previous in Profit ... + bool acceptNewOnlyWhenLastInProfit = AcceptNextDirectionalSignalsWhenFirstInProfit(); + if (acceptNewOnlyWhenLastInProfit) + { + // + isSignalValid = + !hasSameTypeSignal + ? true + : !isValidSymbolIDX + ? true + : isLong + ? symbolPositions[symbolIDX].longsProfit > 0 + : symbolPositions[symbolIDX].shortsProfit > 0; + } + else + { + isSignalValid = true; + } + if (!isSignalValid) + { + continue; + } + + // + // Multiply Signal Volume ... + // Create First Signal Opposit Protector ... + bool canIncreaseVolume = IncreaseNextSignalsVolume(); + double volumeMultiplier = IncreaseNextSignalsVolumeMultiplier(); + if (canIncreaseVolume) + { + // + double multiplier = + (!isValidSymbolIDX + ? 0 + : isLong + ? symbolPositions[symbolIDX].CountLongs() + : symbolPositions[symbolIDX].CountShorts()) + + 1; + + // + multiplier = NormalizeDouble(multiplier * volumeMultiplier, 2); + iSignal.volume = iSignal.volume * multiplier; + } + + // + // Handle Signal ... + if (isSignalValid) + { + // + AddRef( + iSignal, + eSignals // + ); + } + + // + } + + // + result = ArraySize(eSignals); + + // + // Cutom Signal Execution ... + if (IsValidSize(result)) + { + // + // Execute Signals ... + HandleSignals(eSignals); + } + + // + // Here we maker result to 0 + // for prevent XBaseEA Calss for Executing Signal ... + result = 0; + Clean(signals); + + // + return result; + } + + // + // Handle State Management .... + // here we can manage current state ... + // - Check for Long Positions for each Signaller to Close ... + // - Handle Hedging Signaller's Positions if it's enabled ... + // - Force Closing Position when Specified Time reached ... + // - Check Start and End time or Trading Dates ... + // - handle Trailing or Risk free Signals based on several conditions ... + // and etc ... + bool HandleStateManagement(XSignal &signals[]) override + { + // + bool result = false; + + // + // Do all State Management here ... + + // + // Check if there are open Positions + // and their doesn't have TP and SL and + // Youngest Age of Positions longest as enough + // Make State of Signalling to Force State for Recieving + // Signal and Clear their Tp and SL for allowing hedges ... + EQMHandleForceState(); + + // + DoHedge(); + + // + // Handle Close All Positions on Specific Time ... + DoEQMCloseOnSpecificTime(); + + // + // Do EQM Protection if Provided ... + DoEQMProtect(); + + // + // if Returns true, Signal Execution failed ... + return result; + } + + // + // Signal Info ... + + // + void OnSignalExecuted(const XSignal &signal) override + { + // + // Signal Info Manager ... + XSignal tSignal = signal; + bool isSupport = IsSupport(signal.comment); + if (!isSupport) + { + mTradeHandler.Update(tSignal); + } + + // + mTradeHandler.Sync(); + } + + // + void OnSignalExecutionFailed( + const XSignal &signal, + const ENUM_X_SIGNAL_EXECUTION_RESULT reason // + ) override + { + // + // Signal Info Manager ... + XSignal tSignal = signal; + mTradeHandler.Remove(tSignal); + mTradeHandler.Sync(); + } + + // + void OnPositionClosed( + const XPosition &position, + const string comment // + ) override + { + // + // When a Position Closed Manually ... + // Signal Info Manager ... + XPosition tPosition = position; + bool isSupport = ExtractSupportedTicket(position.comment) > 0; + bool isEQMSupport = ExtractEQMSupportedTicket(position.comment) > 0; + tPosition.comment = comment; + if (!isSupport && !isEQMSupport) + { + mTradeHandler.Update(tPosition); + } + + // + mTradeHandler.Sync(); + } + + // + void OnStopLossTriggered(const XDeal &deal) override + { + // + // When a Position's Stop Loss Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeHandler.Update(tDeal); + mTradeHandler.Sync(); + } + + // + void OnTakeProfitTriggered(const XDeal &deal) override + { + // + // When a Position's Take Profit Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeHandler.Update(tDeal); + mTradeHandler.Sync(); + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Check Signalling Enable or not ... + bool IsEnable() + { + // + bool result = false; + + // + // Check Signal Type is Enabled or not ... + bool isTypePassed = mAllowLong || mAllowShort; + + // + // Check Signalling Time ... + MqlDateTime cTime; + bool isTimeRecieved = TimeCurrent(cTime); + + // + int endHour = EndSignallingHoure(); + int startHour = StartSignallingHoure(); + + // + bool isStartHourPassed = + startHour <= -1 + ? true + : cTime.hour >= startHour; + bool isEndHourPassed = + endHour <= -1 + ? true + : cTime.hour < endHour; + bool isTimePassed = + isTimeRecieved && + isStartHourPassed && + isEndHourPassed; + + // + result = + isTypePassed && + isTimePassed; + + // + return result; + } + + // + bool CanCloseOnTime() + { + // + bool result = false; + + // + result = + mCloseOnSpecificTime >= 0 && + mCloseOnSpecificTime <= 23; + if (!result) + { + return result; + } + + // + MqlDateTime timeStruct; + result = TimeCurrent(timeStruct); + if (!result) + { + return result; + } + + // + result = timeStruct.hour == mCloseOnSpecificTime; + + // + return result; + } + + // + // Custom Signal Execution ... + void HandleSignals(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signals)) + { + return; + } + + // + bool isMarginPassed = IsMarginPassed(); + bool isDrawdownPassed = IsDrawdownPassed(); + if (!isDrawdownPassed) + { + // + string message = "Desn't Have Good State For Execute Signals ..."; + + // + Alert(message); + + // + mForce = true; + + // + EQMHandleForceSignals(signals); + return; + } + else + { + mForce = false; + } + + // + bool executeOnBreakouts = ExecuteSignalsOnBreakout(); + if (executeOnBreakouts) + { + // + XSignal bSignals[]; + int bSignalsCount = mTradeHandler.GetBreakoutsSignals(bSignals); + if (IsValidSize(bSignalsCount)) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executedSignalsCount = ExecuteSignals( + signals, + states, + false // + ); + } + } + else + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executedSignalsCount = ExecuteSignals( + signals, + states, + false // + ); + } + } + + // + // Check Delay Between Two Signals ... + bool IsSignalDelayPassed( + XSignal &signal, + XSymbolPositions &positions // + ) + { + // + bool result = false; + + // + // Check Signal Validation ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Check Delay Signals Allowed ... + int delay = DelayBetweenTwoSignal(); + result = delay <= 0; + if (result) + { + return result; + } + + // + XPosition youngest; + int youngestAge = positions.GetYoungest( + youngest, + signal.type // + ); + result = !IsValidIndex(youngestAge); + if (result) + { + return result; + } + + // + result = youngestAge >= delay; + + // + return result; + } + + // + bool IsMarginPassed() + { + // + double freeMargin = mTrader.mAccount.GetFreeMargin(); + double minFreeMargingForHandleForce = MinFreeMargingForOpenTrades(); + + // + bool result = minFreeMargingForHandleForce <= 0 + ? true + : freeMargin >= minFreeMargingForHandleForce; + + // + return result; + } + + // + bool IsDrawdownPassed() + { + // + bool result = false; + + // + double maxAllowedDrawdownPercent = MaxAllowedDrawdownPercent(); + double drawdownPercent = GetDrawdownPercent(); + + // + result = maxAllowedDrawdownPercent <= 0 + ? true + : drawdownPercent <= maxAllowedDrawdownPercent; + + // + return result; + } + + // + // EQM Functions ... + + // + // Force Close All Positions Due EQM Hedge ... + bool DoEQMForceClose() + { + // + bool result = false; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + result = IsValidSize(positionsCount); + if (!result) + { + return result; + } + + // + double profit = SpecifiedCalculatePositionsProfit( + positions // + ); + + // + string comment = XEQMSupportToken + " Hedge ..."; + int closed = Close( + positions, + comment // + ); + + // + result = IsValidSize(closed); + if (result) + { + // + mTradeHandler.Sync(); + EQMClearAllForceStates(); + } + + // + // Handle Sleeping ... + int restingTime = RestingAfterHedge(); + if (result && IsValidSize(restingTime)) + { + Sleeping(restingTime); + } + + // + return result; + } + + // + // Do All Protecting Mechanism ... + void DoEQMProtect() + { + // + XSignal supports[]; + int supportsCount = mTradeHandler.DoProtect( + supports, + mSetups // + ); + + // + if (IsValidSize(supportsCount)) + { + EQMExecuteSignals(supports); + } + } + + // + // Handle Close Trades on Specific Time ... + void DoEQMCloseOnSpecificTime() + { + // + bool canClose = CanCloseOnTime(); + if (!canClose) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return; + } + + // + string comment = XEQMSupportToken + " Close On Specific Time ..."; + + // + int closed = Close( + positions, + comment // + ); + if (IsValidSize(closed)) + { + // + string message = XEQMSupportToken + " Closed " + ToString(closed) + " Positions on Specified Time ..."; + + // + Alert(message); + } + } + + // + // Handle any Invalid Signals ... + // this Signals passed From Request For Signal Function ... + // these need to add to Trade Handler .... + void EQMHandleInvalidSignal( + XSignal &signal, // Invalid Signal + int pushers, // Pushers + bool isValid, // IsValid Signal ... + X121SetupConditions &conditions[] // All Time Frames Conditions + ) + { + // + int setupIDX = FindSetupIndex(signal.symbol); + if (!IsValidIndex(setupIDX)) + { + return; + } + + // + // bool isForce = mSetups[setupIDX].ForceState(); + if (!mForce) + { + return; + } + + // + // TODO: Implement this later ... + return; + + // + XSignal signals[]; + + // + if (isValid) + { + // + bool canSupport = + // + EnableSupport() && + SupportOnlyForces() + // + ; + bool canGrid = + // + EnableGrid() && + GridOnlyForces() + // + ; + bool canRecover = + // + EnableRecovery() && + RecoverOnlyForces() + // + ; + + // + AddRef( + signal, + signals // + ); + + // + // Add new Signal Info ... + mTradeHandler.Add( + signal, + pushers, + canGrid, + canRecover, + canSupport, + conditions[0], + conditions[1], + conditions[2], + conditions[3], + conditions[4] // + ); + } + + // + if (ArraySize(signals) > 0) + { + EQMExecuteSignals(signals); + } + } + + // + // When Margin not passed and Happens an Invalid Signal + // HandleSignals Functions passed Signals to this Method ... + // these Signals Added to Trade Handler Before ... + void EQMHandleForceSignals( + XSignal &signals[] // + ) + { + // + if (!mForce) + { + return; + } + + // + int count = ArraySize(signals); + if (!IsValidSize(count)) + { + return; + } + + // + // TODO: + // Implement what we want ... + } + + // + void EQMHandleForceState() + { + // + if (!mForce) + { + return; + } + + // + // Exit From Force State ... + + // + // One: Based On Positions Count ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + // + mForce = false; + return; + } + + // + // Two: Based On Free Margin ... + bool isMarginPassed = IsMarginPassed(); + bool isDrawdownPassed = IsDrawdownPassed(); + if (isDrawdownPassed) + { + // + mForce = false; + return; + } + + // + // Additional Works on Force States ... + + // + double drawdown = GetDrawdownPercent(); + double margin = mTrader.mAccount.GetMargin(); + double callMargin = mTrader.mAccount.GetMarginCall(); + double stopoutMargin = mTrader.mAccount.GetMarginStopOut(); + + // + double workingMargin = MathMax(callMargin, stopoutMargin) * 0.75; + + // + // Checking Call Margin ... + // if (drawdown > workingMargin) + // { + // // + // int maxInDPIDX = FindMaxDrawdownIndex( + // positions // + // ); + // if (IsValidIndex(maxInDPIDX)) + // { + // // + // // We Close Max In Drawdown Position to Guard Account ... + // string comment = XEQMSupportToken + " Close Max Due Guard ..."; + // bool isClosed = Close( + // positions[maxInDPIDX].ticket, + // comment // + // ); + // if (isClosed) + // { + // // + // string message = XEQMSupportToken + " Close Position (" + ToString(positions[maxInDPIDX].ticket) + ") Due Guard Account ..."; + + // // + // Alert(message); + // } + // } + // } + } + + // + // Execute Signals which Provided through + // EQM Protecting Senarios and must be Executed withouth + // any Policies ... + void EQMExecuteSignals( + XSignal &signals[] // + ) + { + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signals)) + { + return; + } + + // + // + // Execute Supports ... + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executed = ExecuteSignals( + signals, + states, + false // Ignore Policies ... + ); + if (executed != signalsCount) + { + // + // TODO: Dow What We Want ... + // Print("Error On Executing Support Signal ..."); + } + + // + // Remove Supported Signals TP and SL and leave them for Handling using HEDGE Mechanism ... + if (IsValidSize(executed)) + { + // + for (int i = 0; i < signalsCount; i++) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT iState = states[i]; + if (iState != X_SIGNAL_EXECUTION_SUCCEED) + { + continue; + } + + // + XSignal iSignal = signals[i]; + if (!iSignal.IsValid() || !iSignal.IsExecuted()) + { + continue; + } + + // + ulong iParentTicket = ExtractParentTicket(iSignal.comment); + if (iParentTicket <= 0) + { + continue; + } + + // + XPosition iParent; + bool hasParent = mTrader.GetPosition( + iParentTicket, + iParent // + ); + if (!hasParent) + { + continue; + } + + // + // Check Parent Has TP or SL ... + if (iParent.tp == 0 && iParent.sl == 0) + { + continue; + } + + // + // Remove TP and SL of Supported Positions ... + string comment = "EQM Remove TPSL ..."; + bool isModified = Modify( + iParentTicket, + 0, + 0, + comment // + ); + if (isModified) + { + // + // TODO: + // do What we want ... + } + } + } + } + + // + // Clear All Force States of Setups ... + void EQMClearAllForceStates() + { + // + int setupsCount = CountSetups(); + if (!IsValidSize(setupsCount)) + { + return; + } + + // + for (int i = 0; i < setupsCount; i++) + { + mSetups[i].ForceState(false); + } + } + + // + // Private ... +private: + // + // Props ... + + // + // Signals ... + bool mAllowLong; // Allow Long + bool mAllowShort; // Allow Short + int mReuiredSignalVerifications; // Required Verifications for Validate Signals + bool mExecuteSignalsOnBreakout; // Execute Signals On Breakouts + bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames + + // + // Risk Management ... + double mVolume; // Volume + double mTPPoint; // TP Point + double mSLPoint; // SL Point + bool mIgnoreTP; // Ignore Calculated TP + bool mIgnoreSL; // Ignore Calculated SL + int mMaxAllowedTrades; // Max Alloed Positions + bool mUseMaxAllowedPerDirection; // Use Max Allowed Positions Per Direction + bool mIncreaseNextSignalsVolume; // Increase Next Signals Volume + double mIncreaseNextSignalsVolumeMultiplier; // Increase Next Signals Volume Multiplier + bool mAcceptNextDirectionalSignalsWhenFirstInProfit; // Accept Same Symbol/Type Signal when Last in Profit + + // + // Signalling ... + bool mCloseOnOpposit; // Close all Positions on Opposit + int mEndSignallingHoure; // End Signalling at Specific Time + int mCloseOnSpecificTime; // Close All Trades in Specific Time + int mStartSignallingHoure; // Start Signalling at Specific Time + + // + // Force State: + // we can do many things in force state: + // - Prepare Force Hedging; + // - Receive Signals with minimal Verifications; + // - Increase Volume Size of in Profit Positions; + // - etc ... + bool mForce; // Determine in Force State or not + int mDelayBetweenTwoSignal; // Delay between two same signal + double mMinFreeMargingForOpenTrades; // Min Free Margin for Open Trades + double mMaxAllowedDrawdownPercent; // Max Allowed Drawdown for Open Trades + + // + XSCX121SetupCycles *mSetups[]; // Number of Setups + XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions + + // + // Apply Default Configurations ... + void DefaultConfigs() + { + // + // Signals ... + AllowLong(false); + AllowShort(false); + ReuiredSignalVerifications(0); + GetVerificationFromOtherTimeFrames(false); + + // + // Risk Management ... + TPPoint(0); + SLPoint(0); + Volume(0.01); + IgnoreTP(false); + IgnoreSL(false); + MaxAllowedTrades(0); + UseMaxAllowedPerDirection(false); + IncreaseNextSignalsVolume(false); + IncreaseNextSignalsVolumeMultiplier(1); + AcceptNextDirectionalSignalsWhenFirstInProfit(false); + + // + // Signalling ... + CloseOnOpposit(false); + EndSignallingHoure(-1); + CloseOnSpecificTime(-1); + StartSignallingHoure(-1); + + // + // Trailling ... + AllowTrailStop(false); + NextTrailPoint(0); + FirstTrailPoint(0); + NextTrailDistance(0); + FirstTrailDistance(0); + + // + // Supporting ... + AllowSupport(false); + MaxNumberOfSupports(0); + SupportOnlyForces(false); + SupportVolumeMultiplier(0.01); + MaxAllowedSupportVolume(0.08); + + // + // Grid ... + GridDistance(0); + AllowGrid(false); + MaxNumberOfGrids(0); + GridOnlyForces(false); + GridVolumeMultiplier(0.01); + MaxAllowedGridVolume(0.08); + + // + // Recovery ... + RecoveryDistance(0); + AllowRecovery(false); + MaxNumberOfRecoveries(0); + RecoverOnlyForces(false); + RecoveryVolumeMultiplier(0.01); + MaxAllowedRecoveryVolume(0.08); + + // + MaxAllowedDrawdownPercent(5); + MinFreeMargingForOpenTrades(0); + + // + SaveResults(false); + SaveSignalsOnly(true); + } + + // + // Tools ... + int CountSetups() + { + return ArraySize(mSetups); + } + + // + // Find Setup Index by Symbol and Period ... + int FindSetupIndex( + string symbol, + ENUM_TIMEFRAMES period // + ) + { + // + int result = -1; + + // + int count = CountSetups(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSCX121SetupCycles *iSetup = mSetups[i]; + + // + X121SetupInputs iInputs = iSetup.GetInputs(); + + // + if ( + iInputs.symbol == symbol && + iInputs.period == period) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + // Find Setup Index by Providing Symbol ... + int FindSetupIndex( + string symbol // + ) + { + // + int result = -1; + + // + int count = CountSetups(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSCX121SetupCycles *iSetup = mSetups[i]; + + // + X121SetupInputs iInputs = iSetup.GetInputs(); + + // + if (iInputs.symbol == symbol) + { + // + result = i; + break; + } + } + + // + return result; + } + + // +}; + +// diff --git a/BKPS/14030412/Classes/x-saherelm.xaccount.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xaccount.class.ex5 new file mode 100644 index 0000000..6631f59 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xaccount.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xaccount.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xaccount.class.mq5 new file mode 100644 index 0000000..66169f5 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xaccount.class.mq5 @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAccount +// Description: provides all Account requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +// END Definitions ... +// + +// +// START Import and Inclused requirements ... +// + +// +// Includes ... +#include +#include "../Classes/x-saherelm.base.class.mq5" + +// +// END Import and Inclused requirements ... +// + +// +// START Overrides ... +// + +// +// END Overrides ... +// + +// +// a Class for Manage Account ... +class XSCAccount : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCAccount() + { + // + mAccountInfo = new CAccountInfo(); + } + + // + // Deconstructor ... + void ~XSCAccount() + { + } + + // + // START Provided Functions ... + // + + // + // User Account ... + long GetUserAccount() + { + return mAccountInfo.Login(); + } + + // + // Account Leverage ... + long GetLeverage() + { + return mAccountInfo.Leverage(); + } + + // + // Get Trade Expert State ... + bool CanExpertTrade() + { + return mAccountInfo.TradeExpert(); + } + + // + // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... + // -------------------------- + // ACCOUNT_TRADE_MODE_DEMO + // ACCOUNT_TRADE_MODE_CONTEST + // ACCOUNT_TRADE_MODE_REAL + ENUM_ACCOUNT_TRADE_MODE GetTradeMode() + { + return mAccountInfo.TradeMode(); + } + + // + // Get Account Balance ... + double GetBalance() + { + return mAccountInfo.Balance(); + } + + // + // Get the amount of give Credit ... + double GetCredit() + { + return mAccountInfo.Credit(); + } + + // + // Get the amount of current Profit on account ... + double GetProfit() + { + return mAccountInfo.Profit(); + } + + // + // Get the amount of current Equity on account ... + double GetEquity() + { + return mAccountInfo.Equity(); + } + + // + // Get the amount of reserved Margin ... + double GetMargin() + { + return mAccountInfo.Margin(); + } + + // + // Get the amount of free Margin ... + double GetFreeMargin() + { + return mAccountInfo.FreeMargin(); + } + + // + // Get the Level of Margin ... + double GetMarginLevel() + { + return mAccountInfo.MarginLevel(); + } + + // + // Get the Level Of Margin for a Deposit ... + double GetMarginCall() + { + return mAccountInfo.MarginCall(); + } + + // + // Get the Level of Margin for Stop out ... + double GetMarginStopOut() + { + return mAccountInfo.MarginStopOut(); + } + + // + // Get the Client Name ... + string GetName() + { + return mAccountInfo.Name(); + } + + // + // Get the Trade Server Name ... + string GetServerName() + { + return mAccountInfo.Server(); + } + + // + // Get deposit Currency Name ... + string GetCurrency() + { + return mAccountInfo.Currency(); + } + + // + // Get the Company Name that serves an Account ... + string GetCompany() + { + return mAccountInfo.Company(); + } + + // + // Calculate Profits for the current account based on passed parameters ... + double CalculateTradeProfit( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry, // open price + double exit // close price + ) + { + // + double result = mAccountInfo.OrderProfitCheck( + symbol, + type, + volume, + entry, + exit); + + // + return result; + } + + // + // Calculate amount of margin which required for trade operation ... + double CalculateMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.MarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate amount of free margin left after trade operation ... + double CalculateFreeMarging( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double volume, // volume + double entry // open price + ) + { + // + double result = mAccountInfo.FreeMarginCheck( + symbol, + type, + volume, + entry); + + // + return result; + } + + // + // Calculate the Maximum possible volume of trade operation ... + double CalculateMaxVolume( + const string symbol, // trading symbol + ENUM_ORDER_TYPE type, // order type + double entry, // open price + double percent = 100 // percent of available margin + ) + { + // + double result = mAccountInfo.MaxLotCheck( + symbol, + type, + entry, + percent); + + // + return result; + } + + // + // Calculate Point Value for Given Symbol based on Account ... + double GetPointValue( + string symbol // trading symbol + ) + { + // + double result = 0; + + // + double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); + double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); + double point = SymbolInfoDouble(symbol, SYMBOL_POINT); + + // + double ticksPerPoint = tickSize / point; + + // + result = tickValue / ticksPerPoint; + + // + return result; + } + + // + // Calculate Risk Amount based on account Currency by Providing: + // Points and Volume ... + double CalculateRiskAmount( + string symbol, // trading symbol + double points, // amount of Risk Points + double volume // position Volume + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = pointValue * volume * points; + + // + return result; + } + + // + // Calculate Risk Points based on account Currency by Providing: + // Volume and Amount ... + double CalculateRiskPoints( + string symbol, // trading symbol + double volume, // position Volume + double amount // amount of Risk based on Account Currency + ) + { + // + double result = 0; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * volume); + + // + return result; + } + + // + // Calculate Volume based on account Currency by Providing: + // Amount and Risk Points ... + double CalculateVolume( + string symbol, // trading symbol + double amount, // amount of Risk based on Account Currency + double points // amount of Risk Points + ) + { + // + double result = 0; + + // + points = + points <= 0 + ? 10 + : points; + + // + double pointValue = GetPointValue(symbol); + + // + result = amount / (pointValue * points); + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Account Info ... + CAccountInfo mAccountInfo; +}; + +// +// START Usefull Functions ... +// + +// +// END Usefull Functions ... +// diff --git a/BKPS/14030412/Classes/x-saherelm.xalert.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xalert.class.ex5 new file mode 100644 index 0000000..322345f Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xalert.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xalert.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xalert.class.mq5 new file mode 100644 index 0000000..7f15e32 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xalert.class.mq5 @@ -0,0 +1,1575 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCAlert +// Description: provides all Alerts requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Class Definition ... + +class XSCAlert : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + XSCAlert( + string prefix = "X-Alert", // Alerts Prefixe + bool enableAlerts = true, // Enable Alerts + bool logAlerts = true, // Log Alerts + bool terminalAlerts = false, // Terminal Alerts + bool mailAlerts = false, // Mail Alerts + bool pushAlerts = false // Push Alerts + ) + { + // + mPrefix = prefix; + mLogAlerts = logAlerts; + mMailAlerts = mailAlerts; + mPushAlerts = pushAlerts; + mEnableAlerts = enableAlerts; + mTerminalAlerts = terminalAlerts; + + // + // Normalize Prefix if Not Provided ... + if (!IsValid(mPrefix)) + { + mPrefix = GetTag(); + } + } + + // + // Deconstructor ... + ~XSCAlert() {} + + // + // Override ... + string GetTag() override + { + return GetSpecificToken(this); + } + + // + // Properties Getter(s) / Setter(s) ... + + // + string GetPrefix() + { + return mPrefix; + } + + // + void SetPrefix(string value) + { + mPrefix = value; + } + + // + bool GetLogAlerts() + { + return mLogAlerts; + } + + // + void SetLogAlerts(bool value) + { + mLogAlerts = value; + } + + // + bool GetEnableAlerts() + { + return mEnableAlerts; + } + + // + void SetEnableAlerts(bool value) + { + mEnableAlerts = value; + } + + // + bool GetPushAlerts() + { + return mPushAlerts; + } + + // + void SetPushAlerts(bool value) + { + mPushAlerts = value; + } + + // + bool GetMailAlerts() + { + return mMailAlerts; + } + + // + void SetMailAlerts(bool value) + { + mMailAlerts = value; + } + + // + bool GetTerminalAlerts() + { + return mTerminalAlerts; + } + + // + void SetTerminalAlerts(bool value) + { + mTerminalAlerts = value; + } + + // + // Tools Funtions ... + + // + // Alerts ... + + // + // Logging an Alert ... + void LogAlert(string message) + { + // + // Validate Args ... + if (!CanLogAlert()) + { + return; + } + + // + Log(message); + } + + // + // Terminal Alert ... + void TerminalAlert(string message) + { + // + // Validate Args ... + if (!CanTerminalAlert()) + { + return; + } + + // + // Prepare Message ... + message = PrepareMessage(message); + + // Send Terminal Alert ... + Alert(message); + } + + // + // Mail Alert ... + void MailAlert(string message) + { + // + // Validate Args ... + if (!CanMailAlert()) + { + return; + } + + // + // Send Mail Alert ... + SendMail(GetPrefix(), message); + } + + // + // Send Push Notification ... + void PushAlert(string message) + { + // + // Validate Args ... + if (!CanPushAlert()) + { + return; + } + + // + // Prepare Message ... + message = PrepareMessage(message); + + // + // Send Push Notification Alert ... + SendNotification(message); + } + + // + // Send an Alert by Handling all Different Specified + // type's of Alert's if they are Enabled ... + void Alert(string message) + { + // + // Handle Log, if Enabled ... + LogAlert(message); + + // + // Handle Mail if Enabled ... + MailAlert(message); + + // + // Handle Push if Enabled ... + PushAlert(message); + + // + // Handle Terminal if Enabled ... + TerminalAlert(message); + } + + // + // Logs ... + + // + // Log a Message ... + void Log(string message) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), " > ", message); + } + void Log(string tag, string message) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), "_", tag, " > ", message); + } + void LogEmpty() + { + // + if (!CanLog()) + { + return; + } + + // + Print(" "); + } + + // + // Log Specific Array ... + template + void LogArray( + T &array[], // Array to Log + string label = NULL // Array Label + ) + { + // + if (!CanLog()) + { + return; + } + + // + Print(GetPrefix(), ">", (IsValid(label) ? label : "")); + ArrayPrint(array); + } + + // + // Error ... + + // + // Log an Error ... + void LogError( + int error = -1 // Specific Error, if it's equal to -1, use Last Error ... + ) + { + // + if (!CanLog()) + { + return; + } + + // + if (error <= -1) + { + error = GetLastError(); + } + + // + string errorMsg = GetErrorDescription(error); + + // + Log("Error: " + errorMsg); + } + + // + // Retrieve Specified Error Code Description ... + string GetErrorDescription(int err_code) + { + // + string result = ""; + + // + switch (err_code) + { + // + //--- Constant Description + + // + case ERR_SUCCESS: + result = "The operation completed successfully"; + break; + + // + case ERR_INTERNAL_ERROR: + result = "Unexpected internal error"; + break; + + // + case ERR_WRONG_INTERNAL_PARAMETER: + result = "Wrong parameter in the inner call of the client terminal function"; + break; + + // + case ERR_INVALID_PARAMETER: + result = "Wrong parameter when calling the system function"; + break; + + // + case ERR_NOT_ENOUGH_MEMORY: + result = "Not enough memory to perform the system function"; + break; + + // + case ERR_STRUCT_WITHOBJECTS_ORCLASS: + result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; + break; + + // + case ERR_INVALID_ARRAY: + result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; + break; + + // + case ERR_ARRAY_RESIZE_ERROR: + result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; + break; + + // + case ERR_STRING_RESIZE_ERROR: + result = "Not enough memory for the relocation of string"; + break; + + // + case ERR_NOTINITIALIZED_STRING: + result = "Not initialized string"; + break; + + // + case ERR_INVALID_DATETIME: + result = "Invalid date and/or time"; + break; + + // + case ERR_ARRAY_BAD_SIZE: + result = "Requested array size exceeds 2 GB"; + break; + + // + case ERR_INVALID_POINTER: + result = "Wrong pointer"; + break; + + // + case ERR_INVALID_POINTER_TYPE: + result = "Wrong type of pointer"; + break; + + // + case ERR_FUNCTION_NOT_ALLOWED: + result = "System function is not allowed to call"; + break; + + // + //--- Charts + + // + case ERR_CHART_WRONG_ID: + result = "Wrong chart ID"; + break; + + // + case ERR_CHART_NO_REPLY: + result = "Chart does not respond"; + break; + + // + case ERR_CHART_NOT_FOUND: + result = "Chart not found"; + break; + + // + case ERR_CHART_NO_EXPERT: + result = "No Expert Advisor in the chart that could handle the event"; + break; + + // + case ERR_CHART_CANNOT_OPEN: + result = "Chart opening error"; + break; + + // + case ERR_CHART_CANNOT_CHANGE: + result = "Failed to change chart symbol and period"; + break; + + // + case ERR_CHART_CANNOT_CREATE_TIMER: + result = "Failed to create timer"; + break; + + // + case ERR_CHART_WRONG_PROPERTY: + result = "Wrong chart property ID"; + break; + + // + case ERR_CHART_SCREENSHOT_FAILED: + result = "Error creating screenshots"; + break; + + // + case ERR_CHART_NAVIGATE_FAILED: + result = "Error navigating through chart"; + break; + + // + case ERR_CHART_TEMPLATE_FAILED: + result = "Error applying template"; + break; + + // + case ERR_CHART_WINDOW_NOT_FOUND: + result = "Subwindow containing the indicator was not found"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_ADD: + result = "Error adding an indicator to chart"; + break; + + // + case ERR_CHART_INDICATOR_CANNOT_DEL: + result = "Error deleting an indicator from the chart"; + break; + + // + case ERR_CHART_INDICATOR_NOT_FOUND: + result = "Indicator not found on the specified chart"; + break; + + // + //--- Graphical Objects + case ERR_OBJECT_ERROR: + result = "Error working with a graphical object"; + break; + + // + case ERR_OBJECT_NOT_FOUND: + result = "Graphical object was not found"; + break; + + // + case ERR_OBJECT_WRONG_PROPERTY: + result = "Wrong ID of a graphical object property"; + break; + + // + case ERR_OBJECT_GETDATE_FAILED: + result = "Unable to get date corresponding to the value"; + break; + + // + case ERR_OBJECT_GETVALUE_FAILED: + result = "Unable to get value corresponding to the date"; + break; + + // + //--- MarketInfo + + // + case ERR_MARKET_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_MARKET_NOT_SELECTED: + result = "Symbol is not selected in MarketWatch"; + break; + + // + case ERR_MARKET_WRONG_PROPERTY: + result = "Wrong identifier of a symbol property"; + break; + + // + case ERR_MARKET_LASTTIME_UNKNOWN: + result = "Time of the last tick is not known (no ticks)"; + break; + + // + case ERR_MARKET_SELECT_ERROR: + result = "Error adding or deleting a symbol in MarketWatch"; + break; + + // + //--- History Access + + // + case ERR_HISTORY_NOT_FOUND: + result = "Requested history not found"; + break; + + // + case ERR_HISTORY_WRONG_PROPERTY: + result = "Wrong ID of the history property"; + break; + + // + //--- Global_Variables + + // + case ERR_GLOBALVARIABLE_NOT_FOUND: + result = "Global variable of the client terminal is not found"; + break; + + // + case ERR_GLOBALVARIABLE_EXISTS: + result = "Global variable of the client terminal with the same name already exists"; + break; + + // + case ERR_MAIL_SEND_FAILED: + result = "Email sending failed"; + break; + + // + case ERR_PLAY_SOUND_FAILED: + result = "Sound playing failed"; + break; + + // + case ERR_MQL5_WRONG_PROPERTY: + result = "Wrong identifier of the program property"; + break; + + // + case ERR_TERMINAL_WRONG_PROPERTY: + result = "Wrong identifier of the terminal property"; + break; + + // + case ERR_FTP_SEND_FAILED: + result = "File sending via ftp failed"; + break; + + // + case ERR_NOTIFICATION_SEND_FAILED: + result = "Error in sending notification"; + break; + + // + //--- Custom Indicator Buffers + + // + case ERR_BUFFERS_NO_MEMORY: + result = "Not enough memory for the distribution of indicator buffers"; + break; + + // + case ERR_BUFFERS_WRONG_INDEX: + result = "Wrong indicator buffer index"; + break; + + // + //--- Custom Indicator Properties + + // + case ERR_CUSTOM_WRONG_PROPERTY: + result = "Wrong ID of the custom indicator property"; + break; + + // + //--- Account + + // + case ERR_ACCOUNT_WRONG_PROPERTY: + result = "Wrong account property ID"; + break; + + // + case ERR_TRADE_WRONG_PROPERTY: + result = "Wrong trade property ID"; + break; + + // + case ERR_TRADE_DISABLED: + result = "Trading by Expert Advisors prohibited"; + break; + + // + case ERR_TRADE_POSITION_NOT_FOUND: + result = "Position not found"; + break; + + // + case ERR_TRADE_ORDER_NOT_FOUND: + result = "Order not found"; + break; + + // + case ERR_TRADE_DEAL_NOT_FOUND: + result = "Deal not found"; + break; + + // + case ERR_TRADE_SEND_FAILED: + result = "Trade request sending failed"; + break; + + // + //--- Indicators + + // + case ERR_INDICATOR_UNKNOWN_SYMBOL: + result = "Unknown symbol"; + break; + + // + case ERR_INDICATOR_CANNOT_CREATE: + result = "Indicator cannot be created"; + break; + + // + case ERR_INDICATOR_NO_MEMORY: + result = "Not enough memory to add the indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_APPLY: + result = "The indicator cannot be applied to another indicator"; + break; + + // + case ERR_INDICATOR_CANNOT_ADD: + result = "Error applying an indicator to chart"; + break; + + // + case ERR_INDICATOR_DATA_NOT_FOUND: + result = "Requested data not found"; + break; + + // + case ERR_INDICATOR_WRONG_HANDLE: + result = "Wrong indicator handle"; + break; + + // + case ERR_INDICATOR_WRONG_PARAMETERS: + result = "Wrong number of parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_PARAMETERS_MISSING: + result = "No parameters when creating an indicator"; + break; + + // + case ERR_INDICATOR_CUSTOM_NAME: + result = "The first parameter in the array must be the name of the custom indicator"; + break; + + // + case ERR_INDICATOR_PARAMETER_TYPE: + result = "Invalid parameter type in the array when creating an indicator"; + break; + + // + case ERR_INDICATOR_WRONG_INDEX: + result = "Wrong index of the requested indicator buffer"; + break; + + // + //--- Depth of Market + + // + case ERR_BOOKS_CANNOT_ADD: + result = "Depth Of Market can not be added"; + break; + + // + case ERR_BOOKS_CANNOT_DELETE: + result = "Depth Of Market can not be removed"; + break; + + // + case ERR_BOOKS_CANNOT_GET: + result = "The data from Depth Of Market can not be obtained"; + break; + + // + case ERR_BOOKS_CANNOT_SUBSCRIBE: + result = "Error in subscribing to receive new data from Depth Of Market"; + break; + + // + //--- File Operations + + // + case ERR_TOO_MANY_FILES: + result = "More than 64 files cannot be opened at the same time"; + break; + + // + case ERR_WRONG_FILENAME: + result = "Invalid file name"; + break; + + // + case ERR_TOO_LONG_FILENAME: + result = "Too long file name"; + break; + + // + case ERR_CANNOT_OPEN_FILE: + result = "File opening error"; + break; + + // + case ERR_FILE_CACHEBUFFER_ERROR: + result = "Not enough memory for cache to read"; + break; + + // + case ERR_CANNOT_DELETE_FILE: + result = "File deleting error"; + break; + + // + case ERR_INVALID_FILEHANDLE: + result = "A file with this handle was closed, or was not opening at all"; + break; + + // + case ERR_WRONG_FILEHANDLE: + result = "Wrong file handle"; + break; + + // + case ERR_FILE_NOTTOWRITE: + result = "The file must be opened for writing"; + break; + + // + case ERR_FILE_NOTTOREAD: + result = "The file must be opened for reading"; + break; + + // + case ERR_FILE_NOTBIN: + result = "The file must be opened as a binary one"; + break; + + // + case ERR_FILE_NOTTXT: + result = "The file must be opened as a text"; + break; + + // + case ERR_FILE_NOTTXTORCSV: + result = "The file must be opened as a text or CSV"; + break; + + // + case ERR_FILE_NOTCSV: + result = "The file must be opened as CSV"; + break; + + // + case ERR_FILE_READERROR: + result = "File reading error"; + break; + + // + case ERR_FILE_BINSTRINGSIZE: + result = "String size must be specified, because the file is opened as binary"; + break; + + // + case ERR_INCOMPATIBLE_FILE: + result = "A text file must be for string arrays, for other arrays - binary"; + break; + + // + case ERR_FILE_IS_DIRECTORY: + result = "This is not a file, this is a directory"; + break; + + // + case ERR_FILE_NOT_EXIST: + result = "File does not exist"; + break; + + // + case ERR_FILE_CANNOT_REWRITE: + result = "File can not be rewritten"; + break; + + // + case ERR_WRONG_DIRECTORYNAME: + result = "Wrong directory name"; + break; + + // + case ERR_DIRECTORY_NOT_EXIST: + result = "Directory does not exist"; + break; + + // + case ERR_FILE_ISNOT_DIRECTORY: + result = "This is a file, not a directory"; + break; + + // + case ERR_CANNOT_DELETE_DIRECTORY: + result = "The directory cannot be removed"; + break; + + // + case ERR_CANNOT_CLEAN_DIRECTORY: + result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; + break; + + // + case ERR_FILE_WRITEERROR: + result = "Failed to write a resource to a file"; + break; + + // + //--- String Casting + + // + case ERR_NO_STRING_DATE: + result = "No date in the string"; + break; + + // + case ERR_WRONG_STRING_DATE: + result = "Wrong date in the string"; + break; + + // + case ERR_WRONG_STRING_TIME: + result = "Wrong time in the string"; + break; + + // + case ERR_STRING_TIME_ERROR: + result = "Error converting string to date"; + break; + + // + case ERR_STRING_OUT_OF_MEMORY: + result = "Not enough memory for the string"; + break; + + // + case ERR_STRING_SMALL_LEN: + result = "The string length is less than expected"; + break; + + // + case ERR_STRING_TOO_BIGNUMBER: + result = "Too large number, more than ULONG_MAX"; + break; + + // + case ERR_WRONG_FORMATSTRING: + result = "Invalid format string"; + break; + + // + case ERR_TOO_MANY_FORMATTERS: + result = "Amount of format specifiers more than the parameters"; + break; + + // + case ERR_TOO_MANY_PARAMETERS: + result = "Amount of parameters more than the format specifiers"; + break; + + // + case ERR_WRONG_STRING_PARAMETER: + result = "Damaged parameter of string type"; + break; + + // + case ERR_STRINGPOS_OUTOFRANGE: + result = "Position outside the string"; + break; + + // + case ERR_STRING_ZEROADDED: + result = "0 added to the string end, a useless operation"; + break; + + // + case ERR_STRING_UNKNOWNTYPE: + result = "Unknown data type when converting to a string"; + break; + + // + case ERR_WRONG_STRING_OBJECT: + result = "Damaged string object"; + break; + + // + //--- Operations with Arrays + + // + case ERR_INCOMPATIBLE_ARRAYS: + result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; + break; + + // + case ERR_SMALL_ASSERIES_ARRAY: + result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; + break; + + // + case ERR_SMALL_ARRAY: + result = "Too small array, the starting position is outside the array"; + break; + + // + case ERR_ZEROSIZE_ARRAY: + result = "An array of zero length"; + break; + + // + case ERR_NUMBER_ARRAYS_ONLY: + result = "Must be a numeric array"; + break; + + // + case ERR_ONEDIM_ARRAYS_ONLY: + result = "Must be a one-dimensional array"; + break; + + // + case ERR_SERIES_ARRAY: + result = "Timeseries cannot be used"; + break; + + // + case ERR_DOUBLE_ARRAY_ONLY: + result = "Must be an array of type double"; + break; + + // + case ERR_FLOAT_ARRAY_ONLY: + result = "Must be an array of type float"; + break; + + // + case ERR_LONG_ARRAY_ONLY: + result = "Must be an array of type long"; + break; + + // + case ERR_INT_ARRAY_ONLY: + result = "Must be an array of type int"; + break; + + // + case ERR_SHORT_ARRAY_ONLY: + result = "Must be an array of type short"; + break; + + // + case ERR_CHAR_ARRAY_ONLY: + result = "Must be an array of type char"; + break; + + // + //--- Operations with OpenCL + + // + case ERR_OPENCL_NOT_SUPPORTED: + result = "OpenCL functions are not supported on this computer"; + break; + + // + case ERR_OPENCL_INTERNAL: + result = "Internal error occurred when running OpenCL"; + break; + + // + case ERR_OPENCL_INVALID_HANDLE: + result = "Invalid OpenCL handle"; + break; + + // + case ERR_OPENCL_CONTEXT_CREATE: + result = "Error creating the OpenCL context"; + break; + + // + case ERR_OPENCL_QUEUE_CREATE: + result = "Failed to create a run queue in OpenCL"; + break; + + // + case ERR_OPENCL_PROGRAM_CREATE: + result = "Error occurred when compiling an OpenCL program"; + break; + + // + case ERR_OPENCL_TOO_LONG_KERNEL_NAME: + result = "Too long kernel name (OpenCL kernel)"; + break; + + // + case ERR_OPENCL_KERNEL_CREATE: + result = "Error creating an OpenCL kernel"; + break; + + // + case ERR_OPENCL_SET_KERNEL_PARAMETER: + result = "Error occurred when setting parameters for the OpenCL kernel"; + break; + + // + case ERR_OPENCL_EXECUTE: + result = "OpenCL program runtime error"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_SIZE: + result = "Invalid size of the OpenCL buffer"; + break; + + // + case ERR_OPENCL_WRONG_BUFFER_OFFSET: + result = "Invalid offset in the OpenCL buffer"; + break; + + // + case ERR_OPENCL_BUFFER_CREATE: + result = "Failed to create and OpenCL buffer"; + break; + + // + //--- User-Defined Errors + default: + result = "UNKNOWN Erro ..."; + break; + } + + // + return result; + } + + // + // Retrieve Specified Error Code Description ... + string GetTradeServerReturnCodeDescription(int return_code) + { + // + string result = ""; + + // + switch (return_code) + { + // + case TRADE_RETCODE_REQUOTE: + result = "Requote"; + break; + + // + case TRADE_RETCODE_REJECT: + result = "Request rejected"; + break; + + // + case TRADE_RETCODE_CANCEL: + result = "Request canceled by trader"; + break; + + // + case TRADE_RETCODE_PLACED: + result = "Order placed"; + break; + + // + case TRADE_RETCODE_DONE: + result = "Request completed"; + break; + + // + case TRADE_RETCODE_DONE_PARTIAL: + result = "Only part of the request was completed"; + break; + + // + case TRADE_RETCODE_ERROR: + result = "Request processing error"; + break; + + // + case TRADE_RETCODE_TIMEOUT: + result = "Request canceled by timeout"; + break; + + // + case TRADE_RETCODE_INVALID: + result = "Invalid request"; + break; + + // + case TRADE_RETCODE_INVALID_VOLUME: + result = "Invalid volume in the request"; + break; + + // + case TRADE_RETCODE_INVALID_PRICE: + result = "Invalid price in the request"; + break; + + // + case TRADE_RETCODE_INVALID_STOPS: + result = "Invalid stops in the request"; + break; + + // + case TRADE_RETCODE_TRADE_DISABLED: + result = "Trade is disabled"; + break; + + // + case TRADE_RETCODE_MARKET_CLOSED: + result = "Market is closed"; + break; + + // + case TRADE_RETCODE_NO_MONEY: + result = "There is not enough money to complete the request"; + break; + + // + case TRADE_RETCODE_PRICE_CHANGED: + result = "Prices changed"; + break; + + // + case TRADE_RETCODE_PRICE_OFF: + result = "There are no quotes to process the request"; + break; + + // + case TRADE_RETCODE_INVALID_EXPIRATION: + result = "Invalid order expiration date in the request"; + break; + + // + case TRADE_RETCODE_ORDER_CHANGED: + result = "Order state changed"; + break; + + // + case TRADE_RETCODE_TOO_MANY_REQUESTS: + result = "Too frequent requests"; + break; + + // + case TRADE_RETCODE_NO_CHANGES: + result = "No changes in request"; + break; + + // + case TRADE_RETCODE_SERVER_DISABLES_AT: + result = "Autotrading disabled by server"; + break; + + // + case TRADE_RETCODE_CLIENT_DISABLES_AT: + result = "Autotrading disabled by client terminal"; + break; + + // + case TRADE_RETCODE_LOCKED: + result = "Request locked for processing"; + break; + + // + case TRADE_RETCODE_FROZEN: + result = "Order or position frozen"; + break; + + // + case TRADE_RETCODE_INVALID_FILL: + result = "Invalid order filling type"; + break; + + // + case TRADE_RETCODE_CONNECTION: + result = "No connection with the trade server"; + break; + + // + case TRADE_RETCODE_ONLY_REAL: + result = "Operation is allowed only for live accounts"; + break; + + // + case TRADE_RETCODE_LIMIT_ORDERS: + result = "The number of pending orders has reached the limit"; + break; + + // + case TRADE_RETCODE_LIMIT_VOLUME: + result = "The volume of orders and positions for the symbol has reached the limit"; + break; + + // + default: + result = "Invalid return code of the trade server"; + break; + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... + + // + bool CanLog() + { + return mLogAlerts; + } + + // + bool CanLogAlert() + { + // + bool result = GetEnableAlerts() && GetLogAlerts(); + + // + return result; + } + + // + bool CanTerminalAlert() + { + // + bool result = GetEnableAlerts() && GetTerminalAlerts(); + + // + return result; + } + + // + bool CanMailAlert() + { + // + bool result = GetEnableAlerts() && GetMailAlerts(); + + // + return result; + } + + // + bool CanPushAlert() + { + // + bool result = GetEnableAlerts() && GetPushAlerts(); + + // + return result; + } + +private: + // + // Props ... + string mPrefix; // Alerts Prefixe + bool mEnableAlerts; // Enable Alerts + bool mLogAlerts; // Log Alerts + bool mTerminalAlerts; // Terminal Alerts + bool mMailAlerts; // Mail Alerts + bool mPushAlerts; // Push Alerts + + // + // Tools ... + + // + // Clear Escape String and + // Attach Alert Prefix to Message ... + string PrepareMessage(string message) + { + // + StringReplace(message, "\n", " | "); + + // + StringConcatenate(message, GetPrefix(), " > ", message); + + // + return message; + } +}; + +// +// a Base Class by Support Alert ... +class XSCBaseAlert : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XSCBaseAlert() + { + // + // Instance Alert ... + mAlert = new XSCAlert(); + } + + // + // Deconstructors ... + void ~XSCBaseAlert() + { + // + delete mAlert; + } + + // + // Alert Handler Functions ... + + // + // Alert Functions Getter(s) / Setters(s) ... + + // + string GetAlertPrefix() + { + return mAlert.GetPrefix(); + } + + // + void SetAlertPrefix(string value) + { + mAlert.SetPrefix(value); + } + + // + bool GetAlertLogAlerts() + { + return mAlert.GetLogAlerts(); + } + + // + void SetAlertLogAlerts(bool value) + { + mAlert.SetLogAlerts(value); + } + + // + bool GetAlertEnableAlerts() + { + return mAlert.GetEnableAlerts(); + } + + // + void SetAlertEnableAlerts(bool value) + { + mAlert.SetEnableAlerts(value); + } + + // + bool GetAlertPushAlerts() + { + return mAlert.GetPushAlerts(); + } + + // + void SetAlertPushAlerts(bool value) + { + mAlert.SetPushAlerts(value); + } + + // + bool GetAlertMailAlerts() + { + return mAlert.GetMailAlerts(); + } + + // + void SetAlertMailAlerts(bool value) + { + mAlert.SetMailAlerts(value); + } + + // + bool GetAlertTerminalAlerts() + { + return mAlert.GetTerminalAlerts(); + } + + // + void SetAlertTerminalAlerts(bool value) + { + mAlert.SetTerminalAlerts(value); + } + + // + // Alert Actions ... + + // + // Logging an Alert ... + void LogAlert(string message) + { + mAlert.LogAlert(message); + } + + // + // Terminal Alert ... + void TerminalAlert(string message) + { + mAlert.TerminalAlert(message); + } + + // + // Mail Alert ... + void MailAlert(string message) + { + mAlert.MailAlert(message); + } + + // + // Send Push Notification ... + void PushAlert(string message) + { + mAlert.PushAlert(message); + } + + // + // Send an Alert by Handling all Different Specified + // type's of Alert's if they are Enabled ... + void Alert(string message) + { + mAlert.Alert(message); + } + + // + // Logs ... + + // + // Log a Message ... + void Log(string message) + { + mAlert.Log(message); + } + void Log(string tag, string message) + { + mAlert.Log(tag, message); + } + void LogEmpty() + { + mAlert.LogEmpty(); + } + + // + // Log Specific Array ... + template + void LogArray( + T &array[], // Array to Log + string label = NULL // Array Label + ) + { + mAlert.LogArray(array, label); + } + + // + // Error ... + + // + // Log an Error ... + void LogError( + int error = -1 // Specific Error, if it's equal to -1, use Last Error ... + ) + { + mAlert.LogError(error); + } + + // + // Retrieve Specified Error Code Description ... + string GetErrorDescription(int err_code) + { + return mAlert.GetErrorDescription(err_code); + } + + // + // Retrieve Specified Error Code Description ... + string GetTradeServerReturnCodeDescription(int return_code) + { + return mAlert.GetTradeServerReturnCodeDescription(return_code); + } + + // + // Protected ... +protected: + // + // Alert ... + XSCAlert *mAlert; + + // + // Private ... +private: +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xea.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xea.class.ex5 new file mode 100644 index 0000000..4051051 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xea.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xea.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xea.class.mq5 new file mode 100644 index 0000000..3b3eb94 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xea.class.mq5 @@ -0,0 +1,1779 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseEA +// Description: provides all Base EA requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xalert.class.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +// Define On Signal Event Handler Type ... +typedef void (*TOnSignal)(XSignal &signal); + +// +// Class Definition ... + +class XSCBaseEA : public XSCBaseAlert +{ + // + // Public ... +public: + // + // Props ... + + // + // Trade Class Instance ... + XSCTrade *mTrader; + + // + // Constructor ... + XSCBaseEA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + // + // Event Handlers ... + TOnSignal onSignal = NULL, // On Signal Recieved Event Handler + TOnModify onModifyPosition = NULL, // On Modify Position Event Handler + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnForceClose onForceClosePosition = NULL, // On Force Close Position Event Handler + TOnPartialClose onPartialClosePosition = NULL, // On Partial Close Position Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) + { + // + // Instance XSCTrade Class ... + mTrader = new XSCTrade( + slippage, + magicNumber // + ); + + // + mIsInTestMode = IsRunningOnTestMode(); + mStaticBalanceForCalculateDrawdown = 0; // Ignore ... + + // + // Set Event Handlers ... + mOnSignal = onSignal; + mOnModifyPosition = onModifyPosition; + mOnStopLossTriggered = onStopLossTriggered; + mOnForceClosePosition = onForceClosePosition; + mOnTakeProfitTriggered = onTakeProfitTriggered; + mOnDealsChangedHandler = onDealsChangedHandler; + mOnPartialClosePosition = onPartialClosePosition; + mOnOrdersChangedHandler = onOrdersChangedHandler; + mOnPositionsChangedHandler = onPositionsChangedHandler; + mOnTradeStateChangedHandler = onTradeStateChangedHandler; + + // + if (mOnSignal != NULL) + { + AddOnSignalEventHandler(mOnSignal); + } + + // + if (mOnModifyPosition != NULL) + { + mTrader.AddOnModifyPositionEventHandler(mOnModifyPosition); + } + + // + if (mOnForceClosePosition != NULL) + { + mTrader.AddOnForceClosePositionEventHandler(mOnForceClosePosition); + } + + // + if (mOnPartialClosePosition != NULL) + { + mTrader.AddOnPartialClosePositionEventHandler(mOnPartialClosePosition); + } + + // + if (mOnStopLossTriggered != NULL) + { + mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); + } + + // + if (mOnTakeProfitTriggered != NULL) + { + mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); + } + + // + if (mOnDealsChangedHandler != NULL) + { + mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); + } + + // + if (mOnOrdersChangedHandler != NULL) + { + mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); + } + + // + if (mOnPositionsChangedHandler != NULL) + { + mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); + } + + // + if (mOnTradeStateChangedHandler != NULL) + { + mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); + } + } + + // + // Deconstractor ... + ~XSCBaseEA() + { + // + delete mTrader; + } + + // + // Properties Getter(s) / Setter(s) ... + + // + // Retrieve Slippage ... + int GetSlippage() + { + return mTrader.GetSlippage(); + } + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mTrader.GetMagicNumber(); + } + + // + double GetDrawdownPercent() + { + // + CalculateMaxDrawdown(); + return mDrawdownPercent; + } + + // + void AddOnSignalEventHandler(TOnSignal handler) + { + // + Add( + handler, + mOnSignalEventHandlers // + ); + } + + // + double MinRequiredProfitPerTrade() + { + return mMinRequiredProfitPerTrade; + } + + // + void MinRequiredProfitPerTrade(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinRequiredProfitPerTrade = value; + } + + // + double MinRequiredProfitPerVolumeFactor() + { + return mMinRequiredProfitPerVolumeFactor; + } + + // + void MinRequiredProfitPerVolumeFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + if (value > 0 && value < 0.01) + { + value = 0.01; + } + + // + mMinRequiredProfitPerVolumeFactor = value; + } + + // + int RestingAfterHedge() + { + return mRestingAfterHedge; + } + + // + void RestingAfterHedge(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRestingAfterHedge = value; + } + + // + // Overrides ... + + // + // Customize Token ... + virtual string GetToken() + { + return GetSpecificToken(this); + } + + // + virtual string GetTag() + { + return this.GetToken(); + } + + // + // Virtual Functions ... + + // + // Handle Chart Events ... + virtual void OnChartEvent( + const int id, // event ID + const long &lparam, // long type event parameter + const double &dparam, // double type event parameter + const string &sparam // string type event parameter + ) + { + } + + // + // OnTick Handler ... + virtual void OnTick() + { + // + CalculateMaxDrawdown(); + + // + // Draw ... + Draw(); + + // + // Check Trade Events ... + OnTrade(); + + // + SyncSupports(); + + // + // First Check For Any Guard Actions ... + // then Handle Guards if Provided ... + XGuard guards[]; + bool hasGuard = CheckForGuard(guards); + if (hasGuard) + { + DoGuards(guards); + } + + // + XSignal signals[]; + + // + // Second Check for Position Management or Equity Management + // Actions like Supports or etc ... + bool isIgnored = HandleStateManagement(signals); + if (isIgnored) + { + return; + } + + // + // Check Sleeping State ... + bool isSlept = IsSlept(); + if (isSlept) + { + return; + } + + // + // Second Check For Signals ... + // then Execute Signals if Provided ... + int signalsCount = RequestForSignal(signals); + if (signalsCount <= 0) + { + return; + } + + // + // Execute Signals ... + HandleSignalsExecution(signals); + } + + // + // These are Some Event Handler ... + + // + // Calls whenever a signal Executed ... + virtual void OnSignalExecuted(const XSignal &signal) {} + + // + // Cals whenever a Signal Execution Failed ... + virtual void OnSignalExecutionFailed( + const XSignal &signal, + const ENUM_X_SIGNAL_EXECUTION_RESULT reason // + ) + { + } + + // + // Calls when a Position Modified ... + virtual void OnPositionModified( + const XPosition &position, + const string comment // + ) + { + } + + // + // Calls when a Position Closed ... + virtual void OnPositionClosed( + const XPosition &position, + const string comment // + ) + { + } + + // + // Calls when a Position Partially Closed ... + virtual void OnPositionPartialyClosed( + const XPosition &position, + const string comment // + ) + { + } + + // + // Handle StopLoss Event ... + virtual void OnStopLossTriggered(const XDeal &deal) {} + + // + // Handle TakeProfit Event ... + virtual void OnTakeProfitTriggered(const XDeal &deal) {} + + // + // Handle Deals Changed Event ... + virtual void OnDealsChangedHandler(int count) {} + + // + // Handle Order Changed Event ... + virtual void OnOrdersChangedHandler(int count) {} + + // + // Handle Position Changed Event ... + virtual void OnPositionsChangedHandler(int count) {} + + // + // Handle Trade State Changed ... + virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} + + // + // Handle On Trade ... + virtual void OnTrade() + { + // + XOnTradeHandlerState state = mTrader.HandleOnTrade(); + + // + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return; + } + + // + // STATE ... + + // + // Notfy Trade State Changed Event ... + OnTradeStateChangedHandler(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + OnDealsChangedHandler(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + mTrader.GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + OnTakeProfitTriggered(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + OnStopLossTriggered(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + OnPositionsChangedHandler(state.newPositions); + } + } + + // + // Retrieve Dept Of Market ... + virtual void OnBookEvent(const string &symbol) + { + // + // TODO: Implement this ... + } + + // + // Draw On Chart if anything is required ... + virtual void Draw() {} + + // + // Check For any Guard Actions ... + virtual bool CheckForGuard(XGuard &guards[]) + { + return false; + } + + // + // When a Guard Notified to Do Support Signal ... + // this Method Calls For Retrieve Support Signal ... + // if it's Provided, Execute it ... + virtual bool RequestForSupport( + XSignal &support, // Holds Support Signal, if Provided + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + return false; + } + + // + // Handle Position(s)/ Order(s) or EQM Supporting Action ... + // if returns true, prevent for process Tick ... + virtual bool HandleStateManagement(XSignal &signals[]) + { + return false; + } + + // + // Regulary Filtered Signals passed to this + // and here we can do Additional Signal Filtering + // for Signal Management such as (Providers and etc) ... + virtual int HandleSignalManagement(XSignal &signals[]) + { + // + int result = ArraySize(signals); + + // + return result; + } + + // + // Here we Have to Check Market based + // on our Strategy for Trading ... + // and if a Good Entry founded ... + // model it as an XSignal struct and passed it to result ... + virtual int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) + { + return 0; + } + + // + // Execute Provided Signals ... + virtual void HandleSignalsExecution(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return; + } + + // + int managedSignalsCount = HandleSignalManagement(signals); + if (managedSignalsCount <= 0) + { + return; + } + + // + // Notify Signal Event Handlers for Reciving New Signal ... + for (int i = 0; i < managedSignalsCount; i++) + { + NotifyOnSignalEventHandlers(signals[i]); + } + + // + // Try to Execute Signals ... + ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; + int executedSignalsCount = ExecuteSignals( + signals, + reasons // + ); + } + + // + // Tools ... + + // + // Calculate Max Drawdown and it's Percent ... + double CalculateMaxDrawdown() + { + // + int positionsCount = PositionsTotal(); + if (IsValidSize(positionsCount)) + { + double mEquity = mTrader.mAccount.GetEquity(); + if (mEquity > mMaxDrawdown) + { + mMaxDrawdown = mEquity; + } + + // + mDrawdownPercent = (mMaxDrawdown - mEquity) / (mStaticBalanceForCalculateDrawdown > 0 ? mStaticBalanceForCalculateDrawdown : mMaxDrawdown) * 100; + mDrawdownPercent = NormalizeDouble(mDrawdownPercent, 3); + } + else + { + // + mMaxDrawdown = 0.0; + mDrawdownPercent = 0.0; + } + + // + return mDrawdownPercent; + } + + // + // Protected ... +protected: + // + // Props ... + + // + // Check in Test Mode or not ... + bool mIsInTestMode; + + // + // Save Max Drawdown ... + double mMaxDrawdown; + double mDrawdownPercent; + double mStaticBalanceForCalculateDrawdown; + + // + + // + // Tools ... + + // + // Since we need to Calls Some Event Handlers on + // - Signal Execution; + // - Modified; + // - Closed; + // - Partial Closed; + // events ... + // we have to implement thouse Methods here and use them ... + + // + // Execute Stand alone Signal ... + bool ExecuteSignal( + XSignal &signal, // Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result + bool checkPolicies = true, // Check Account Policies + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL // order expiration time + ) + { + // + bool result = false; + + // + result = mTrader.ExecuteSignal( + signal, + state, + lifetime, + expiration, + checkPolicies // + ); + if (result) + { + // + OnSignalExecuted(signal); + + // + string message = "Signal Executed (" + ToString(signal.positionId) + ") Successfully ..."; + + // + Alert(message); + } + else + { + // + OnSignalExecutionFailed(signal, state); + + // // + // string message = "Signal Execution Failed: " + ToString(state) + " ..."; + + // // + // Alert(message); + } + + // + return result; + } + + // + // Execute a Collection of Signals ... + int ExecuteSignals( + XSignal &signals[], // Collection of Signal for Execution + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + bool checkPolicies = true, // Check Account Policies + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL // order expiration time + ) + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signalsCount)) + { + return result; + } + + // + Clean(states); + ArrayResize(states, signalsCount, X_SIGNAL_EXECUTION_UNKNOWN); + + // + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + checkPolicies, + lifetime, + expiration // + ); + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + // Modify ... + bool Modify( + ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + string comment = NULL // comment + ) + { + // + bool result = false; + + // + result = mTrader.Modify( + ticket, + sl, + tp, + comment // + ); + + // + if (result) + { + // + XPosition position; + result = mTrader.GetPosition( + ticket, + position // + ); + if (result) + { + // + OnPositionModified( + position, + comment // + ); + + // + string message = "Position " + ToString(ticket) + " Modified Successfully ..."; + + // + Alert(message); + } + } + + // + return result; + } + + // + // Close ... + bool Close( + ulong ticket, + string comment // + ) + { + // + bool result = false; + + // + XPosition position; + result = mTrader.GetPosition( + ticket, + position // + ); + + // + result = mTrader.Close( + ticket, + comment // + ); + + // + if (result) + { + // + OnPositionClosed( + position, + comment // + ); + + // + string message = "Position " + ToString(ticket) + " Closed Successfully ..."; + + // + Alert(message); + } + + // + return result; + } + + // + // Close ... + int Close( + XPosition &positions[], + string comment // + ) + { + // + int result = 0; + + // + int count = ArraySize(positions); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isClosed = Close( + positions[i].ticket, + comment // + ); + + // + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Partial Close ... + bool PartialClose( + ulong ticket, + double volume, + string comment // + ) + { + // + bool result = false; + + // + XPosition position; + result = mTrader.GetPosition( + ticket, + position // + ); + if (!result) + { + return result; + } + + // + result = mTrader.ClosePartial( + ticket, + volume, + comment // + ); + + // + if (result) + { + // + OnPositionPartialyClosed( + position, + comment // + ); + + // + string message = "Position " + ToString(ticket) + " Successfully Closed Parital ..."; + + // + Alert(message); + } + + // + return result; + } + + // + // Partial Close ... + int PartialClose( + XPosition &positions[], + double volume, + string comment // + ) + { + // + int result = 0; + + // + int count = ArraySize(positions); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + bool isClosed = PartialClose( + positions[i].ticket, + volume, + comment // + ); + + // + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + int CancelOrders() + { + // + int result = 0; + + // + XOrder supports[]; + int supportsCount = mTrader.GetOrders( + supports, + NULL, // All Symbols ... + XEQMSupportToken, // Only EQM Supports ... + NULL, // All Periods ... + X_POSITION_TYPE_ALL, // All Order Types ... + ORDER_STATE_PLACED, // Untriggered Orders ... + true // Filter by Magic ... + ); + if (!IsValidSize(supportsCount)) + { + return result; + } + + // + result = mTrader.CancelOrders( + supports // + ); + + // + return result; + } + + // + // Search Positions and Remove + // non Exists Positions Support Orders ... + void SyncSupports() + { + // + XOrder orders[]; + int ordersCount = mTrader.GetOrders( + orders, + NULL, // All Symbols ... + NULL, // All Providers ... + NULL, // All Periods ... + X_POSITION_TYPE_ALL, // All Types ... + ORDER_STATE_PLACED, // Placed Untriggered Orders ... + true // Filter by Magic ... + ); + if (!IsValidSize(ordersCount)) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions // + ); + if (!IsValidSize(positions)) + { + // + mTrader.CancelOrders(orders); + return; + } + + // + XOrder mustCancel[]; + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + // Check Order is Support or not ... + ulong iParentTicket = ExtractSupportedTicket(iOrder.comment); + if (iParentTicket <= 0) + { + continue; + } + + // + // We Sure it is support Order ... + XPosition parent; + bool isParentExists = mTrader.GetPosition( + iParentTicket, + parent // + ); + if (!isParentExists) + { + // + AddRef( + iOrder, + mustCancel // + ); + } + } + + // + int mustCancelCount = ArraySize(mustCancel); + if (!IsValidSize(mustCancelCount)) + { + return; + } + + // + mTrader.CancelOrders(mustCancel); + } + + // + // Hedging ... + + // + // Check Required Properties Setted for Hedge or not ... + bool AllowHedge() + { + // + bool result = false; + + // + result = + // + mMinRequiredProfitPerTrade > 0 && + mMinRequiredProfitPerVolumeFactor > 0 + // + ; + + // + return result; + } + + // + // Check Hedge Conditions is Happens or not ... + // if true doing Hedge ... + bool DoHedge() + { + // + bool result = false; + + // + result = AllowHedge(); + if (!result) + { + return result; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + result = positionsCount > 1; + if (!result) + { + return result; + } + + // + // Check At Least One Support Positions Open For Hedging ... + // XPosition supports[]; + // int supportsCount = ExtractSupports( + // positions, + // supports // + // ); + // result = IsValidSize(supportsCount); + // if (!result) + // { + // return result; + // } + + // + double profits = SpecifiedCalculatePositionsProfit(positions); + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + mMinRequiredProfitPerTrade, + mMinRequiredProfitPerVolumeFactor // + ); + + // + result = + positionsCount <= 5 + ? profits >= requiredProfit + : profits >= requiredProfit * 0.6; + if (!result) + { + return result; + } + + // + string comment = XEQMSupportToken + " Hedge ..."; + + // + int closed = Close( + positions, + comment // + ); + result = IsValidSize(closed); + if (!result) + { + return result; + } + + // + SyncSupports(); + + // + string message = XEQMSupportToken + " Hedge: " + ToString(profits) + " ..."; + + // + Alert(message); + + // + if (mRestingAfterHedge > 0) + { + Sleeping(mRestingAfterHedge); + } + + // + return result; + } + + // + // Signal Event Listeners ... + + // + void NotifyOnSignalEventHandlers(XSignal &signal) + { + // + int listenersCount = ArraySize(mOnSignalEventHandlers); + if (listenersCount <= 0) + { + return; + } + + // + for (int i = 0; i < listenersCount; i++) + { + // + TOnSignal iListener = mOnSignalEventHandlers[i]; + + // + iListener(signal); + } + } + + // + // Guards ... + + // + // Do All Provided Guards ... + void DoGuards(XGuard &guards[]) + { + // + int guardsCount = ArraySize(guards); + if (guardsCount <= 0) + { + return; + } + + // + for (int i = 0; i < guardsCount; i++) + { + // + XGuard iGuard = guards[i]; + + // + switch (iGuard.action) + { + // + // Hedge In Profit Specified Positions ... + case X_GUARD_ACTION_HEDGE: + HandleGuardHedgeAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Trail Stop Loss in Specified Positions ... + case X_GUARD_ACTION_TRAIL_STOP: + HandleGuardTrailingStopAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period, + iGuard.dblPayLoad); + break; + + // + // Force Close Specified Positions ... + case X_GUARD_ACTION_FORCE_CLOSE: + HandleGuardForceCloseAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Generate and Place Support Signals ... + case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: + HandleGuardAddSupportPositionAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + + // + // Delete All Placed Pending Orders ... + case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: + HandleGuardCancelPendingOrdersAction( + iGuard.provider, + iGuard.symbol, + iGuard.type, + iGuard.period); + break; + } + } + } + + // + // Close All Specified Provider's Positions in Profit Summary ... + void HandleGuardHedgeAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double minProfitForHedging = 1, // Specified Profit for Hedge + double minProfitForHedgingVolumeFactor = 0.01 // Specified Volume Factor for Hedge + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 1) + { + return; + } + + // + double profit = SpecifiedCalculatePositionsProfit(positions); + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + minProfitForHedging, + minProfitForHedgingVolumeFactor // + ); + + // + bool isReadyForHedge = profit >= requiredProfit; + if (!isReadyForHedge) + { + return; + } + + // + string comment = "Guard Hedge " + provider; + int closed = mTrader.Close( + positions, + comment + // + ); + if (closed > 0) + { + // + string message = "Guard Hedge " + provider + "'s Positions on Profit: " + ToString(profit); + + // + Alert(message); + } + } + + // + // Close Max In Profit Trade Guard Action ... + void HandleGuardCloseInProfitAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetInProfitPositions( + positions, + symbol, + provider, + period, + type, + method + // + ); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InProfit ..."; + mTrader.Close( + positions, + comment + // + ); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Postion(s) In Profit ..."; + + // + Alert(message); + } + + // + // Close Max In Drawdown Trade Guard Action ... + void HandleGuardCloseInDrawdownAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method + ) + { + // + XPosition positions[]; + int positionsCount = mTrader + .GetInDrawdownPositions( + positions, + symbol, + provider, + period, + type, + method + // + ); + if (positionsCount <= 0) + { + return; + } + + // + string comment = "Close InDrawdown ..."; + mTrader.Close( + positions, + comment + // + ); + + // + string message = "Guard Close (" + ToString(positionsCount) + ") Position(s) In Drawdown ..."; + + // + Alert(message); + } + + // + // Force Close Specified Set Of Position ... + void HandleGuardForceCloseAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + ulong ticket = 0 // Specific Ticket + ) + { + // + string comment = ""; + + // + // Close All Positions ... + if (ticket == 0) + { + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 0) + { + return; + } + + // + comment = provider + " Force Close Guard ..."; + + // + mTrader.Close( + positions, + comment + // + ); + } + // + // Close Specific Position ... + else + { + // + XPosition position; + bool hasPosition = mTrader + .GetPosition( + ticket, + position + // + ); + + // + if (hasPosition) + { + // + comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; + + // + mTrader.Close( + ticket, + comment + // + ); + } + } + + // + if (IsValid(comment)) + { + Alert(comment); + } + } + + // + // Trailing Specified Set Of Positions Stop Losses ... + void HandleGuardTrailingStopAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period, // Specified Time Frame + double sl // Desired SL Value ... + ) + { + // + if (sl <= 0) + { + return; + } + + // + NormalizePrice( + sl, + symbol + // + ); + + // + XPosition positions[]; + int positionsCount = mTrader + .GetPositions( + positions, + symbol, + provider, + period, + type + // + ); + if (positionsCount <= 0) + { + return; + } + + // + int modified = 0; + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + string comment = PrepareSLTrailTag(iPosition.comment); + + // + if (iPosition.sl == sl) + { + continue; + } + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment); + if (isModified) + { + modified++; + } + } + + // + if (modified > 0) + { + // + string message = "(" + ToString(modified) + ") Position's Stop Trailed Successfully ..."; + + // + Alert(message); + } + } + + // + // Add Support Signal for Specified Positions ... + void HandleGuardAddSupportPositionAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + XSignal support; + bool hasSupport = RequestForSupport( + support, + provider, + symbol, + type, + period + // + ); + + // + if (!hasSupport || !support.IsValid()) + { + return; + } + + // + // TODO: May be need to add Support Tag to comments ... + + // + ENUM_X_SIGNAL_EXECUTION_RESULT reason = NULL; + bool isExecuted = ExecuteSignal( + support, + reason // + ); + + // + string comment = NULL; + if (!isExecuted) + { + comment = "Support Execution Failed doue " + ToString(reason); + } + else + { + comment = "Guard Support Signal Executed Successfully ..."; + } + + // + if (IsValid(comment)) + { + Alert(comment); + } + } + + // + // Cancel all Placed Orders ... + void HandleGuardCancelPendingOrdersAction( + string provider, // Positions Provided by Specific Provider + string symbol, // Trading Symbol + ENUM_X_POSITION_TYPES type, // Trading Type + ENUM_TIMEFRAMES period // Specified Time Frame + ) + { + // + XOrder orders[]; + int ordersCount = mTrader.GetOrders( + orders, + symbol, + provider, + period, + type, + ORDER_STATE_PLACED, + true // Filter by Magic ... + // + ); + if (ordersCount <= 0) + { + return; + } + + // + int canceledOrdersCount = mTrader.CancelOrders(orders); + + // + if (canceledOrdersCount > 0) + { + // + string message = "Guard Cancel (" + ToString(canceledOrdersCount) + ") Pending Orders ..."; + + // + Alert(message); + } + } + + // + // Sleeping Context ... + + // + // Sleeping Mode ... + int mSleepingDuration; + datetime mSleepingStartAt; + bool Sleeping(int seconds = -1) + { + // + bool result = false; + + // + mSleepingDuration = + seconds > 0 + ? seconds + : mRestingAfterHedge > 0 + ? mRestingAfterHedge + : 0; + result = mSleepingDuration > 0; + if (!result) + { + // + ResetSleeping(); + return result; + } + + // + // Check Doesnt Sleep Before ... + result = mSleepingStartAt == NULL; + if (!result) + { + // + ResetSleeping(); + return result; + } + + // + datetime cTime = TimeCurrent(); + mSleepingStartAt = cTime; + + // + return result; + } + bool IsSlept() + { + // + bool result = false; + + // + result = mSleepingDuration > 0 && + mSleepingStartAt != NULL; + if (!result) + { + // + ResetSleeping(); + return result; + } + + // + datetime cTime = TimeCurrent(); + result = (int)cTime < (int)mSleepingStartAt + mSleepingDuration; + if (!result) + { + ResetSleeping(); + } + + // + return result; + } + void ResetSleeping() + { + // + mSleepingDuration = 0; + mSleepingStartAt = NULL; + } + + // + // Private ... +private: + // + // Props ... + + // + int mRestingAfterHedge; // Resting Bars After Hedge + double mMinRequiredProfitPerTrade; // Minimum Required Profit for Hedging + double mMinRequiredProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Velume + + // + // Signal Event Listeners ... + TOnSignal mOnSignalEventHandlers[]; + + // + // Event Handlers ... + TOnSignal mOnSignal; + TOnModify mOnModifyPosition; + TOnStopLoss mOnStopLossTriggered; + TOnTakeProfit mOnTakeProfitTriggered; + TOnForceClose mOnForceClosePosition; + TOnDealsChanged mOnDealsChangedHandler; + TOnPartialClose mOnPartialClosePosition; + TOnOrdersChanged mOnOrdersChangedHandler; + TOnPositionsChanged mOnPositionsChangedHandler; + TOnTradeStateChanged mOnTradeStateChangedHandler; +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xhelper.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xhelper.class.ex5 new file mode 100644 index 0000000..821c178 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xhelper.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xhelper.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xhelper.class.mq5 new file mode 100644 index 0000000..966eb8d --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xhelper.class.mq5 @@ -0,0 +1,148 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCBaseHelper +// Description: provides all Base Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Includes ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Definitions ... + +// +// a Class for Handle base requirements ... +// for indicators ... +class XSCBaseHelper : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCBaseHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading Time Frame + ) + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCBaseHelper() + { + // + IndicatorRelease(mHandler); + } + + // + // Setter(s) / Getter(s) ... + + // + // Symbol ... + string GetSymbol() + { + return mSymbol; + } + + // + // Period ... + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Retrieve Bars ... + int CountBars() + { + // + int result = + Bars( + mSymbol, + mPeriod + // + ); + + // + return result; + } + + // + // Retrieve Indicator Calculated Bars ... + int CountCalculatedBars() + { + return BarsCalculated(mHandler); + } + + // + // Generate Tag ... + virtual string GetTag() + { + // + string result = NULL; + + // + result = + // + GetToken() + + "[" + + GetSymbol() + "|" + + ToString(GetPeriod()) + + "]" + // + ; + + // + return result; + } + + // + // Functions ... + + // + // Protected ... +protected: + // + // Props ... + + // + // Symbol ... + string mSymbol; + + // + // Period ... + ENUM_TIMEFRAMES mPeriod; + + // + // Indicator Handler ... + int mHandler; + + // + // Private ... +private: + // +}; + +// +// Tools .... \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xhttp.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xhttp.class.ex5 new file mode 100644 index 0000000..0c99da7 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xhttp.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xhttp.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xhttp.class.mq5 new file mode 100644 index 0000000..82adadb --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xhttp.class.mq5 @@ -0,0 +1,373 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCHttp +// Description: provides all HTTP requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Definitions ... + +// +enum X_HTTP_METHOD +{ + X_HTTP_GET, + X_HTTP_POST +}; + +// +// Imports ... + +// +// Includes ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// a Class for Manage Account ... +class XSCHttp : public XSCBase +{ + // + // Public ... +public: + // + // Constructor ... + void XSCHttp() + { + XSCHttp("", 10000); + } + void XSCHttp( + string path, // Base Folder to Store Data + int timeout // base timeout for Requests + ) + { + // + Path(path); + Timeout(timeout); + } + + // + // Deconstructor ... + void ~XSCHttp() + { + } + + // + // Properties Getter(s) / Setter(s) ... + + // + // Path ... + void Path(string value) + { + // + mPath = value; + + // + if (!IsValid(mPath)) + { + mPath = GetTag(); + } + } + + string Path() + { + return mPath; + } + + // + // Timeout ... + void Timeout(int value) + { + mTimeout = value; + } + + // + int Timeout() + { + return mTimeout; + } + + // + // Error ... + int Error() + { + return mError; + } + + // + // Response ... + string Response() + { + return mResponse; + } + + // + // Overrides ... + string GetTag() override + { + return GetSpecificToken(this); + } + + // + // Tools ... + + // + // Send Global Request ... + int SendRequest( + X_HTTP_METHOD method, // Httm Request Method + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = -1; + + // + string strMethod = ToString(method); + if (StringLen(strMethod) == 0) + { + return result; + } + + // + // Reset State ... + ResetState(); + + // + result = WebRequest( + strMethod, + url, + headers, + timeout, + payload, + response, + responseHeaders); + + // + if (result < 0) + { + mError = GetLastError(); + } + else + { + mResponse = CharArrayToString(response); + } + + // + return result; + } + + // + // Get Request ... + int GetRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_GET, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Post Request ... + int PostRequest( + const string url, // Server Address + const string headers, // Headers providing + const char &payload[], // the Data which needs to Send + char &response[], // Response of request + string responseHeaders, // Response Headers + int timeout = 500 // Timeout for response default is 500 + ) + { + // + int result = SendRequest( + X_HTTP_POST, + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + return result; + } + + // + // Handle Download Specific URL Content to Specific Path and File Name ... + bool Download( + string url, // the URL address which going to download + string fileName // Specify Destination file name to Store Response + ) + { + // + bool result = false; + + // + string filePath = GetFilePath(fileName); + string cookie = NULL; + string referer = NULL; + int timeout = Timeout(); + + // + char payload[]; + string headers; + char response[]; + string responseHeaders; + + // + // Send Request ... + int requestResult = GetRequest( + url, + headers, + payload, + response, + responseHeaders, + timeout); + + // + // Define File Handler ... + int mFileHandler = FileOpen( + filePath, + FILE_WRITE | FILE_BIN); + if (mFileHandler == INVALID_HANDLE) + { + // + mError = GetLastError(); + return result; + } + + // + // Write Response to File ... + uint writed = FileWriteArray( + mFileHandler, + response, + 0, + ArraySize(response)); + FileFlush(mFileHandler); + FileClose(mFileHandler); + + // + result = writed > 0; + + // + return result; + } + + // + // END Provided Functions ... + // + + // + // Protected ... +protected: + // + // Destintion Folder Path ... + string mPath; + + // + // WEB Request Timeout Value ... + int mTimeout; + + // + // WEB Request's Response ... + string mResponse; + + // + // Error Value ... + int mError; + + // + // Private ... +private: + // + // Reset Errors State ... + void ResetState() + { + // + // Reset Errors ... + mError = -1; + mResponse = ""; + ResetLastError(); + } + + // + // Generate Full File Path ... + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + Path() + "\\" + fileName + // + ; + + // + return result; + } +}; + +// +// Tools ... + +// +// Convert enum to String ... +string ToString(X_HTTP_METHOD method) +{ + // + string result = ""; + + // + switch (method) + { + // + case X_HTTP_GET: + result = "GET"; + break; + + // + case X_HTTP_POST: + result = "POST"; + break; + } + + // + return result; +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xmd5.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xmd5.class.ex5 new file mode 100644 index 0000000..0cc3c1c Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xmd5.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xmd5.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xmd5.class.mq5 new file mode 100644 index 0000000..3311aa5 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xmd5.class.mq5 @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCMD5 +// Description: Provides MD5 Hashing Requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// START Definitions ... +// + +// +static uchar _md5_PADDING[64] = + { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +// +#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) +#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +// +#define _md5_FF(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_GG(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_HH(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_II(a, b, c, d, x, s, ac) \ + { \ + (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ + (a) = _md5_ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +// +#define _md5_INIT_STATE_0 0x67452301 +#define _md5_INIT_STATE_1 0xefcdab89 +#define _md5_INIT_STATE_2 0x98badcfe +#define _md5_INIT_STATE_3 0x10325476 + +// +#define _md5_S11 7 +#define _md5_S12 12 +#define _md5_S13 17 +#define _md5_S14 22 + +// +#define _md5_S21 5 +#define _md5_S22 9 +#define _md5_S23 14 +#define _md5_S24 20 + +// +#define _md5_S31 4 +#define _md5_S32 11 +#define _md5_S33 16 +#define _md5_S34 23 + +// +#define _md5_S41 6 +#define _md5_S42 10 +#define _md5_S43 15 +#define _md5_S44 21 + +// +// END Definitions ... +// + +// +// XCMD5 a library for Hashing ... +class XSCMD5 +{ + // + // Public Provides ... +public: + // + // Protected Provides ... + + // + // Constructor ... + XSCMD5(void) {} + + // + // Deconstructor ... + ~XSCMD5(void) {} + + // + // Hash Specified Char Array ... + string Hash( + uchar &mSource[], // Specify Char Array to Hash + int mLength = 0 // Specify Length of Char Array which required to hash + ) + { + // + string result = ""; + + // + int sourceCount = ArraySize(mSource); + + // + // Validate Args ... + if ( + sourceCount <= 0 || + (sourceCount > 0 && mLength > sourceCount)) + { + return result; + } + + // + // Normalize Args ... + if (mLength == 0) + { + mLength = sourceCount; + } + + // + // Init MD5 ... + MD5Init(); + + // + // Update Buffer ... + MD5Update(mSource, mLength); + + // + // Calculate Result ... + result = MD5Final(); + + // + return result; + } + + // + // Hash Specified String ... + string Hash( + string mSource // Specified String + ) + { + // + string result = ""; + + // + // Converts String to Char Array ... + uchar bytes[]; + StringToCharArray( + mSource, + bytes, + 0, + StringLen(mSource)); + + // + result = Hash( + bytes, + ArraySize(bytes)); + + // + return result; + } + +protected: + // + // Private Provides ... +private: + // + uint m_lMD5[4]; + uint m_nCount[2]; + uchar m_lpszBuffer[64]; + + // + // Convert Byte to DWord ... + void ByteToDWord(int &out[], uint &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; + } + } + + // + // Convert DWord to Byte ... + void DWordToByte(uchar &out[], int &in[], uint len) + { + // + uint i = 0; + uint j = 0; + + // + for (; j < len; i++, j += 4) + { + // + out[j] = (uchar)(in[i] & 0xff); + out[j + 1] = (uchar)((in[i] >> 8) & 0xff); + out[j + 2] = (uchar)((in[i] >> 16) & 0xff); + out[j + 3] = (uchar)((in[i] >> 24) & 0xff); + } + } + + // + // Init MD5 Array ... + void MD5Init() + { + // + ArrayInitialize(m_lpszBuffer, 64); + + // + m_nCount[0] = m_nCount[1] = 0; + m_lMD5[0] = _md5_INIT_STATE_0; + m_lMD5[1] = _md5_INIT_STATE_1; + m_lMD5[2] = _md5_INIT_STATE_2; + m_lMD5[3] = _md5_INIT_STATE_3; + } + + // + // Update MD5 ... + void MD5Update(uchar &inBuf[], uint inLen) + { + // + int i, ii; + int mdi; + + // + uint in[16]; + int i0 = 0; + + // + mdi = (int)((m_nCount[0] >> 3) & 0x3F); + + // + if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) + { + m_nCount[1]++; + } + + // + m_nCount[0] += ((uint)inLen << 3); + m_nCount[1] += ((uint)inLen >> 29); + + // + while ((inLen--) > 0) + { + // + m_lpszBuffer[mdi++] = inBuf[i0++]; + if (mdi == 0x40) + { + // + for (i = 0, ii = 0; i < 16; i++, ii += 4) + { + in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); + } + + // + Transform(m_lMD5, in); + + // + mdi = 0; + } + } + } + + // + // Finalize an MD5 Expression ... + string MD5Final() + { + // + uchar bits[8]; + int nIndex; + uint nPadLen; + const int nMD5Size = 16; + uchar lpszMD5[16]; + string temp; + string out = ""; + int i; + + // + DWordToByte(bits, m_nCount, 8); + nIndex = (int)((m_nCount[0] >> 3) & 0x3f); + nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + MD5Update(_md5_PADDING, nPadLen); + MD5Update(bits, 8); + DWordToByte(lpszMD5, m_lMD5, nMD5Size); + + // + for (i = 0; i < nMD5Size; i++) + { + // + if (lpszMD5[i] == 0) + { + temp = "00"; + } + else if (lpszMD5[i] <= 15) + { + temp = StringFormat("0%x", lpszMD5[i]); + } + else + { + temp = StringFormat("%x", lpszMD5[i]); + } + + // + out += temp; + } + + // + lpszMD5[0] = '\0'; + + // + return (out); + } + + // + // Transform Buffers ... + void Transform(uint &buf[], uint &in[]) + { + // + uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + // + _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); + _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); + _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); + _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); + _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); + _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); + _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); + _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); + _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); + _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); + _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); + _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); + _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); + _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); + _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); + _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); + + // + _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); + _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); + _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); + _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); + _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); + _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); + _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); + _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); + _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); + _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); + _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); + _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); + _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); + _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); + _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); + _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); + + // + _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); + _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); + _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); + _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); + _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); + _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); + _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); + _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); + _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); + _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); + _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); + _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); + _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); + _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); + _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); + _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); + + // + _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); + _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); + _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); + _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); + _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); + _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); + _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); + _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); + _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); + _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); + _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); + _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); + _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); + _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); + _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); + _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); + + // + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + } +}; diff --git a/BKPS/14030412/Classes/x-saherelm.xrange.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xrange.class.ex5 new file mode 100644 index 0000000..760aa3f Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xrange.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xrange.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xrange.class.mq5 new file mode 100644 index 0000000..0fedb42 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xrange.class.mq5 @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCRange +// Description: provides all Range requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Definitions ... + +// +enum ENUM_XSCRANGE_CALCULATION_MODE { + // + XSCRANGE_CALCULATE_MANUALLY = 0, + XSCRANGE_CALCULATE_DAILY = 1, + XSCRANGE_CALCULATE_HALFDAY = 2, + XSCRANGE_CALCULATE_4H = 3, +}; + +// +struct XSCRangeInput +{ + // + // Props ... + + // + datetime startTime; // Range Start Time + datetime endTime; // Range End Time + + // + int lifetime; // Range Live Time (Secconds) + + // + +}; \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xsccf.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xsccf.class.ex5 new file mode 100644 index 0000000..0e72fbb Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xsccf.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xsccf.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xsccf.class.mq5 new file mode 100644 index 0000000..2e5d55c --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xsccf.class.mq5 @@ -0,0 +1,736 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCRange +// Description: provides all Range requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Definitions ... + +// +struct XSCCFInput +{ + // + // Props ... + + // + int length; // Minimum of Same Bars + + // + color clrUpper; // Upper Color ... + color clrLower; // Lower Color ... + + // + // Constructor ... + void XSCCFInput() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + length = 0; + + // + clrUpper = CLR_NONE; + clrLower = CLR_NONE; + } + + // + // Defualt Configs ... + void Default() + { + // + length = 4; + + // + clrLower = clrAqua; + clrUpper = clrMagenta; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 2 + // + ; + + // + return result; + } +}; + +// +// Class ... + +class XSCCF : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCCF( + string symbol, + ENUM_TIMEFRAMES period // + ) : XSCBase() + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCCF() {} + + // + // Initialize ... + bool Init(XSCCFInput &inputs) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + // Find Bullish Bar ... + result = FindBullishBar(0); + if (!result) + { + return result; + } + + // + // Find Bearish Bar ... + result = FindBearishBar(0); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + string GetSymbol() + { + return mSymbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + XSCCFInput GetInputs() + { + return mInputs; + } + + // + bool SetInputs(XSCCFInput &inputs) + { + return Init(inputs); + } + + // + XOHCL GetBullishBar() + { + return bullishBar; + } + + // + XOHCL GetBearishBar() + { + return bearishBar; + } + + // + // Overrides ... + string GetTag() override + { + return "XCF"; + } + + // + // Tools ... + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + bullishBar.IsValid() && + bearishBar.IsValid() + // + ; + + // + return result; + } + + // + // Retrieve Title Prefix ... + string GetIdentifier() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetTag() + "_" + + mSymbol + "_" + + ToString(mPeriod) + "_" + + ToFormatString(bullishBar.time) + "_"; + + // + return result; + } + + // + // Remove Draws ... + bool Remove( + long chartId = 0, + int subWindow = 0 // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + string prefix = GetIdentifier(); + result = IsSpecifiedValid(prefix); + if (!result) + { + return result; + } + + // + RemoveDraws( + prefix, + chartId, + subWindow // + ); + + // + return result; + } + + // + bool Draw( + long chartId = 0, + string prefix = NULL, + int subWindow = 0, + string upperPrefix = "Upper", + string lowerPrefix = "Lower" // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + result = DrawBullishBar( + chartId, + prefix, + subWindow, + upperPrefix, + lowerPrefix // + ); + if (!result) + { + return result; + } + + // + result = DrawBearishBar( + chartId, + prefix, + subWindow, + upperPrefix, + lowerPrefix // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + bool FindBullishBar( + int barIndex // + ) + { + // + bool result = false; + + // + int next = barIndex + 1; + + // + int totalBars = iBars( + mSymbol, + mPeriod // + ); + result = barIndex >= 0 && barIndex + 1 + mInputs.length < totalBars; + if (!result) + { + return result; + } + + // + bool isNextValid = next >= 0 && next + 1 + mInputs.length < totalBars; + + // + int bullBarIndex = barIndex + 1; + int start = bullBarIndex + 1; + int end = start + mInputs.length; + + // + XOHCL startBar; + result = startBar.Init( + mSymbol, + mPeriod, + bullBarIndex // + ); + if (!result) + { + return result; + } + + // + result = startBar.IsBullish(); + if (!result) + { + if (isNextValid) + { + return FindBullishBar(next); + } + else + { + return result; + } + } + + // + // Loop Back to Find Bearish Bars ... + for (int i = start; i < end; i++) + { + // + XOHCL iBar; + result = iBar.Init( + mSymbol, + mPeriod, + i // + ); + if (!result || !iBar.IsBearish()) + { + // + if (isNextValid) + { + return FindBullishBar(next); + } + else + { + return result; + } + + // + break; + } + } + + // + if (result) + { + bullishBar = startBar; + } + + // + return result; + } + + // + bool FindBearishBar( + int barIndex // + ) + { + // + bool result = false; + + // + int next = barIndex + 1; + + // + int totalBars = iBars( + mSymbol, + mPeriod // + ); + result = barIndex >= 0 && barIndex + 1 + mInputs.length < totalBars; + if (!result) + { + return result; + } + + // + bool isNextValid = next >= 0 && next + 1 + mInputs.length < totalBars; + + // + int bearBarIndex = barIndex + 1; + int start = bearBarIndex + 1; + int end = start + mInputs.length; + + // + XOHCL startBar; + result = startBar.Init( + mSymbol, + mPeriod, + bearBarIndex // + ); + if (!result) + { + return result; + } + + // + result = startBar.IsBearish(); + if (!result) + { + if (isNextValid) + { + return FindBearishBar(next); + } + else + { + return result; + } + } + + // + // Loop Back to Find Bearish Bars ... + for (int i = start; i < end; i++) + { + // + XOHCL iBar; + result = iBar.Init( + mSymbol, + mPeriod, + i // + ); + if (!result || !iBar.IsBullish()) + { + // + if (isNextValid) + { + return FindBearishBar(next); + } + else + { + return result; + } + + // + break; + } + } + + // + if (result) + { + bearishBar = startBar; + } + + // + return result; + } + + // + bool DrawBullishBar( + long chartId = 0, + string prefix = NULL, + int subWindow = 0, + string upperPrefix = "Upper", + string lowerPrefix = "Lower" // + ) + { + // + bool result = false; + + // + result = bullishBar.IsValid(); + if (!result) + { + return result; + } + + // + if (!IsSpecifiedValid(upperPrefix)) + { + upperPrefix = "High"; + } + + // + if (!IsSpecifiedValid(lowerPrefix)) + { + lowerPrefix = "Low"; + } + + // + datetime cTime = TimeCurrent(); + + // + string identifier = GetIdentifier(); + + // + // High Line ... + string bullishHighLineName = + (IsSpecifiedValid(prefix) + ? prefix + "_" + : "") + + identifier + "_" + + "BULL_" + + upperPrefix; + + // + result = DrawTrendLine( + chartId, + bullishHighLineName, + subWindow, + bullishBar.time, + bullishBar.high, + cTime, + bullishBar.high, + mInputs.clrUpper, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + + // + // Low Line ... + string bullishLowLineName = + (IsSpecifiedValid(prefix) + ? prefix + "_" + : "") + + identifier + "_" + + "BULL_" + + lowerPrefix; + + // + result = DrawTrendLine( + chartId, + bullishLowLineName, + subWindow, + bullishBar.time, + bullishBar.low, + cTime, + bullishBar.low, + mInputs.clrLower, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + + // + return result; + } + + // + bool DrawBearishBar( + long chartId = 0, + string prefix = NULL, + int subWindow = 0, + string upperPrefix = "Upper", + string lowerPrefix = "Lower" // + ) + { + // + bool result = false; + + // + result = bearishBar.IsValid(); + if (!result) + { + return result; + } + + // + if (!IsSpecifiedValid(upperPrefix)) + { + upperPrefix = "High"; + } + + // + if (!IsSpecifiedValid(lowerPrefix)) + { + lowerPrefix = "Low"; + } + + // + datetime cTime = TimeCurrent(); + + // + string identifier = GetIdentifier(); + + // + // High Line ... + string bearishHighLineName = + (IsSpecifiedValid(prefix) + ? prefix + "_" + : "") + + identifier + "_" + + "BEAR_" + + upperPrefix; + + // + result = DrawTrendLine( + chartId, + bearishHighLineName, + subWindow, + bearishBar.time, + bearishBar.high, + cTime, + bearishBar.high, + mInputs.clrUpper, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + + // + // Low Line ... + string bearishLowLineName = + (IsSpecifiedValid(prefix) + ? prefix + "_" + : "") + + identifier + "_" + + "BEAR_" + + lowerPrefix; + + // + result = DrawTrendLine( + chartId, + bearishLowLineName, + subWindow, + bearishBar.time, + bearishBar.low, + cTime, + bearishBar.low, + mInputs.clrLower, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + string mSymbol; // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod; // Trading Period ... + + // + XOHCL bearishBar; // Bearish Order Block Bar + XOHCL bullishBar; // Bullish Order Block Bar + + // + XSCCFInput mInputs; // Configs ... +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xscsupres.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xscsupres.class.ex5 new file mode 100644 index 0000000..a2bdacf Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xscsupres.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xscsupres.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xscsupres.class.mq5 new file mode 100644 index 0000000..e5dda43 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xscsupres.class.mq5 @@ -0,0 +1,330 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCSupRes +// Description: provides all Support and Resistances requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Helpers/x-saherelm.xpv.helper.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// Definitions ... +struct XSCSupResInput +{ + // + // Props ... + + // + int numberOfSupports; // Number of Required Supports + int numberOfResistances; // Number of Required Resistances + + // + int pivotsVerifications; // Pivots Verifications + + // + double distance; // Distance between Pivots + + // + double price; // Price for Support and Resistance Finding + + // + color clrSupport; + color clrResistance; + + // + // Constructor ... + void XSCSupResInput() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + numberOfSupports = 0; + numberOfResistances = 0; + + // + price = 0; + distance = 0; + pivotsVerifications = 0; + + // + clrSupport = CLR_NONE; + clrResistance = CLR_NONE; + } + + // + // Defualt Configs ... + void Default() + { + // + numberOfSupports = 5; + numberOfResistances = 5; + + // + price = 0; + distance = 10; + pivotsVerifications = 35; + + // + clrSupport = clrAqua; + clrResistance = clrMagenta; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + price > 0 && + distance >= 0 && + numberOfSupports > 0 && + numberOfResistances > 0 && + pivotsVerifications > 2 + // + ; + + // + return result; + } +}; + +// +// Class ... + +// +class XSCSupRes : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCSupRes( + string symbol, + ENUM_TIMEFRAMES period // + ) : XSCBase() + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCSupRes() {} + + // + // Initializer ... + bool Init(XSCSupResInput &inputs) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + // Find Pivots ... + result = FindPivots(); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + string GetSymbol() + { + return mSymbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + XSCSupResInput GetInputs() + { + return mInputs; + } + + // + bool SetInputs(XSCSupResInput &inputs) + { + return Init(inputs); + } + + // + // Overrides ... + + // + string GetTag() override + { + return "XSupRes"; + } + + // + // Tools ... + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + false + // + ; + + // + return result; + } + + // + // Retrieve Title Prefix ... + string GetIdentifier() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetTag() + "_" + + mSymbol + "_" + + ToString(mPeriod) + "_"; + + // + return result; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Private ... +private: + // + // Props ... + + // + string mSymbol; // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod; // Trading Period ... + + // + XSCSupResInput mInputs; // Configs ... + + // + double mSupports[]; + double mResistances[]; + + // + // Tools ... + + // + bool FindPivots(int barIndex = 0) + { + // + bool result = false; + + // + int totalBars = iBars( + mSymbol, + mPeriod // + ); + + // + result = barIndex >= 0 && barIndex < totalBars - mInputs.pivotsVerifications; + if (!result) { + return result; + } + + // + int next = barIndex + 1; + bool canNext = next >= 0 && next < totalBars - mInputs.pivotsVerifications; + + // + XSCXPVHelper helper = new XSCXPVHelper(); + XPVInputs pvInputs; + pvInputs.Default(); + result = helper.Init( + mSymbol, + mPeriod, + pvInputs // + ); + if (!result) + { + return result; + } + + // + // TODO: Complete this ... + + // + // Check States ... + + // + return result; + } +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xsctrend.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xsctrend.class.ex5 new file mode 100644 index 0000000..7575573 Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xsctrend.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xsctrend.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xsctrend.class.mq5 new file mode 100644 index 0000000..9b2e096 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xsctrend.class.mq5 @@ -0,0 +1,746 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCTrend +// Description: provides all Trend requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" + +// +// All Required Inputs ... +struct XSCTrendInput +{ + // + int numberOfShoulders; // Number of Shoulders + + // + color clrUpper; // Upper Colors + color clrLower; // Lower Colors + color clrHighs; // Highs Colors + color clrLows; // Lows Colors + + // + // Constructor ... + void XSCTrendInput() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + numberOfShoulders = 0; + + // + clrUpper = CLR_NONE; + clrLower = CLR_NONE; + clrHighs = CLR_NONE; + clrLows = CLR_NONE; + } + + // + // Defualt Configs ... + void Default() + { + // + numberOfShoulders = 7; + + // + clrUpper = clrRed; + clrLower = clrGreen; + + // + clrHighs = clrAqua; + clrLows = clrMagenta; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + numberOfShoulders >= 2 + // + ; + + // + return result; + } +}; + +// +// Class Definitions ... +class XSCTrend : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor ... + void XSCTrend( + string symbol, + ENUM_TIMEFRAMES period // + ) : XSCBase() + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCTrend() + { + Remove(); + } + + // + // Initialize ... + bool Init(XSCTrendInput &inputs) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + result = zBar.Init( + mSymbol, + mPeriod, + 0 // + ); + + // + int firstSwingLowIndex = FindSwing( + zBar.symbol, + zBar.period, + X_SWING_LOW, + mInputs.numberOfShoulders, + zBar.Index() + 1 // + ); + result = firstSwingLowBar.Init( + zBar.symbol, + zBar.period, + firstSwingLowIndex // + ); + if (!result) + { + return result; + } + + // + int secondSwingLowIndex = FindSwing( + zBar.symbol, + zBar.period, + X_SWING_LOW, + mInputs.numberOfShoulders, + firstSwingLowIndex + 1 // + ); + + // + result = secondSwingLowBar.Init( + zBar.symbol, + zBar.period, + secondSwingLowIndex // + ); + if (!result) + { + return result; + } + + // + int firstSwingHighIndex = FindSwing( + zBar.symbol, + zBar.period, + X_SWING_HIGH, + mInputs.numberOfShoulders, + zBar.Index() + 1 // + ); + result = firstSwingHighBar.Init( + zBar.symbol, + zBar.period, + firstSwingHighIndex // + ); + if (!result) + { + return result; + } + + // + int secondSwingHighIndex = FindSwing( + zBar.symbol, + zBar.period, + X_SWING_HIGH, + mInputs.numberOfShoulders, + firstSwingHighIndex + 1 // + ); + result = secondSwingHighBar.Init( + zBar.symbol, + zBar.period, + secondSwingHighIndex // + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + string GetSymbol() + { + return mSymbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + XSCTrendInput GetInputs() + { + return mInputs; + } + + // + bool SetInputs(XSCTrendInput &inputs) + { + return Init(inputs); + } + + // + XOHCL GetBar() + { + return zBar; + } + + // + XOHCL GetFirstSwingLowBar() + { + return firstSwingLowBar; + } + + // + XOHCL GetSecondSwingLowBar() + { + return secondSwingLowBar; + } + + // + XOHCL GetFirstSwingHighBar() + { + return firstSwingHighBar; + } + + // + XOHCL GetSecondSwingHighBar() + { + return secondSwingHighBar; + } + + // + // Overrides ... + + // + string GetTag() override + { + return "XTREND"; + } + + // + // Tools ... + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + zBar.IsValid() && + firstSwingLowBar.IsValid() && + secondSwingLowBar.IsValid() && + firstSwingHighBar.IsValid() && + secondSwingHighBar.IsValid() + // + ; + + // + return result; + } + + // + // Retrieve Title Prefix ... + string GetIdentifier() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetTag() + "_" + + mSymbol + "_" + + ToString(mPeriod) + "_" + + ToFormatString(zBar.time); + + // + return result; + } + + // + // Retrieve Chart Line Values ... + + // + // Get Lows Line Price at Specific Time ... + double GetLows(datetime time = NULL) + { + // + double result = 0; + + // + result = GetObjectPrice( + lowsName, + time // + ); + + // + return result; + } + + // + // Get Highs Line Price at Specific Time ... + double GetHighs(datetime time = NULL) + { + // + double result = 0; + + // + result = GetObjectPrice( + highsName, + time // + ); + + // + return result; + } + + // + // Get Support Line Price at Specific Time ... + double GetSupport(datetime time = NULL) + { + // + double result = 0; + + // + result = GetObjectPrice( + supportName, + time // + ); + + // + return result; + } + + // + // Get Resistance Line Price at Specific Time ... + double GetResistance(datetime time = NULL) + { + // + double result = 0; + + // + result = GetObjectPrice( + resistanceName, + time // + ); + + // + return result; + } + + // + // Remove Draws ... + bool Remove( + long chartId = 0, + int subWindow = 0 // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + string prefix = GetIdentifier(); + result = IsSpecifiedValid(prefix); + if (!result) + { + return result; + } + + // + RemoveDraws( + prefix, + chartId, + subWindow // + ); + + // + return result; + } + + // + // Draw Trend Object on Chart ... + bool Draw( + long chartId = 0, + string prefix = NULL, + int subWindow = 0, + string upperPrefix = "Upper", + string lowerPrefix = "Lower", + string highsPrefix = "Highs", + string lowsPrefix = "Lows" // + ) + { + // + bool result = false; + + // + result = IsValid(); + if (!result) + { + return result; + } + + // + // Normalize Prefixes ... + + // + if (!IsSpecifiedValid(upperPrefix)) + { + upperPrefix = "Upper"; + } + + // + if (!IsSpecifiedValid(lowerPrefix)) + { + lowerPrefix = "Lower"; + } + + // + if (!IsSpecifiedValid(highsPrefix)) + { + highsPrefix = "Highs"; + } + + // + if (!IsSpecifiedValid(lowsPrefix)) + { + lowsPrefix = "Lows"; + } + + // + string identifier = GetIdentifier(); + result = IsSpecifiedValid(identifier); + if (!result) + { + return result; + } + + // + double support = secondSwingLowBar.low; + datetime supportTime = + secondSwingLowBar.time > secondSwingHighBar.time + ? secondSwingHighBar.time + : secondSwingLowBar.time; + supportName = + // + identifier + + (IsSpecifiedValid(prefix) + ? "_" + prefix + "_" + : "") + + "_" + lowerPrefix + "_" + + "" + // + ; + + // + double resistance = secondSwingHighBar.high; + datetime resistanceTime = + secondSwingLowBar.time > secondSwingHighBar.time + ? secondSwingHighBar.time + : secondSwingLowBar.time; + resistanceName = + // + identifier + + (IsSpecifiedValid(prefix) + ? "_" + prefix + "_" + : "") + + "_" + upperPrefix + "_" + + "" + // + ; + + // + double newLow = firstSwingLowBar.low; + datetime newLowTime = firstSwingLowBar.time; + + // + double oldLow = secondSwingLowBar.low; + datetime oldLowTime = secondSwingLowBar.time; + lowsName = + // + identifier + + (IsSpecifiedValid(prefix) + ? "_" + prefix + "_" + : "") + + "_" + lowsPrefix + "_" + + "" + // + ; + + // + double newHigh = firstSwingHighBar.high; + datetime newHighTime = firstSwingHighBar.time; + + // + double oldHigh = secondSwingHighBar.high; + datetime oldHighTime = secondSwingHighBar.time; + highsName = + // + identifier + + (IsSpecifiedValid(prefix) + ? "_" + prefix + "_" + : "") + + "_" + highsPrefix + "_" + + "" + // + ; + + // + // Draw Support ... + result = DrawTrendLine( + chartId, + supportName, + subWindow, + supportTime, + support, + newLowTime, + support, + mInputs.clrLower, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + if (!result) + { + return result; + } + + // + // Draw Resistance ... + result = DrawTrendLine( + chartId, + resistanceName, + subWindow, + resistanceTime, + resistance, + newHighTime, + resistance, + mInputs.clrUpper, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + if (!result) + { + return result; + } + + // + // Draw Highs ... + result = DrawTrendLine( + chartId, + highsName, + subWindow, + oldHighTime, + oldHigh, + newHighTime, + newHigh, + mInputs.clrHighs, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + if (!result) + { + return result; + } + + // + // Draw Lows ... + result = DrawTrendLine( + chartId, + lowsName, + subWindow, + oldLowTime, + oldLow, + newLowTime, + newLow, + mInputs.clrLows, + STYLE_SOLID, + 2, + false, + false, + true // Ray Right ... + ); + if (!result) + { + return result; + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Tools ... + + // + double GetObjectPrice( + string objName, + datetime objTime, + long chartId = 0, + int subWindow = 0 // + ) + { + // + double result = 0; + + // + if (!IsValid()) + { + return result; + } + + // + if (!IsSpecifiedValid(objName)) + { + return result; + } + + // + objTime = NormalizeTime(objTime); + + // + string objectName = FindObjectName( + objName, + chartId, + subWindow // + ); + + // + result = ObjectGetValueByTime( + chartId, + objectName, + objTime // + ); + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + string mSymbol; // Trading Symbol ... + ENUM_TIMEFRAMES mPeriod; // Trading Period ... + + // + XSCTrendInput mInputs; // Configs ... + + // + XOHCL zBar; + XOHCL firstSwingLowBar; + XOHCL secondSwingLowBar; + XOHCL firstSwingHighBar; + XOHCL secondSwingHighBar; + + // + // Object Names ... + string lowsName; + string highsName; + string supportName; + string resistanceName; +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xsczone.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xsczone.class.ex5 new file mode 100644 index 0000000..fcf227d Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xsczone.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xsczone.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xsczone.class.mq5 new file mode 100644 index 0000000..a6421c4 --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xsczone.class.mq5 @@ -0,0 +1,805 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCZone +// Description: provides all Zone requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include +#include +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include + +// +// Definitions ... +#define defZoneBGColor CLR_NONE // clrLightGray +#define defZoneLBLColor clrWhite + +// +// All Required Inputs ... +struct XSCZonesInput +{ + // + int length; // Calculation Length + int numberOfZones; // Number of Zones + + // + double levels[]; // Levels Percentage + color colors[]; // level Colors + + // + // Constructor ... + void XSCZonesInput() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + length = 0; + numberOfZones = 0; + + // + Clean(levels); + Clean(colors); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length >= 5 && + numberOfZones >= 2 + // + ; + + // + return result; + } + + // + // Add Specified Level/Color ... + void AddLevelColor( + double level, + color clr // + ) + { + // + Add( + level, + levels); + + // + Add( + clr, + colors // + ); + } + + // + // Retrieve Sort Indexed Levels Color ... + void RetrieveSortedLevels( + double &_levels[], + color &_colors[] // + ) + { + // + Clean(_levels); + Clean(_colors); + + // + int levelsCount = ArraySize(levels); + int colorsCount = ArraySize(colors); + + // + bool hasChild = IsValidSize(levelsCount) && + IsValidSize(colorsCount); + if (!hasChild) + { + return; + } + + // + // Create Temp Levels ... + double tmpLevels[]; + Copy( + levels, + tmpLevels // + ); + ArraySort(tmpLevels); + ArrayReverse(tmpLevels); + + // + // Size of Looping ... + int minSize = MathMin(levelsCount, colorsCount); + + // + for (int i = 0; i < minSize; i++) + { + // + double iLevel = tmpLevels[i]; + + // + int iLevelIDX = FindIndex( + iLevel, + levels // + ); + if (!IsValidIndex(iLevelIDX)) + { + continue; + } + + // + Add( + levels[iLevelIDX], + _levels // + ); + + // + Add( + colors[iLevelIDX], + _colors // + ); + } + } +}; + +// +// Class ... + +// +// Specific Zone ... +class XSCZone : public CObject +{ + // + // Public ... +public: + // + // Props ... + double high; + double low; + int ticks; + double percent; + + // + // Compare Two Zone With Each Other ... + virtual int Compare( + const CObject *node, + const int mode = 0 // + ) const + { + // + const XSCZone *other = (XSCZone *)node; + + // + return other.ticks - ticks; + } + + // + // Create Object ... + + // + // Protected ... +protected: + // + // Private ... +private: +}; + +// +// Zones ... + +// +class XSCZones : public XSCBase +{ + // + // Public ... +public: + // + // Constructor(s) ... + void XSCZones( + string symbol, + ENUM_TIMEFRAMES period // + ) : XSCBase() + { + // + this.mSymbol = symbol; + this.mPeriod = period; + } + + // + void ~XSCZones() + { + // + mZones.Clear(); + mChartObjects.Clear(); + } + + // + // Initialize Zones by Providing required + // Input Variables ... + bool Init( + XSCZonesInput &inputs // Inputs ... + ) + { + // + bool result = false; + + // + // Validate Inputs ... + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + // Set Inputs ... + mInputs = inputs; + + // + // Do Calculatins ... + Calculate(); + + // + return result; + } + + // + XSCZonesInput GetInputs() + { + return mInputs; + } + + // + bool SetInputs(XSCZonesInput &inputs) + { + return Init(inputs); + } + + // + // Overrides ... + + // + string GetTag() override + { + return "XZONE"; + } + + // + // Retrieve Title Prefix ... + string GetIdentifier() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = GetTag() + "_" + + mSymbol + "_" + + ToString(mPeriod) + + ToFormatString(mStartTime) + "_" + + ToFormatString(mEndTime); + + // + return result; + } + + // + bool IsValid() + { + // + bool result = false; + + // + result = + // + mZones.Total() > 0 + // + ; + + // + return result; + } + + // + // Add Specified Level/Color ... + void AddLevelColor( + double level, + color clr // + ) + { + // + mInputs.AddLevelColor( + level, + clr // + ); + } + + // + void Calculate() + { + // + // Prevent Double Calculating ... + int bars = iBars( + mSymbol, + mPeriod // + ); + if (mCalculatedBars == bars) + { + return; + } + + // + mCalculatedBars = bars; + + // + // Calculate Start and End Time ... + + // + mStartTime = iTime( + mSymbol, + mPeriod, + mInputs.length + 1 // + ); + + // + mEndTime = iTime( + mSymbol, + mPeriod, + 0 // + ); + + // + // Retrieve Ticks between Times ... + Clean(mTicks); + CopyTicksRange( + mSymbol, + mTicks, + COPY_TICKS_ALL, + mStartTime * 1000, + mEndTime * 1000 // + ); + + // + // Retrieve Highs ... + Clean(mHighs); + CopyHigh( + mSymbol, + mPeriod, + mStartTime, + mEndTime, + mHighs // + ); + + // + // Find Highest Value in Range ... + int highIDX = ArrayMaximum(mHighs); + mRangeHigh = mHighs[highIDX]; + + // + // Retrieve Lows ... + Clean(mLows); + CopyLow( + mSymbol, + mPeriod, + mStartTime, + mEndTime, + mLows // + ); + + // + // Find Lowest Value in Range ... + int lowIDX = ArrayMinimum(mLows); + mRangeLow = mLows[lowIDX]; + + // + datetime mTimes[]; + CopyTime( + mSymbol, + mPeriod, + mStartTime, + mEndTime, + mTimes // + ); + mRangeHighTime = mTimes[highIDX]; + mRangeLowTime = mTimes[lowIDX]; + + // + double mRangeSize = GetRange(); + + // + // Prepare Zones Array ... + mZones.Clear(); + + // + // Create Zones ... + for (int i = 0; i < mInputs.numberOfZones; i++) + { + // + // Instance a New Zone ... + XSCZone *iZone = new XSCZone(); + + // + // Calculate Each Zones High / Low based on Range ... + double iH = mRangeHigh - mRangeSize * i / mInputs.numberOfZones; + double iL = mRangeHigh - mRangeSize * (i + 1) / mInputs.numberOfZones; + + // + // Set Zone High Low Properties ... + iZone.low = iL; + iZone.high = iH; + + // + // Add Zone to Zone Array Objects ... + mZones.Add(iZone); + } + + // + // Calculate Each Zone Ticks ... + int mTicksCount = CountTicks(); + for (int i = 0; i < mTicksCount; i++) + { + // + // Retrieve i Index Tick Object ... + MqlTick iTick = mTicks[i]; + + // + // Loop Through Zones ... + for (int j = 0; j < mZones.Total(); j++) + { + // + // Retrieve j Index Zone Object ... + XSCZone *jZone = mZones.At(j); + + // + bool isInRange = IsTickInZoneRange( + iTick, + jZone // + ); + if (isInRange) + { + // + jZone.ticks++; + break; + } + } + } + + // + // Calculating Zone Percents ... + for (int i = 0; i < mZones.Total(); i++) + { + // + XSCZone *iZone = mZones.At(i); + + // + double percent = CalculateZoneTickPercent(iZone); + iZone.percent = percent; + } + + // + mZones.Sort(); + } + + // + int CountZones() + { + return mZones.Total(); + } + + // + XSCZone *GetZone(int index) + { + return mZones.At(index); + } + + // + double CalculateZoneTickPercent( + XSCZone *zone, + int normalizationDigits = 2 // + ) + { + // + double result = 0; + + // + if (normalizationDigits < 2 || normalizationDigits > 5) + { + normalizationDigits = 2; + } + + // + int ticksCount = CountTicks(); + if (ticksCount <= 0) + { + return result; + } + + // + result = (double)zone.ticks / ticksCount * 100; + result = NormalizeDouble(result, normalizationDigits); + + // + return result; + } + + // + bool Draw( + long chartId = 0, + string prefix = "XSCZone", + int subWindow = 0, + bool redraw = false // + ) + { + // + bool result = false; + + // + if (redraw) + { + mChartObjects.Clear(); + } + + // + if (StringLen(prefix) <= 0) + { + prefix = "XSCZone"; + } + + // + int zonesCount = mZones.Total(); + result = IsValidSize(zonesCount); + if (!result) + { + return result; + } + + // + mZones.Sort(); + + // + int ticksCount = CountTicks(); + result = IsValidSize(ticksCount); + if (!result) + { + return result; + } + + // + double levels[]; + color colors[]; + mInputs.RetrieveSortedLevels( + levels, + colors // + ); + int levelsCount = ArraySize(levels); + int colorsCount = ArraySize(colors); + bool canSetLevels = IsValidSize(levelsCount) && + IsValidSize(colorsCount) && + levelsCount == colorsCount; + + // + // Loop Through Zones ... + for (int i = 0; i < zonesCount; i++) + { + // + XSCZone *iZone = mZones.At(i); + + // + // Generate Chart Object Names ... + string iRectName = prefix + ToString(i); + string iLabelName = iRectName + "_lbl"; + + // + // Creating Rectangles ... + CChartObjectRectangle *iRect = new CChartObjectRectangle(); + result = iRect.Create( + chartId, + iRectName, + subWindow, + mStartTime, + iZone.high, + mEndTime, + iZone.low // + ); + if (!result) + { + break; + } + + // + // Set Default Rectangle Color ... + // iRect.Color(defZoneBGColor); + iRect.Fill(true); + + // + // Create Label ... + CChartObjectLabel *iLabel = new CChartObjectLabel(); + result = iLabel.Create( + chartId, + iLabelName, + subWindow, + mStartTime, + iZone.high // + ); + if (!result) + { + break; + } + + // + iLabel.Color(defZoneLBLColor); + + // + iLabel.Description(ToString(iZone.percent) + "%"); + + // + // Set Levels and Colors if Provided ... + if (canSetLevels) + { + // + color iRectColor = defZoneBGColor; + for (int z = 0; z < levelsCount; z++) + { + // + double zLevel = levels[z]; + color zColor = colors[z]; + + // + if (iZone.ticks >= ticksCount * zLevel) + { + // + iRectColor = zColor; + break; + } + } + + // + iRect.Color(iRectColor); + } + + // + mChartObjects.Add(iRect); + mChartObjects.Add(iLabel); + } + + // + return result; + } + + // + bool Remove( + long chartId = 0, + string prefix = "XSCZone", + int subWindow = 0, + bool redraw = false // + ) + { + // + bool result = false; + + // + mChartObjects.Clear(); + + // + result = + // + true + // + ; + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + + // + datetime mStartTime; + datetime mEndTime; + + // + MqlTick mTicks[]; + double mHighs[]; + double mLows[]; + double mRangeHigh; + datetime mRangeHighTime; + double mRangeLow; + datetime mRangeLowTime; + + // + CArrayObj mZones; + CArrayObj mChartObjects; + + // + // Tools ... + + // + int CountTicks() + { + return ArraySize(mTicks); + } + + // + double GetRange() + { + return mRangeHigh - mRangeLow; + } + + // + // Check a Tick is in a Zone rage or not ... + bool IsTickInZoneRange( + MqlTick &tick, // Tick For Checking + XSCZone *zone // Zone For Checking + ) + { + // + bool result = false; + + // + result = + // + tick.bid >= zone.low && + tick.bid <= zone.high + // + ; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + + // + string mSymbol; // Analyzing Symbol + ENUM_TIMEFRAMES mPeriod; // Analyzing Period + + // + XSCZonesInput mInputs; // Configurations + + // + int mCalculatedBars; // Calculated Bars ... +}; \ No newline at end of file diff --git a/BKPS/14030412/Classes/x-saherelm.xtrade.class.ex5 b/BKPS/14030412/Classes/x-saherelm.xtrade.class.ex5 new file mode 100644 index 0000000..ceba3ec Binary files /dev/null and b/BKPS/14030412/Classes/x-saherelm.xtrade.class.ex5 differ diff --git a/BKPS/14030412/Classes/x-saherelm.xtrade.class.mq5 b/BKPS/14030412/Classes/x-saherelm.xtrade.class.mq5 new file mode 100644 index 0000000..3947d2c --- /dev/null +++ b/BKPS/14030412/Classes/x-saherelm.xtrade.class.mq5 @@ -0,0 +1,3764 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCTrade +// Description: provides all Trade requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" +#include "../Libraries/x-saherelm.xtrade.lib.mq5" +#include "../Classes/x-saherelm.xaccount.class.mq5" + +// +// Definitions ... + +// +// Overrides ... + +// +// XCTrade Base Class ... +class XSCTradeBase : public CTrade +{ +public: + // + // Modify Specific Position, by Specific Comment ... + bool PositionModify( + const string symbol, // Symbol + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!SelectPosition(symbol)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.symbol = symbol; + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + bool PositionModify( + const ulong ticket, // Position Ticket + const double sl, // Stop Loss + const double tp, // Take Profit + const string comment = "" // Comment For Modify + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // setting request + m_request.action = TRADE_ACTION_SLTP; + m_request.position = ticket; + m_request.symbol = PositionGetString(POSITION_SYMBOL); + m_request.magic = m_magic; + m_request.sl = sl; + m_request.tp = tp; + + // + // Specified Comment ... + if (StringLen(comment) > 0) + { + m_request.comment = comment; + } + + // + // action and return the result + return (OrderSend(m_request, m_result)); + } + + // + // Close Specific Position, by Specific Comment ... + bool PositionClose( + const string symbol, // Symbol + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + bool partial_close = false; + int retry_count = 10; + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + do + { + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specify Comment ... + m_request.comment = comment; + + // + // check volume + double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); + if (m_request.volume > max_volume) + { + // + m_request.volume = max_volume; + partial_close = true; + } + else + { + partial_close = false; + } + + // + // hedging? just send order + if (IsHedging()) + { + return (OrderSend(m_request, m_result)); + } + + // + // order send + if (!OrderSend(m_request, m_result)) + { + // + if (--retry_count != 0) + { + continue; + } + + // + if (retcode == TRADE_RETCODE_DONE_PARTIAL) + { + m_result.retcode = retcode; + } + + // + return (false); + } + + // + //--- WARNING. If position volume exceeds the maximum volume allowed for deal, + //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, + //--- but partially. It is decreased by the maximum volume allowed for deal. + if (m_async_mode) + { + break; + } + + // + retcode = TRADE_RETCODE_DONE_PARTIAL; + if (partial_close) + { + Sleep(1000); + } + } while (partial_close); + + // + // succeed + return (true); + } + bool PositionClose( + const ulong ticket, // Position Ticket + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = PositionGetDouble(POSITION_VOLUME); + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specify Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } + + // + // Partial Close Specific Position, by Specific Comment ... + bool PositionClosePartial( + const string symbol, // Symbol + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + uint retcode = TRADE_RETCODE_REJECT; + + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if (SelectPosition(symbol)) + { + // + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + } + else + { + // + // position not found + m_result.retcode = retcode; + return (false); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + m_request.position = PositionGetInteger(POSITION_TICKET); + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // hedging? just send order + return (OrderSend(m_request, m_result)); + } + bool PositionClosePartial( + const ulong ticket, // Position Ticket + const double volume, // Partial Closing Volume + const ulong deviation, // Deviation + const string comment = "" // Comment For Close + ) + { + // + // check stopped + if (IsStopped(__FUNCTION__)) + { + return (false); + } + + // + // for hedging mode only + if (!IsHedging()) + { + return (false); + } + + // + // check position existence + if (!PositionSelectByTicket(ticket)) + { + return (false); + } + + // + string symbol = PositionGetString(POSITION_SYMBOL); + + // + // clean + ClearStructures(); + + // + // check filling + if (!FillingCheck(symbol)) + { + return (false); + } + + // + // check + if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) + { + // + // prepare request for close BUY position + m_request.type = ORDER_TYPE_SELL; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); + } + else + { + // + // prepare request for close SELL position + m_request.type = ORDER_TYPE_BUY; + m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); + } + + // + // check volume + double position_volume = PositionGetDouble(POSITION_VOLUME); + if (position_volume > volume) + { + position_volume = volume; + } + + // + // setting request + m_request.action = TRADE_ACTION_DEAL; + m_request.position = ticket; + m_request.symbol = symbol; + m_request.volume = position_volume; + m_request.magic = m_magic; + m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; + + // + // Specifieng Comment ... + m_request.comment = comment; + + // + // close position + return (OrderSend(m_request, m_result)); + } +}; + +// +// Implementation ... + +// +// a Class For Manage Trades and Handle Trading Actions ... +class XSCTrade : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + XSCAccount *mAccount; // Account Info Provider + + // + // Constructors ... + void XSCTrade( + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + double maxAllowedSpread = 0, // Max Allowed Spred for Opening Trades + int maxAllowedPositions = 0, // Max Allowed Positions + double maxAllowedDrawdownFactor = 0 // Max Allowed Drawdown Factor + ) + { + // + // Setting Props ... + mSlippage = slippage; + mMagicNumber = magicNumber; + + // + mMaxAllowedSpread = maxAllowedSpread; + mMaxAllowedPositions = maxAllowedPositions; + mMaxAllowedDrawdownFactor = maxAllowedDrawdownFactor; + + // + mAccount = new XSCAccount(); + + // + // Instance Base Trader Class ... + mTrader = new XSCTradeBase(); + + // + // Configuring Base Trader Class ... + mTrader.SetAsyncMode(false); + mTrader.SetDeviationInPoints(mSlippage); + mTrader.SetExpertMagicNumber(mMagicNumber); + + // + // Setting Log Level ... + mTrader.LogLevel(LOG_LEVEL_ERRORS); + + // + // OnTrade Context ... + + // + mDaysForRead = 1; + mScanStarted = false; + + // + // Reset On Trade Counter ... + ResetOnTradeContext(); + + // + // Init On Trade Context ... + InitOnTradeContext(); + } + + // + // Deconstructor ... + ~XSCTrade() + { + // + // Remove Pointer ... + delete mTrader; + delete mAccount; + } + + // + // Props ... + + // + // Retrieve Slippage ... + int GetSlippage() + { + return mSlippage; + } + + // + // Retrieve Magic Number ... + ulong GetMagicNumber() + { + return mMagicNumber; + } + + // + double GetMaxAllowedSpread() + { + return mMaxAllowedSpread; + } + + // + int GetMaxAllowedPositions() + { + return mMaxAllowedPositions; + } + + // + void SetMaxAllowedPositions(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedPositions = value; + } + + // + double GetMaxAllowedDrawdownFactor() + { + return mMaxAllowedDrawdownFactor; + } + + // + // Add Event Listeners ... + + // + void AddOnModifyPositionEventHandler(TOnModify handler) + { + // + Add( + handler, + mOnModifyEventHandlers + // + ); + } + + // + void AddOnForceClosePositionEventHandler(TOnForceClose handler) + { + // + Add( + handler, + mOnForceCloseEventHandlers + // + ); + } + + // + void AddOnPartialClosePositionEventHandler(TOnPartialClose handler) + { + // + Add( + handler, + mOnPartialCloseEventHandlers + // + ); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnTradeStateChangedEventHandler(TOnTradeStateChanged handler) + { + // + Add( + handler, + mTradeStateChangedEventHandlers + // + ); + } + + // + // Add New Deals Changed Event Handler ... + void AddOnDealsChangedEventHandler(TOnDealsChanged handler) + { + // + Add( + handler, + mDealsChangedEventHandlers + // + ); + } + + // + // Add New Orders Changed Event Handler ... + void AddOnOrdersChangedEventHandler(TOnOrdersChanged handler) + { + // + Add( + handler, + mOrdersChangedEventHandlers + // + ); + } + + // + // Add New Positions Changed Event Handler ... + void AddOnPositionsChangedEventHandler(TOnPositionsChanged handler) + { + // + Add( + handler, + mPositionsChangedEventHandlers + // + ); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnStopLossEventHandler(TOnStopLoss handler) + { + // + Add( + handler, + mStopLossEventHandlers + // + ); + } + + // + // Add New Stop Loss Event Handler ... + void AddOnTakeProfitEventHandler(TOnTakeProfit handler) + { + // + Add( + handler, + mTakeProfitEventHandlers + // + ); + } + + // + // Functions ... + + // + // Handlers ... + + // + // Process On Trade Requirement ... + // this Only Used when we Have to Proccess OnTrade Event in EA(s) ... + void HandleOnTradeEvent( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + result.Clean(); + + // + if (mScanStarted) + { + // + ProcessOnTradeContext(result); + } + else + { + // + // Init Trade Context ... + InitOnTradeContext(); + + // + return; + } + + // + // Here we Can Check the Start ... + bool isValid = + // + result.IsValid() && + // + !result.hasNewDeal && + !result.hasNewOrder && + !result.hasNewPosition && + !result.hasNewHistoryOrder + // + ; + if (!isValid) + { + return; + } + + // + // State ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(result); + + // + // Deals ... + if (result.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(result.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + int dealsCount = GetDeals(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // Orders ... + if (result.hasNewOrder || result.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(result.newOrders + result.newHistoryOrders); + } + + // + // Positions ... + if (result.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(result.newPositions); + } + } + + // + // This Must be Called Every time OnTrade Event Happening ... + // this Used for Implementing Custom Senarios ... + XOnTradeHandlerState HandleOnTrade() + { + // + // Handle OnTrade Event ... + XOnTradeHandlerState state; + HandleOnTradeEvent(state); + if ( + !state.hasNewDeal && + !state.hasNewOrder && + !state.hasNewPosition && + !state.hasNewHistoryOrder) + { + return state; + } + + // + // State ... + + // + // Notfy Trade State Changed Event ... + NotifyTradeStateChangeEvent(state); + + // + // DEALS ... + if (state.hasNewDeal) + { + // + // Notfy Deals Changed Event ... + NotifyDealsChangeEvent(state.newDeals); + + // + // Retrieve Last Deal ... + XDeal deals[]; + GetDeals(deals); + int dealsCount = ArraySize(deals); + if (dealsCount > 0) + { + // + XDeal lastDeal = deals[0]; + + // + if (lastDeal.reason == DEAL_REASON_TP) + { + NotifyTakeProfitEvent(lastDeal); + } + else if (lastDeal.reason == DEAL_REASON_SL) + { + NotifyStopLossEvent(lastDeal); + } + } + } + + // + // ORDERS ... + if (state.hasNewOrder || state.hasNewHistoryOrder) + { + // + // Notfy Orders Changed Event ... + NotifyOrdersChangeEvent(state.newOrders + state.newHistoryOrders); + } + + // + // POSITIONS ... + if (state.hasNewPosition) + { + // + // Notfy Positions Changed Event ... + NotifyPositionsChangeEvent(state.newPositions); + } + + // + return state; + } + + // + // Trade Actions ... + + // + // Main ... + + // + // Policies ... + + // + // Check Acocunt Balance is Allow new Trades or not ... + bool CheckEquityForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedDrawdownFactor <= 0) + { + // + result = true; + return result; + } + + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double selectedBalance = MathMax(equity, balance) - MathMin(equity, balance); + + // + double maxAllowedBalanceDrawDown = GetMaxAllowedEquity(); + + // + result = equity > balance || + (equity <= balance && + selectedBalance <= maxAllowedBalanceDrawDown); + + // + return result; + } + + // + // Check Max Allowed Positions Policy for Trade ... + bool CheckPositionsForTrade() + { + // + bool result = false; + + // + if (mMaxAllowedPositions <= 0) + { + // + result = true; + return result; + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 0) + { + // + result = true; + return result; + } + + // + result = positionsCount < mMaxAllowedPositions; + + // + return result; + } + + // + // Check Spread is Ok for Executing Specific Signal ... + bool CheckSpreadForSignalExecution(XSignal &mSignal) + { + // + bool result = false; + + // + bool isSpreadCheckEnable = mMaxAllowedSpread > 0; + if (!isSpreadCheckEnable) + { + result = true; + } + else + { + // + // Retrieve Signal Spread ... + double spread = mSignal.GetSpread(); + result = spread <= mMaxAllowedSpread; + } + + // + return result; + } + + // + // Check Account Policy ... + bool CheckAccountPolicy( + XSignal &mSignal, // For Executing Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state // State Holder + ) + { + // + bool result = false; + + // + // Check Positions For Trade ... + result = CheckPositionsForTrade(); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; + return result; + } + + // + // Check Equity For Trade ... + result = CheckEquityForTrade(); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_NO_EQUITY; + return result; + } + + // + // Check Spread for Trade ... + result = CheckSpreadForSignalExecution(mSignal); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_SPREAD; + return result; + } + + // + return result; + } + + // + // Execute a Signal ... + bool ExecuteSignal( + XSignal &mSignal, // Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + bool result = false; + state = X_SIGNAL_EXECUTION_UNKNOWN; + + // + double currentEntry = GetEntry( + mSignal.symbol, + mSignal.type + // + ); + bool isLong = IsLong(mSignal.type); + + // + if (!mSignal.IsValid()) + { + // + state = X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS; + return result; + } + + // + // Prepare Signal Comment ... + string mSComment = mSignal.GenerateComment(); + if (!Contains(mSComment, mSignal.comment)) + { + mSignal.comment += mSComment; + } + + // + // Handle Market Execution ... + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + // + // Do Apply Policies here ... + bool hasPolicy = !checkPolicies + ? true + : CheckAccountPolicy(mSignal, state); + if (!hasPolicy) + { + result = false; + } + else + { + // + if (isLong) + { + // + result = Buy( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + mSignal.comment + // + ); + } + else + { + // + result = Sell( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + mSignal.comment + // + ); + } + } + } + // + // Handle Stop Execution ... + else if (mSignal.mode == X_ORDER_MODE_STOP) + { + + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? mSignal.entry > currentEntry + : mSignal.entry < currentEntry; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; + return result; + } + + // + // Execute Order ... + if (isLong) + { + // + result = BuyStop( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + lifetime, + expiration, + mSignal.comment + // + ); + } + else + { + // + result = SellStop( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + lifetime, + expiration, + mSignal.comment + // + ); + } + } + // + // Handle Limit Execution ... + else if (mSignal.mode == X_ORDER_MODE_LIMIT) + { + // + // Check Conditions ... + + // + // Check Price ... + result = isLong + ? mSignal.entry < currentEntry + : mSignal.entry > currentEntry; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR; + return result; + } + + // + // Execute Order ... + if (isLong) + { + // + result = BuyLimit( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + lifetime, + expiration, + mSignal.comment + // + ); + } + else + { + // + result = SellLimit( + mSignal.symbol, + mSignal.period, + mSignal.volume, + mSignal.entry, + mSignal.sl, + mSignal.tp, + lifetime, + expiration, + mSignal.comment + // + ); + } + } + + // + // Handle Ticket ... + if (result) + { + // + state = X_SIGNAL_EXECUTION_SUCCEED; + + // + ulong ticket; + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + ticket = GetLastOpenPositionTicket(); + } + else + { + ticket = GetLastPlacedOrderTicket(); + } + + // + mSignal.positionId = ticket; + + // + // Handle Store XPositionInfo ... + if (mSignal.mode == X_ORDER_MODE_MARKET) + { + // + // TODO: Implement this ... + } + + // + // Handle Executing Support Signals ... + int supportsCount = ArraySize(mSignal.supports); + if (supportsCount > 0) + { + // + int executed = 0; + for (int i = 0; i < supportsCount; i++) + { + // + XSignal iSupport = mSignal.supports[i]; + + // + int supIndex = i + 1; + string iComment = GenerateSupportTag(ticket); + iSupport.comment = iComment; + + // + bool isExecuted = ExecuteSignal( + iSupport, + state, + lifetime, + expiration + // + ); + if (isExecuted) + { + executed++; + } + } + + // + result = executed == supportsCount; + } + } + + // + return result; + } + + // + // Execute a Collection Of Signals ... + int ExecuteSignals( + XSignal &signals[], // Collection of Signal for Execution + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + int result = 0; + + // + Clean(states); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + ArrayResize(states, signalsCount); + ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + lifetime, + expiration, + checkPolicies + // + ); + + // + if (isExecuted) + { + result++; + } + } + + // + return result; + } + + // + int ExecuteSpecifiedSignals( + XSignal &signals[], // Collection of Signal for Execution + XSignal ¬Executeds[], // Not Executed Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL, // order expiration time + bool checkPolicies = true // Check Account Policies + ) + { + // + int result = 0; + + // + Clean(states); + Clean(notExecuteds); + + // + int signalsCount = ArraySize(signals); + if (signalsCount <= 0) + { + return result; + } + + // + ArrayResize(states, signalsCount); + ArrayInitialize(states, X_SIGNAL_EXECUTION_UNKNOWN); + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + lifetime, + expiration + // + ); + + // + if (isExecuted) + { + result++; + } + else + { + // + AddRef( + signals[i], + notExecuteds // + ); + } + } + + // + return result; + } + + // + // Regular Trade Actions ... + + // + // Buy ... + + // + // Force Open a Buy/Long Position ... + bool Buy( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.Buy( + volume, + symbol, + price, + sl, + tp, + comment + // + ); + + // + return result; + } + + // + // Send BUY LIMIT order ... + bool BuyLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.BuyLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Send BUY STOP order ... + bool BuyStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.BuyStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Sell ... + + // + // Force Open a Sell/Short Position ... + bool Sell( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // position volume + double price, // execution price + double sl = 0, // stop loss price + double tp = 0, // take profit price + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.Sell( + volume, + symbol, + price, + sl, + tp, + comment + // + ); + + // + return result; + } + + // + // Send SELL LIMIT order ... + bool SellLimit( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.SellLimit( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Send SELL STOP order ... + bool SellStop( + string symbol, // Specified Symbol + ENUM_TIMEFRAMES period, // Specified Trade's Period + double volume, // order volume + double price, // order price + double sl = 0.0, // stop loss price + double tp = 0.0, // take profit price + ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime + datetime expiration = 0, // order expiration time + string comment = NULL // comment + ) + { + // + bool result = false; + + // + ENUM_TIMEFRAMES mPeriod = ExtractPeriod(comment); + if (!IsValid(comment) || + !IsValid(mPeriod)) + { + // + string mPeriodStr = GeneratePeriodTag(period); + + // + comment += mPeriodStr; + } + + // + result = mTrader.SellStop( + volume, + price, + symbol, + sl, + tp, + typeTime, + expiration, + comment + // + ); + + // + return result; + } + + // + // Check a Position is Exists Open or not ... + bool IsOpen( + ulong ticket // Specified Position Ticket + ) + { + // + bool result = false; + + // + result = mPositionInfo + .SelectByTicket(ticket); + + // + return result; + } + + // + // Modify Position ... + bool Modify( + const ulong ticket, // position ticket + double sl = 0, // stop loss price + double tp = 0, // take profit + string comment = NULL // comment + ) + { + // + bool result = false; + + // + // Validate Args ... + XPosition position; + result = + GetPosition( + ticket, + position // + ) && + (tp >= 0 || sl >= 0); + if (!result) + { + return result; + } + + // + // Use Position Comment when there isn't new One ... + if (!IsValid(comment) == 0) + { + // + // if there isn't provided Comment + // Use Position Comment for default ... + comment = "Modify " + GetPositionComment(ticket); + } + + // + result = mTrader.PositionModify( + ticket, + sl, + tp, + comment + // + ); + if (result) + { + // + NotifyModifyEvent( + ticket, + position.profit, + comment // + ); + } + + // + return result; + } + + // + // Close Position By Ticket ... + bool Close( + ulong ticket, // Position Ticket + string comment = NULL // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + // Check Position Open ... + XPosition position; + result = GetPosition( + ticket, + position // + ); + if (!result) + { + return result; + } + + // + // Use Default Position Comment if it's Not Provided ... + if (!IsValid(comment)) + { + comment = "Close " + GetPositionComment(ticket); + } + + // + // Close Position By Specific Comment ... + result = mTrader.PositionClose( + ticket, + mSlippage, + comment + // + ); + if (result) + { + // + NotifyForceCloseEvent( + ticket, + position, + comment // + ); + } + + // + return result; + } + + // + // Close Specified Positions ... + int Close( + string comment = NULL, // Close Position By Specific Comment + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions + ) + { + // + int result = 0; + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment + // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Close a Collection of Positions ... + int Close( + XPosition &positions[], // Collection of Positions + string comment // Close Comment + ) + { + // + int result = 0; + + // + int positionsCount = ArraySize(positions); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + bool isClosed = Close( + iPosition.ticket, + comment + // + ); + if (isClosed) + { + result++; + } + } + + // + return result; + } + + // + // Close Partial By Ticket ... + bool ClosePartial( + ulong ticket, // Position Ticket + double volume, // Volume Size for Partial Closing + string comment = NULL // Close Position By Specific Comment + ) + { + // + bool result = false; + + // + XPosition position; + result = GetPosition( + ticket, + position // + ); + if (!result) + { + return result; + } + + // + // Use Default Partial Close Comment ... + if (!IsValid(comment)) + { + // + comment += "PClose " + GetPositionComment(ticket); + } + + // + result = mTrader.PositionClosePartial( + ticket, + volume, + mSlippage, + comment + // + ); + if (result) + { + // + NotifyPartialCloseEvent( + ticket, + position.profit, + comment // + ); + } + + // + return result; + } + + // + // Cancel Specific Order ... + bool CancelOrder(ulong ticket) + { + return mTrader + .OrderDelete(ticket); + } + + // + // Cancel Specific Orders ... + int CancelOrders( + XOrder &orders[] // Specified Orders ... + ) + { + // + int result = 0; + + // + int ordersCount = ArraySize(orders); + if (ordersCount <= 0) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + bool isDeleted = mTrader + .OrderDelete(iOrder.ticket); + if (isDeleted && !result) + { + result++; + } + } + + // + return result; + } + + // + // Extractors ... + + // + // Positions ... + + // + // Calculate Positions Profit ... + double Profit( + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true // Get Only Self Open Positions + ) + { + // + double result = 0; + + // + // Retrieve Positions ... + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic + // + ); + if (positionsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < positionsCount; i++) + { + result += positions[i].profit; + } + + // + return result; + } + + // + // Retrieve Specific Position by Index ... + bool GetPosition( + int index, // Specified Index + XPosition &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + // Retrieve Specific Position by Ticket ... + bool GetPosition( + ulong ticket, // Specified Ticket + XPosition &result // Hold's Result + ) + { + // + return result + .ByTicket(ticket); + } + + // + // Retrieve Positions ... + int GetPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = PositionsTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XPosition iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + void GetPositions( + XPosition &longs[], // Hold's Longs Result + XPosition &shorts[], // Hold's Shorts Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + // Retrieve Long Positions ... + GetPositions( + longs, + symbol, + provider, + period, + X_POSITION_TYPE_LONG, + filterByMagic, + forceClean // + ); + + // + // Retrieve Short Positions ... + GetPositions( + shorts, + symbol, + provider, + period, + X_POSITION_TYPE_SHORT, + filterByMagic, + forceClean // + ); + } + + // + // Select In Profit Positions ... + int GetInProfitPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic, + forceClean); + if (positionsCount <= 0) + { + return mResult; + } + + // + XPosition min; + XPosition max; + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (iPosition.profit <= 0) + { + continue; + } + + // + // Calculate Min and Max ... + + // + // Min ... + if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) + { + min = iPosition; + } + + // + // Max ... + if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) + { + max = iPosition; + } + + // + bool isSelectionMethodFilterPassed = + // + (method == NULL || + method == X_POSITION_SELECT_ALL) + ? true + : false; + // + ; + if (!isSelectionMethodFilterPassed) + { + continue; + } + + // + AddRef( + iPosition, + result + // + ); + } + + // + if (min.IsValid() && + (method == X_POSITION_SELECT_MIN || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + min, + result + // + ); + } + + // + if (max.IsValid() && + (method == X_POSITION_SELECT_MAX || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + max, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Select In Drawdown Positions ... + int GetInDrawdownPositions( + XPosition &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + ENUM_X_POSITION_SELECT_METHODS method = NULL, // Selection Method + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + XPosition positions[]; + int positionsCount = GetPositions( + positions, + symbol, + provider, + period, + type, + filterByMagic, + forceClean); + if (positionsCount <= 0) + { + return mResult; + } + + // + XPosition min; + XPosition max; + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + if (iPosition.profit >= 0) + { + continue; + } + + // + // Calculate Min and Max ... + + // + // Min ... + if (!min.IsValid() || min.profit <= 0 || min.profit > iPosition.profit) + { + min = iPosition; + } + + // + // Max ... + if (!max.IsValid() || max.profit <= 0 || max.profit < iPosition.profit) + { + max = iPosition; + } + + // + bool isSelectionMethodFilterPassed = + // + (method == NULL || + method == X_POSITION_SELECT_ALL) + ? true + : false; + // + ; + if (!isSelectionMethodFilterPassed) + { + continue; + } + + // + AddRef( + iPosition, + result + // + ); + } + + // + if (min.IsValid() && + (method == X_POSITION_SELECT_MIN || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + min, + result + // + ); + } + + // + if (max.IsValid() && + (method == X_POSITION_SELECT_MAX || + method == X_POSITION_SELECT_BOTH)) + { + // + AddRef( + max, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Orders ... + + // + // Retrieve Specific Order by Index ... + bool GetOrder( + int index, // Specified Index + XOrder &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + // Retrieve Specific Positions Orders ... + int GetOrders( + ulong ticket, // Positions Ticket + XOrder &result[], // Hold's Result + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + // Select History by Specified Ticket ... + bool isHistorySelected = HistorySelectByPosition(ticket); + if (!isHistorySelected) + { + return mResult; + } + + // + int ordersCount = HistoryOrdersTotal(); + if (ordersCount <= 0) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder; + bool isLoaded = iOrder.HistoryByIndex(i); + if (!isLoaded) + { + continue; + } + + // + bool isTicketFilterPassed = + // + iOrder.ticket = ticket + // + ; + if (!isTicketFilterPassed) + { + continue; + } + + // + AddRef( + iOrder, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Retrieve All Orders ... + int GetOrders( + XOrder &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + ENUM_ORDER_STATE state = NULL, // Order State + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = OrdersTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XOrder iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + state, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Retrieve Historical Orders ... + int GetOrders( + XOrder &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_X_POSITION_TYPES type = NULL, // Long (Buy) or Short (Sell) + ENUM_ORDER_STATE state = NULL, // Order State + datetime startDate = NULL, // Specify Start Date + datetime endDate = NULL, // Specify End Date + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + endDate = NormalizeTime(endDate); + + // + if (!IsValid(startDate)) + { + startDate = endDate - PeriodSeconds(PERIOD_D1); + } + + // + bool isHistorySelected = HistorySelect( + startDate, + endDate); + if (!isHistorySelected) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = OrdersTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XOrder iItem; + bool isLoaded = iItem.HistoryByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + state, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Deals ... + + // + // Retrieve Specific Deal by Index ... + bool GetDeal( + int index, // Specified Index + XDeal &result // Hold's Result + ) + { + // + return result + .ByIndex(index); + } + + // + bool GetLastDeal( + XDeal &result // Hold's Result + ) + { + // + bool mResult = false; + + // + mResult = HistorySelect(0, TimeCurrent()); + if (!mResult) + { + return mResult; + } + + // + int lastDealIndex = HistoryDealsTotal() - 1; + + // + mResult = GetDeal( + lastDealIndex, + result // + ); + + // + return mResult; + } + + // + // Retrieve Specified Deal's History ... + int GetDealsHistory( + XDeal &deal, // Specified Deal + XOrder &history[], // Deals History + bool forceClean = true // Clean Result Array + ) + { + // + int result = 0; + + // + if (!deal.IsValid()) + { + return result; + } + + // + result = GetOrders( + deal.positionId, + history, + forceClean); + + // + return result; + } + + // + // Retrieve All Deals ... + int GetDeals( + XDeal &result[], // Hold's Result + string symbol = NULL, // Trading Symbol + string provider = NULL, // Signal Provider + ENUM_TIMEFRAMES period = NULL, // Trading Period + ENUM_DEAL_TYPE type = NULL, // Deal Type + ENUM_DEAL_ENTRY entry = NULL, // Deal Entry + ENUM_DEAL_REASON reason = NULL, // Deal Reason + datetime startDate = NULL, // Specify Start Date + datetime endDate = NULL, // Specify End Date + bool filterByMagic = true, // Get Only Self Open Positions + bool forceClean = true // Clean Result Array + ) + { + // + int mResult = 0; + + // + endDate = NormalizeTime(endDate); + + // + if (!IsValid(startDate)) + { + startDate = endDate - PeriodSeconds(PERIOD_D1); + } + + // + bool isHistorySelected = HistorySelect( + startDate, + endDate); + if (!isHistorySelected) + { + return mResult; + } + + // + int before = ArraySize(result); + + // + if (forceClean) + { + Clean(result); + } + + // + // Count Positions ... + int itemsCount = HistoryDealsTotal(); + if (itemsCount <= 0) + { + return mResult; + } + + // + // Loop Through all Positions ... + for (int i = itemsCount - 1; i >= 0; i--) + { + // + XDeal iItem; + bool isLoaded = iItem.ByIndex(i); + if (!isLoaded) + { + continue; + } + + // + // Now we have to Check Given Filters ... + bool isFiltersPassed = + iItem.IsFiltersPassed( + symbol, + provider, + period, + type, + entry, + reason, + mMagicNumber, + filterByMagic + // + ); + if (!isFiltersPassed) + { + continue; + } + + // + // Add Filtered Item into Result ... + AddRef( + iItem, + result + // + ); + } + + // + int after = ArraySize(result); + + // + mResult = after - before; + + // + return mResult; + } + + // + // Support Functions ... + + // + // Check a Position has Support or not ... + bool HasSupport( + ulong ticket, + bool forceOpen = true // + ) + { + // + bool result = false; + + // + result = ticket > 0; + if (!result) + { + return result; + } + + // + if (forceOpen) + { + // + result = IsOpen(ticket); + if (!result) + { + return result; + } + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + result = IsValidSize(positionsCount); + if (!result) + { + return result; + } + + // + // Extract Support Positions ... + XPosition supports[]; + int supportsCount = ExtractSupports( + positions, + supports // + ); + result = IsValidSize(supportsCount); + if (!result) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XPosition iSupport = supports[i]; + + // + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + result = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (result) + { + break; + } + } + + // + return result; + } + + // + // Retrieve Specific Position's Supports ... + int GetSupports( + ulong ticket, + XPosition &dest[], // Result ... + bool forceOpen = true // + ) + { + // + int result = 0; + + // + Clean(dest); + + // + bool hasSupport = HasSupport( + ticket, + forceOpen // + ); + if (!hasSupport) + { + return result; + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + // Extract Support Positions ... + XPosition supports[]; + int supportsCount = ExtractSupports( + positions, + supports // + ); + if (!IsValidSize(supportsCount)) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XPosition iSupport = supports[i]; + + // + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + bool isOwn = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (isOwn) + { + // + AddRef( + iSupport, + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; + } + + // + // Retrieve Specific Position's Supports ... + int GetSupports( + ulong ticket, + XOrder &dest[], // Result ... + bool forceOpen = true // + ) + { + // + int result = 0; + + // + Clean(dest); + + // + bool hasSupport = HasSupport( + ticket, + forceOpen // + ); + if (!hasSupport) + { + return result; + } + + // + XOrder orders[]; + int ordersCount = GetOrders( + orders, + NULL, // All Symbols ... + NULL, // All Providers ... + NULL, // All Periods ... + X_POSITION_TYPE_ALL, // All Types ... + ORDER_STATE_PLACED, // Untriggere Orders ... + true // + ); + if (!IsValidSize(ordersCount)) + { + return result; + } + + // + // Extract Support Positions ... + XOrder supports[]; + int supportsCount = ExtractSupports( + orders, + supports // + ); + if (!IsValidSize(supportsCount)) + { + return result; + } + + // + // Loop Through Supports ... + for (int i = 0; i < supportsCount; i++) + { + // + XOrder iSupport = supports[i]; + + // + ulong supportedTicket = ExtractSupportedTicket(iSupport.comment); + ulong eqmSupportedTicket = ExtractEQMSupportedTicket(iSupport.comment); + + // + bool isOwn = + // + (supportedTicket > 0 && ticket == supportedTicket) + // + || + // + (eqmSupportedTicket > 0 && ticket == eqmSupportedTicket) + // + ; + if (isOwn) + { + // + AddRef( + iSupport, + dest // + ); + } + } + + // + result = ArraySize(dest); + + // + return result; + } + + // + // Tools ... + + // + // Retrieve Last Open Position Ticket ... + ulong GetLastOpenPositionTicket() + { + // + ulong result = 0; + + int positionsCount = PositionsTotal(); + if (positionsCount <= 0) + { + return result; + } + + // + result = PositionGetTicket(PositionsTotal() - 1); + + // + return result; + } + + // + // Retrieve Last Placed Order Ticket ... + ulong GetLastPlacedOrderTicket() + { + // + ulong result = 0; + + int ordersCount = OrdersTotal(); + if (ordersCount <= 0) + { + return result; + } + + // + if (mOrderInfo.SelectByIndex(ordersCount - 1)) + { + result = mOrderInfo.Ticket(); + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + + // + // Event Listener Notifiers ... + + // + // State ... + void NotifyTradeStateChangeEvent(const XOnTradeHandlerState &state) + { + // + int count = ArraySize(mTradeStateChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTradeStateChanged iHandler = mTradeStateChangedEventHandlers[i]; + iHandler(state); + } + } + + // + // Deals ... + void NotifyDealsChangeEvent(int changes) + { + // + int count = ArraySize(mDealsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnDealsChanged iHandler = mDealsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // Orders ... + void NotifyOrdersChangeEvent(int changes) + { + // + int count = ArraySize(mOrdersChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnOrdersChanged iHandler = mOrdersChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // Positions ... + void NotifyPositionsChangeEvent(int changes) + { + // + int count = ArraySize(mPositionsChangedEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnPositionsChanged iHandler = mPositionsChangedEventHandlers[i]; + iHandler(changes); + } + } + + // + // StopLoss ... + void NotifyStopLossEvent(const XDeal &deal) + { + // + int count = ArraySize(mStopLossEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnStopLoss iHandler = mStopLossEventHandlers[i]; + iHandler(deal); + } + } + + // + // Take Profit ... + void NotifyTakeProfitEvent(const XDeal &deal) + { + // + int count = ArraySize(mTakeProfitEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnTakeProfit iHandler = mTakeProfitEventHandlers[i]; + iHandler(deal); + } + } + + // + void NotifyModifyEvent( + ulong ticket, + double profit, + string comment // + ) + { + // + int count = ArraySize(mOnModifyEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnModify iHandler = mOnModifyEventHandlers[i]; + iHandler( + ticket, + profit, + comment // + ); + } + } + + // + void NotifyForceCloseEvent( + ulong ticket, + XPosition &position, + string comment // + ) + { + // + int count = ArraySize(mOnForceCloseEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnForceClose iHandler = mOnForceCloseEventHandlers[i]; + iHandler( + ticket, + position, + comment // + ); + } + } + + // + void NotifyPartialCloseEvent( + ulong ticket, + double profit, + string comment // + ) + { + // + int count = ArraySize(mOnPartialCloseEventHandlers); + if (count <= 0) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + TOnModify iHandler = mOnPartialCloseEventHandlers[i]; + iHandler( + ticket, + profit, + comment // + ); + } + } + + // + // Tools ... + + // + // Retrieve Specified Position Comment ... + string GetPositionComment(ulong ticket) + { + // + string result = NULL; + + // + if (!IsOpen(ticket)) + { + return result; + } + + // + XPosition position; + bool isLoaded = position.ByTicket(ticket); + if (!isLoaded) + { + return result; + } + + // + result = position.comment; + + // + return result; + } + + // + ENUM_TIMEFRAMES GetDealPeriod(XDeal &deal) + { + // + ENUM_TIMEFRAMES result = NULL; + + // + XOrder orders[]; + int ordersCount = GetDealsHistory( + deal, + orders); + if (!ordersCount) + { + return result; + } + + // + for (int i = 0; i < ordersCount; i++) + { + // + XOrder iOrder = orders[i]; + + // + if (IsValid(iOrder.comment)) + { + // + ENUM_TIMEFRAMES iPeriod = ExtractPeriod(iOrder.comment); + if (IsValid(iPeriod)) + { + result = iPeriod; + break; + } + } + } + + // + return result; + } + + // + double GetMaxAllowedEquity() + { + // + double equity = mAccount.GetEquity(); + double balance = mAccount.GetBalance(); + + // + double balanceForFactor = MathAbs(equity - balance); + if (balanceForFactor <= 0) + { + balanceForFactor = balance; + } + else + { + balanceForFactor = equity; + } + + // + double result = balanceForFactor * mMaxAllowedDrawdownFactor; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + + // + int mSlippage; // Slippage ... + ulong mMagicNumber; // Magic Number (Unique Identifier) ... + + // + double mMaxAllowedSpread; // Max Allowed Spred for Opening Trades + int mMaxAllowedPositions; // Max Allowed Same Positions + double mMaxAllowedDrawdownFactor; // Max Allowed Drawdown Factor + + // + XSCTradeBase *mTrader; // Base CTrade Manipulated Instance ... + + // + CDealInfo mDealInfo; // Deals Info ... + COrderInfo mOrderInfo; // Order Info ... + CPositionInfo mPositionInfo; // Positions Info + CHistoryOrderInfo mHistoryOrderInfo; // History Orders Info ... + + // + // Position Info Collector ... + + // + // Tools ... + + // + // OnTrade Event Handlers Section ... + + // + // Props ... + + // + int mDaysForRead; // Reading Dates for Trade History Checker ... + datetime mEndDate; // End Date for Trade history Checking ... + datetime mStartDate; // Start Date for Trade history Checking ... ... + int mOrdersCount; // Number of Active orders ... + int mPositionsCount; // Number of Open positions ... + int mDealsCount; // Number of Deals in the Trade History Checking ... + int mHistoryOrdersCount; // Number of Orders in the Trade History Checking ... + bool mScanStarted; // a Flag of counter relevance ... + + // + // Event Listeners ... + + // + // Deals Changed Event Handlers ... + TOnDealsChanged mDealsChangedEventHandlers[]; + + // + // Orders Changed Event Handlers ... + TOnOrdersChanged mOrdersChangedEventHandlers[]; + + // + // Positions Changed Event Handlers ... + TOnPositionsChanged mPositionsChangedEventHandlers[]; + + // + // Trade State Changed Event Handlers ... + TOnTradeStateChanged mTradeStateChangedEventHandlers[]; + + // + TOnModify mOnModifyEventHandlers[]; + TOnForceClose mOnForceCloseEventHandlers[]; + TOnPartialClose mOnPartialCloseEventHandlers[]; + + // + // TPSL ... + TOnStopLoss mStopLossEventHandlers[]; + TOnTakeProfit mTakeProfitEventHandlers[]; + + // + // Reset On Trade Scanner Context ... + void ResetOnTradeContext() + { + // + mEndDate = TimeCurrent(); + mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + } + + // + // Initial Context Of Trade Scanner ... + void InitOnTradeContext() + { + // + ResetLastError(); + + // + mOrdersCount = OrdersTotal(); + mPositionsCount = PositionsTotal(); + + // + // load history ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current value ... + mDealsCount = HistoryDealsTotal(); + mHistoryOrdersCount = HistoryOrdersTotal(); + + // + mScanStarted = true; + } + + // + // Check Statrt Date In Trade History ... + void CheckStartDateInTradeHistory() + { + // + // initial interval, if we were to start working right now .. + datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); + + // + // make sure that the start limit of the trade history has not gone + // more than 1 day over the intended date ... + if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) + { + // + // correct the start date of history to be loaded in the cache ... + mStartDate = currStart; + + // + // now reload the trade history for the updated interval ... + HistorySelect(mStartDate, mEndDate); + + // + // correct the deal and order counters in history for further comparison + mHistoryOrdersCount = HistoryOrdersTotal(); + mDealsCount = HistoryDealsTotal(); + } + } + + // + // Process On Trade Context ... + void ProcessOnTradeContext( + XOnTradeHandlerState &result // Hold's Result + ) + { + // + mEndDate = TimeCurrent(); + + // + ResetLastError(); + + // + // download trading history from the specified interval to the program cache ... + bool selected = HistorySelect(mStartDate, mEndDate); + if (!selected) + { + return; + } + + // + // get the current values ... + int currOrders = OrdersTotal(); + int currPositions = PositionsTotal(); + int currDeals = HistoryDealsTotal(); + int currHistoryOrders = HistoryOrdersTotal(); + + // + // Orders ... + // check if the number of active orders has been changed ... + if (currOrders != mOrdersCount) + { + // + // number of active orders has been changed ... + result.hasNewOrder = true; + result.newOrders = currOrders - mOrdersCount; + + // + // update the value ... + mOrdersCount = currOrders; + } + + // + // Positions ... + // changes in the number of open positions ... + if (currPositions != mPositionsCount) + { + // + // number of open positions has been changed ... + result.hasNewPosition = true; + result.newPositions = currPositions - mPositionsCount; + + // + // update the value ... + mPositionsCount = currPositions; + } + + // + // Deals ... + // changes in the number of deals in the trade history cache ... + if (currDeals != mDealsCount) + { + // + // number of deals in the trade history cache has been changed ... + result.hasNewDeal = true; + result.newDeals = currDeals - mDealsCount; + + // + // update the value ... + mDealsCount = currDeals; + } + + // + // History Orders ... + // changes in the number of history orders in the trade history cache ... + if (currHistoryOrders != mHistoryOrdersCount) + { + // + // number of history orders in the trade history cache has been changed ... + result.hasNewHistoryOrder = true; + result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; + + // + // update the value ... + mHistoryOrdersCount = currHistoryOrders; + } + + // + // checking if it is necessary to change the limits of the trade history to be requested in cache ... + CheckStartDateInTradeHistory(); + } +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/.gitkeep b/BKPS/14030412/Documents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/BKPS/14030412/Documents/BKP/Ideas/x-saherelm.xmgtd.mq5 b/BKPS/14030412/Documents/BKP/Ideas/x-saherelm.xmgtd.mq5 new file mode 100644 index 0000000..f9283ab --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Ideas/x-saherelm.xmgtd.mq5 @@ -0,0 +1,504 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XMGTD +// Description: Mega Trend ... +// +// 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 XMGTD Indicator" +#property strict + +// +#define ShortName "XMGTD" + +// +// Imports ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; +input int length = 14; // Length +input double coeff = 2.0; // Coefficient +input double multiplier = 3.0; // Multiplier +input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Applied To + +// +input group "Presentation"; +input bool show = true; // Show +input bool showSTR = false; // Show STR +input bool showHTD = false; // Show HTR +input bool showATSL = false; // Show ATSL + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 13 +#property indicator_plots 6 + +// +#define mainBufferIndex 0 +double mainBuffer[]; + +// +#define mainBufferColorIndex 1 +double mainBufferColor[]; + +// +#define hideColorIDX 0 +#define bullColorIDX 1 +#define bearColorIDX 2 + +// +#property indicator_label1 "XMGTD" +#property indicator_type1 DRAW_COLOR_LINE +#property indicator_color1 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style1 STYLE_DOT +#property indicator_width1 1 + +// +#define atslBufferIndex 2 +#define atslBufferPlotIndex 1 +double atslBuffer[]; + +// +#define atslBufferColorIndex 3 +double atslBufferColor[]; + +// +#property indicator_label2 "XATSL" +#property indicator_type2 DRAW_COLOR_LINE +#property indicator_color2 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 + +// +#define htdBufferIndex 4 +#define htdBufferPlotIndex 2 +double htdBuffer[]; + +// +#define htdBufferColorIndex 5 +double htdBufferColor[]; + +// +#property indicator_label3 "XHTD" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrGreen, clrDarkRed +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define hlBufferIndex 6 +double hlBuffer[]; + +// +#define wmaBufferIndex 7 +double wmaBuffer[]; + +// +#define tmpBufferIndex 8 +double tmpBuffer[]; + +// +#define diffBufferIndex 9 +double diffBuffer[]; + +// +#define upBufferIndex 10 +double upBuffer[]; + +// +#define downBufferIndex 11 +double downBuffer[]; + +// +#define directionBufferIndex 12 +double directionBuffer[]; + +// +// Variables ... + +// +int maPeriod; +double kpi; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + maPeriod = int(length < 1 ? 1 : length); + double n1 = 2.0 * double(maPeriod - 1); + kpi = 2.0 / (n1 + 1); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + + // + if (rates_total < maPeriod) + { + return 0; + } + + // + int limit = rates_total - prev_calculated; + if (limit > 1) + { + // + limit = rates_total - 2; + + // + ArrayInitialize(atslBuffer, EMPTY_VALUE); + ArrayInitialize(hlBuffer, 0); + ArrayInitialize(diffBuffer, 0); + ArrayInitialize(wmaBuffer, 0); + ArrayInitialize(tmpBuffer, 0); + } + + // + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + hlBuffer[i] = high[i] - low[i]; + + // + double href = 0; + double lref = 0; + + // + double sma = MAOnArray(hlBuffer, 0, maPeriod, 0, MODE_SMA, i); + double hiLo = fmin(hlBuffer[i], sma); + + // + href = (low[i] <= high[i + 1] ? high[i] - close[i + 1] : (hlBuffer[i] - close[i + 1] + high[i + 1]) / 2); + lref = (high[i] >= low[i + 1] ? close[i + 1] - low[i] : (close[i + 1] - low[i + 1] + hlBuffer[i]) / 2); + + // + diffBuffer[i] = fmax(hiLo, fmax(href, lref)); + } + + // + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + if (i == rates_total - 2) + { + wmaBuffer[i] = MAOnArray(diffBuffer, 0, maPeriod, 0, MODE_EMA, i); + } + else + { + wmaBuffer[i] = (diffBuffer[i] - wmaBuffer[i + 1]) * kpi + wmaBuffer[i + 1]; + } + } + + // + for (int i = limit; i >= 0 && !IsStopped(); i--) + { + // + double loss = wmaBuffer[i] * coeff; + if (close[i] > tmpBuffer[i + 1] && close[i + 1] > tmpBuffer[i + 1]) + { + // + tmpBuffer[i] = fmax(tmpBuffer[i + 1], close[i] - loss); + + // + atslBuffer[i] = tmpBuffer[i]; + } + else + { + // + if (close[i] < tmpBuffer[i + 1] && close[i + 1] < tmpBuffer[i + 1]) + { + // + tmpBuffer[i] = fmin(tmpBuffer[i + 1], close[i] + loss); + + // + atslBuffer[i] = tmpBuffer[i]; + } + else + { + // + if (close[i] > tmpBuffer[i + 1]) + { + // + tmpBuffer[i] = close[i] - loss; + + // + atslBuffer[i] = tmpBuffer[i]; + } + else + { + // + tmpBuffer[i] = close[i] + loss; + + // + atslBuffer[i] = tmpBuffer[i]; + } + } + } + + // + // Define Color Buffer ... + double clrValue = !showATSL + ? hideColorIDX + : atslBuffer[i] > close[i] + ? bearColorIDX + : bullColorIDX; + atslBufferColor[i] = clrValue; + } + + // + return rates_total; +} + +// +// Custom Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = length >= 2 && + coeff > 0; + + // + return result; +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Define Indexes and Styles ... + +// +void DefineBuffers() +{ + // + // Main ... + ENUM_DRAW_TYPE mainDrawType = show ? DRAW_COLOR_LINE : DRAW_NONE; + + // + ArraySetAsSeries(mainBuffer, true); + ArraySetAsSeries(mainBufferColor, true); + PlotIndexSetInteger(mainBufferIndex, PLOT_SHOW_DATA, show); + SetIndexBuffer(mainBufferIndex, mainBuffer, INDICATOR_DATA); + PlotIndexSetInteger(mainBufferIndex, PLOT_DRAW_TYPE, mainDrawType); + SetIndexBuffer(mainBufferColorIndex, mainBufferColor, INDICATOR_COLOR_INDEX); + + // + // XATSL ... + ENUM_DRAW_TYPE atslDrawType = showATSL ? DRAW_COLOR_LINE : DRAW_NONE; + + // + ArraySetAsSeries(atslBuffer, true); + ArraySetAsSeries(atslBufferColor, true); + SetIndexBuffer(atslBufferIndex, atslBuffer, INDICATOR_DATA); + SetIndexBuffer(atslBufferColorIndex, atslBufferColor, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(atslBufferPlotIndex, PLOT_SHOW_DATA, showATSL); + PlotIndexSetInteger(atslBufferPlotIndex, PLOT_DRAW_TYPE, atslDrawType); + + // + // XHTD ... + ENUM_DRAW_TYPE htdDrawType = showHTD ? DRAW_COLOR_LINE : DRAW_NONE; + + // + SetIndexBuffer(htdBufferIndex, htdBuffer, INDICATOR_DATA); + SetIndexBuffer(htdBufferColorIndex, htdBufferColor, INDICATOR_COLOR_INDEX); + PlotIndexSetInteger(htdBufferPlotIndex, PLOT_SHOW_DATA, showHTD); + PlotIndexSetInteger(htdBufferPlotIndex, PLOT_DRAW_TYPE, htdDrawType); + + // + ArraySetAsSeries(hlBuffer, true); + SetIndexBuffer(hlBufferIndex, hlBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(wmaBuffer, true); + SetIndexBuffer(wmaBufferIndex, wmaBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(tmpBuffer, true); + SetIndexBuffer(tmpBufferIndex, tmpBuffer, INDICATOR_CALCULATIONS); + + // + ArraySetAsSeries(diffBuffer, true); + SetIndexBuffer(diffBufferIndex, diffBuffer, INDICATOR_CALCULATIONS); + + // + SetIndexBuffer(upBufferIndex, upBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(downBufferIndex, downBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(directionBufferIndex, directionBuffer, INDICATOR_CALCULATIONS); +} + +// +// Hull Handler ... +double workHull[][2]; +double iHull( + double price, + double period, + int r, + int bars, + int instanceNo = 0 // +) +{ + // + if (ArrayRange(workHull, 0) != bars) + { + ArrayResize(workHull, bars); + } + + // + int HmaPeriod = (int)MathMax(period, 2); + int HalfPeriod = (int)MathFloor(HmaPeriod / 2); + int HullPeriod = (int)MathFloor(MathSqrt(HmaPeriod)); + double hma, hmw, weight; + instanceNo *= 2; + + // + workHull[r][instanceNo] = price; + + // + hmw = HalfPeriod; + hma = hmw * price; + for (int k = 1; k < HalfPeriod && (r - k) >= 0; k++) + { + // + weight = HalfPeriod - k; + hmw += weight; + hma += weight * workHull[r - k][instanceNo]; + } + workHull[r][instanceNo + 1] = 2.0 * hma / hmw; + + // + hmw = HmaPeriod; + hma = hmw * price; + for (int k = 1; k < period && (r - k) >= 0; k++) + { + // + weight = HmaPeriod - k; + hmw += weight; + hma += weight * workHull[r - k][instanceNo]; + } + workHull[r][instanceNo + 1] -= hma / hmw; + + // + hmw = HullPeriod; + hma = hmw * workHull[r][instanceNo + 1]; + for (int k = 1; k < HullPeriod && (r - k) >= 0; k++) + { + // + weight = HullPeriod - k; + hmw += weight; + hma += weight * workHull[r - k][1 + instanceNo]; + } + + // + return (hma / hmw); +} + +// +double getPrice(ENUM_APPLIED_PRICE price, const double &open[], const double &close[], const double &high[], const double &low[], int i, int bars) +{ + switch (price) + { + case PRICE_CLOSE: + return (close[i]); + case PRICE_OPEN: + return (open[i]); + case PRICE_HIGH: + return (high[i]); + case PRICE_LOW: + return (low[i]); + case PRICE_MEDIAN: + return ((high[i] + low[i]) / 2.0); + case PRICE_TYPICAL: + return ((high[i] + low[i] + close[i]) / 3.0); + case PRICE_WEIGHTED: + return ((high[i] + low[i] + close[i] + close[i]) / 4.0); + // case PRICE_AVERAGE: return((high[i]+low[i]+close[i]+open[i])/4.0); + } + return (0); +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-nn-test.mq5 b/BKPS/14030412/Documents/BKP/Old/x-nn-test.mq5 new file mode 100644 index 0000000..4d68dfd --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-nn-test.mq5 @@ -0,0 +1,384 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XNNTest MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XNNTest +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XNNTest" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.xtrade.class.mq5" + +// +#define ShortName "XNNTest" + +// +// Inputs ... +input group "Weights"; +input double w0 = 0.5; +input double w1 = 0.5; +input double w2 = 0.5; +input double w3 = 0.5; +input double w4 = 0.5; +input double w5 = 0.5; +input double w6 = 0.5; +input double w7 = 0.5; +input double w8 = 0.5; +input double w9 = 0.5; + +// +input double eaVolume = 0.01; + +// +// Variables ... +int barsTotal; + +// +string eaSymbol; +ENUM_TIMEFRAMES eaPeriod; + +// +// This is our Data Provider ... +int rsiHandler = INVALID_HANDLE; +double rsi[]; + +// +double nnInputs[]; // Storing Inputs +double nnWeights[]; // Storing Weights; + +// +double nnOutput; // Output Neuron Value + +// +XSCTrade *mTrader; + +// +// Initialization ... +int OnInit() +{ + // + if (!InitialEA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XSampleEA Providers ... + IndicatorRelease(rsiHandler); + ArrayFree(rsi); + ArrayFree(nnInputs); + ArrayFree(nnWeights); +} + +// +// On Tick Handler ... +void OnTick() +{ + // + XPosition positions[]; + + // + XPosition longs[]; + int longsCount = 0; + + // + XPosition shorts[]; + int shortsCount = 0; + + // + int positionsCount = mTrader.GetPositions( + positions // + ); + if (IsValidSize(positionsCount)) + { + // + ExtractPositions( + positions, + longs, + shorts // + ); + + // + longsCount = ArraySize(longs); + shortsCount = ArraySize(shorts); + } + + // + if (longsCount == 0 && shortsCount == 0) + { + // + double longEntry = GetEntry(eaSymbol, POSITION_TYPE_BUY); + mTrader.Buy( + eaSymbol, + eaPeriod, + eaVolume, + longEntry // + ); + + // + double shortEntry = GetEntry(eaSymbol, POSITION_TYPE_SELL); + mTrader.Sell( + eaSymbol, + eaPeriod, + eaVolume, + shortEntry // + ); + } + + // + return; + // int rsiCopiedData = CopyBuffer( + // rsiHandler, + // 0, // Line Index + // 1, // BarIndex + // 10, // Count + // rsi // Buffer + // ); + // if (rsiCopiedData < 0) + // { + // // + // // Ignore Moving Forward when there isn't any Copied Data ... + // return; + // } + + // // + // // Normalize Input Data ... + // double lower = 0; + // double upper = 1; + + // // + // double max = rsi[ArrayMaximum(rsi)]; + // double min = rsi[ArrayMinimum(rsi)]; + + // // + // ArrayFree(nnInputs); + // ArrayResize(nnInputs, 10); + + // // + // for (int i = 0; i < ArraySize(rsi); i++) + // { + // nnInputs[i] = ((rsi[i] - min) * (upper - lower) / (max - min)) + lower; + // } + + // // + // // Calculating Output ... + // nnOutput = CalculateNeuron( + // nnInputs, + // nnWeights // + // ); + + // // + // // Now we Can Use NN Output for Placing Trades ... + + // // + // bool canBuy = nnOutput < 0.5; + // bool canSell = nnOutput >= 0.5; + + // // + // XPosition positions[]; + // XPosition longs[]; + // XPosition shorts[]; + // int positionsCount = mTrader.GetPositions( + // positions // + // ); + // if (IsValidSize(positionsCount)) + // { + // // + // ExtractPositions( + // positions, + // longs, + // shorts // + // ); + + // // + // if (canBuy) + // { + // // + // mTrader.Close(shorts, "Opposit"); + + // // + // if (ArraySize(longs) > 0) + // { + // return; + // } + // } + // else if (canSell) + // { + // // + // mTrader.Close(longs, "Opposit"); + + // // + // if (ArraySize(shorts) > 0) + // { + // return; + // } + // } + // } + + // // + // double mEntry = + // canBuy + // ? GetEntry(eaSymbol, POSITION_TYPE_BUY) + // : GetEntry(eaSymbol, POSITION_TYPE_SELL); + + // // + // if (canBuy) + // { + // // + // mTrader.Buy( + // eaSymbol, + // eaPeriod, + // eaVolume, + // mEntry // + // ); + // } + // else if (canSell) + // { + // // + // mTrader.Sell( + // eaSymbol, + // eaPeriod, + // eaVolume, + // mEntry // + // ); + // } +} + +// +// Custom Functions ... + +// +bool InitialEA() +{ + // + bool result = false; + + // + eaSymbol = _Symbol; + eaPeriod = _Period; + + // + // Initialize RSI Handler ... + rsiHandler = iRSI( + eaSymbol, + eaPeriod, + 14, + PRICE_CLOSE // + ); + result = rsiHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + mTrader = new XSCTrade( + 1, + 78692110 // + ); + + // + ArraySetAsSeries(rsi, true); + + // + ArrayResize(nnWeights, 10); + + // + // Filling Weights Buffer ... + nnWeights[0] = w0; + nnWeights[1] = w1; + nnWeights[2] = w2; + nnWeights[3] = w3; + nnWeights[4] = w4; + nnWeights[5] = w5; + nnWeights[6] = w6; + nnWeights[7] = w7; + nnWeights[8] = w8; + nnWeights[9] = w9; + + // + result = true; + + // + return result; +} + +// +// Activation Function ... +double Activate(double neuron) +{ + // + double result = 0; + + // + result = 1 / (1 + exp(-neuron)); + + // + return result; +} + +// +// Calculating Neuron ... +// NET Inputs ... +double CalculateNeuron( + double &x[], // Inputs + double &w[] // Weights +) +{ + // + double result = 0; + + // + double netInput = 0; + for (int i = 0; i < ArraySize(x); i++) + { + // + netInput += x[i] * w[i]; + } + + // + // Change The Shape of Sigmoid Graph for Smoothing ... + netInput *= 0.4; + + // + // Calculate Activated Result ... + result = Activate(netInput); + + // + return result; +} \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-saherelm.x121.setup.xea.mq5 b/BKPS/14030412/Documents/BKP/Old/x-saherelm.x121.setup.xea.mq5 new file mode 100644 index 0000000..3b6ab89 --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-saherelm.x121.setup.xea.mq5 @@ -0,0 +1,5878 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCX121SetupCycle +// Description: provides implementation of X121 +// Setup on Specified Market Cycle ... +// +// +// 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 + +// +// Imports ... + +// +#include "../Classes/x-saherelm.xea.class.mq5" +#include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" + +// +// Definitions ... + +// +// Model all Trades Data as this Structure ... +struct XTradeInfo +{ + // + int pushers; // Signal Pushers + datetime time; // Issue Time (Open Position) + string symbol; // Trading Symbol + double entry; // Entry Price + double volume; // Volume + string provider; // Signaller + ENUM_TIMEFRAMES period; // Trading Timeframe + ENUM_X_POSITION_TYPES type; // Position Type + + // + ulong ticket; // Position Ticket + double profit; // Profit on Close + double commission; // Commission + double swap; // Swap + string message; // Close Reason + datetime endTime; // End Time + + // + X121SetupConditions cConditions; // Generated Current Conditions + X121SetupConditions sConditions; // Generated Short Conditions + X121SetupConditions mConditions; // Generated Medium Conditions + X121SetupConditions lConditions; // Generated Long Conditions + X121SetupConditions hConditions; // Generated Hind Conditions + + // + // Constructor ... + void XTradeInfo() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + time = NULL; + type = NULL; + symbol = NULL; + period = NULL; + endTime = NULL; + message = NULL; + provider = NULL; + + // + swap = 0; + entry = 0; + ticket = 0; + profit = 0; + volume = 0; + pushers = 0; + commission = 0; + + // + cConditions.Clean(); + sConditions.Clean(); + mConditions.Clean(); + lConditions.Clean(); + hConditions.Clean(); + + // + ResetGrid(); + ResetSupport(); + ResetRecovery(); + } + + // + bool Fill( + const XSignal &_signal, + int _pushers, + bool _allowGrid, + bool _allowRecover, + bool _allowSupport, + X121SetupConditions &_cConditions, + X121SetupConditions &_sConditions, + X121SetupConditions &_mConditions, + X121SetupConditions &_lConditions, + X121SetupConditions &_hConditions // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_signal.symbol) && + IsValid(_signal.period) && + IsValid(_signal.provider) + // + ; + + // + if (!result) + { + return result; + } + + // + pushers = _pushers; + time = _signal.time; + entry = _signal.entry; + symbol = _signal.symbol; + period = _signal.period; + volume = _signal.volume; + provider = _signal.provider; + type = ToPositionType(_signal.type); + + // + cConditions = _cConditions; + sConditions = _sConditions; + mConditions = _mConditions; + lConditions = _lConditions; + hConditions = _hConditions; + + // + allowGrid = _allowGrid; + allowRecover = _allowRecover; + allowSupport = _allowSupport; + + // + return result; + } + + // + bool IsOwn( + ulong _ticket // + ) + { + // + bool result = false; + + // + result = _ticket == ticket; + + // + return result; + } + + // + bool IsOwn( + string _symbol, + string _provider, + ENUM_TIMEFRAMES _period // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_symbol) && + IsValid(_provider) && + IsValid(_period) && + // + symbol == _symbol && + provider == _provider && + period == _period + // + ; + + // + return result; + } + + // + bool IsOwn(XSignal &signal) + { + // + return IsOwn( + signal.symbol, + signal.provider, + signal.time, + signal.period, + signal.type // + ); + } + + // + bool IsOwn( + string _symbol, + string _provider, + datetime _time, + ENUM_TIMEFRAMES _period, + ENUM_POSITION_TYPE _type // + ) + { + // + bool result = false; + + // + ENUM_X_POSITION_TYPES iType = ToPositionType(_type); + + // + result = + // + IsValid(_symbol) && + IsValid(_provider) && + IsValid(_period) && + // + symbol == _symbol && + provider == _provider && + period == _period && + type == iType && + time == _time + // + ; + + // + return result; + } + + // + // Data Collector ... + + // + bool IsValid() + { + // + bool result = false; + + // + result = + // + ticket > 0 && + IsValid(time) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } + + // + int GetAge() + { + // + int result = -1; + + // + if (!IsValid(symbol) || + !IsValid(time) || + !IsValid(endTime) || + !IsValid(period)) + { + return result; + } + + // + int startIndex = iBarShift( + symbol, + period, + time, + false // + ); + + // + int endIndex = iBarShift( + symbol, + period, + endTime, + false // + ); + + // + result = MathAbs(startIndex - endIndex); + + // + return result; + } + + // + string GetFileName() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = + // + symbol + "\\" + + ToString(type) + "\\" + + (profit >= 0 + ? "Profit" + : "Loss") + + "\\" + + provider + "_" + + ToString(ticket) + "_" + + ToString(period) + "_" + + ToFormatString(time) + // + ; + + // + return result; + } + + // + string GetSignalFileName() + { + // + string result = NULL; + + // + result = + // + symbol + "\\" + + ToString(type) + "\\" + + provider + "_" + + ToFormatString(time) + // + ; + + // + return result; + } + + // + string ToString( + bool onlySignals = false // + ) + { + // + string result = NULL; + + // + string cConditionsStr = cConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string sConditionsStr = sConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string mConditionsStr = mConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string lConditionsStr = lConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string hConditionsStr = hConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + + // + int age = GetAge(); + + // + result = + // + (onlySignals + ? "" + : ToString("Ticket", ticket)) + + ToString("Symbol", symbol) + + ToString("Period", period) + + ToString("Entry", entry) + + ToString("Provider", provider) + + ToString("Type", ToString(type)) + + ToString("Time", time) + + ToString("Pushers", pushers) + + (onlySignals + ? "" + : "-------------" + "\n" + + ToString("Volume", volume) + + ToString("Profit", profit) + + ToString("Commission", commission) + + ToString("Swap", swap) + + ToString("End Time", endTime) + + ToString("Age", age) + + ToString("Message", message)) + + "-------------" + "\n" + + "Conditions" + "\n" + + "-------------" + "\n" + + "-------------" + "\n" + + "CURRENT [" + ToString(cConditions.period) + "]" + "\n" + + "-------------" + "\n" + + cConditionsStr + "\n" + + "-------------" + "\n" + + "SHORT [" + ToString(sConditions.period) + "]" + "\n" + + "-------------" + "\n" + + sConditionsStr + "\n" + + "-------------" + "\n" + + "MEDIUM [" + ToString(mConditions.period) + "]" + "\n" + + "-------------" + "\n" + + mConditionsStr + "\n" + + "-------------" + "\n" + + "LONG [" + ToString(lConditions.period) + "]" + "\n" + + "-------------" + "\n" + + lConditionsStr + "\n" + + "-------------" + "\n" + + "HIND [" + ToString(hConditions.period) + "]" + "\n" + + "-------------" + "\n" + + hConditionsStr + "\n" + + // + "" + // + ; + + // + return result; + } + + // + // These are Some Helpers for Trading Controls and do not relate to Main + // purpose of Trade Handler ... + + // + // Supporting ... + + // + bool allowSupport; // Allow Support + + // + void ResetSupport() + { + allowSupport = false; + } + + // + // Retrieve Support Signal ... + bool HasSupport( + XSignal &support // + ) + { + // + bool result = false; + + // + return result; + } + + // + // Grid System Calculations ... + + // + int gLevel; // Number of Grids + bool allowGrid; // Allow Grid + double gEntry; // Represents Next Grid Signal's Entry + double gVolume; // Represent Next Grid Signal's Volume + + // + void ResetGrid() + { + // + gEntry = 0; + gLevel = 0; + gVolume = 0; + + // + allowGrid = false; + } + + // + void SetGrid( + double nextEntry, + double nextVolume // + ) + { + // + gEntry = nextEntry; + gVolume = nextVolume; + } + + // + // Prepare Data For Next Grid ... + void PrepareNextGrid( + double distance, + double volumeMultiplier // + ) + { + // + bool isValid = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + bool isLong = IsLong(type); + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + double selectedEntry = + gEntry <= 0 + ? entry + : gEntry; + double selectedVolume = + gVolume <= 0 + ? volume + : gVolume; + + // + double nextEntry = + isLong + ? selectedEntry - distancePrice + : selectedEntry + distancePrice; + double nextVolume = selectedVolume * volumeMultiplier; + + // + SetGrid( + nextEntry, + nextVolume // + ); + } + + // + // Check if a Grid Signal Exists Prepared and + // Provide it ... + bool HasGrid( + XSignal &signal, // Result Signal + double distance, + double volumeMultiplier // + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = IsValid() && + allowGrid && + distance > 0 && + volumeMultiplier > 0; + if (!result) + { + return result; + } + + // + bool isLong = IsLong(type); + + // + ENUM_POSITION_TYPE gType = + isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double cEntry = GetEntry( + symbol, + gType // + ); + + // + result = + isLong + ? cEntry <= gEntry + : cEntry >= gEntry; + if (!result) + { + return result; + } + + // + result = signal.Prepare( + symbol, + provider, + period, + gType, + X_ORDER_MODE_MARKET, + cEntry, + gVolume, + 0, // SL ... + 0 // TP ... + ); + + // + if (result) + { + // + // set Support Token ... + string comment = GenerateSupportTag(ticket); + signal.comment = comment; + + // + PrepareNextGrid( + distance, + volumeMultiplier // + ); + + // + gLevel++; + } + + // + return result; + } + + // + // Recovery Zone System ... + + // + bool allowRecover; // Allow Recover + ENUM_POSITION_TYPE rLastRecoveryType; // Last Executed Recovery Signal's Type + double rLongEntry; // Represent Next Recovery Long Signal's Entry + double rShortEntry; // Represent Next Recovery Short Signal's Entry + double rVolume; // Represent Next Recovery Signal's Volume + double rZoneUpper; // Zone Recovery Upper Bound + double rZoneLower; // Zone Recovery Lower Bound + int rLevel; // Number of Recoveries + + // + void ResetRecovery() + { + // + rLevel = 0; + rVolume = 0; + rLongEntry = 0; + rZoneUpper = 0; + rZoneLower = 0; + rShortEntry = 0; + + // + allowRecover = false; + } + + // + void SetRecovery( + double nextLongEntry, + double nextShortEntry, + double zoneUpper, + double zoneLower, + double nextVolume // + ) + { + // + rVolume = nextVolume; + rZoneUpper = zoneUpper; + rZoneLower = zoneLower; + rLongEntry = nextLongEntry; + rShortEntry = nextShortEntry; + } + + // + void PrepareNextRecovery( + double distance, // Define Target Based On Zones + double volumeMultiplier, // Volume Multiplier + ENUM_POSITION_TYPE lastType // Last Type + ) + { + // + bool isValid = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + + // + bool isLong = IsLong(lastType); + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + double selectedEntry = + isLong + ? rLongEntry <= 0 + ? entry + : rLongEntry + : rShortEntry <= 0 + ? entry + : rShortEntry; + double selectedVolume = + rVolume <= 0 + ? volume + : rVolume; + + // + double nextLongEntry = + isLong + ? selectedEntry + : selectedEntry + distancePrice; + double nextShortEntry = + isLong + ? selectedEntry - distancePrice + : selectedEntry; + + // + double nextVolume = selectedVolume * volumeMultiplier; + // rLevel % 2 == 1 + // ? volume + // : volume * volumeMultiplier; + + // + double zoneUpper = + rZoneUpper > 0 + ? rZoneUpper + : isLong + ? entry + distancePrice + : entry + (distancePrice * 2); + double zoneLower = + rZoneLower > 0 + ? rZoneLower + : isLong + ? entry + (distancePrice * 2) + : entry - distancePrice; + + // + SetRecovery( + nextLongEntry, + nextShortEntry, + zoneUpper, + zoneLower, + nextVolume // + ); + + // + rLastRecoveryType = lastType; + } + + // + // Check if a Recovery Signal Exists Prepared and + // Provide it ... + bool HasRecovery( + XSignal &signal, // Result Signal ... + double distance, + double volumeMultiplier // + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + allowRecover && + volumeMultiplier > 0 + // + ; + if (!result) + { + return result; + } + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + bool isLong = IsLong(type); + bool isLastLong = IsLong(rLastRecoveryType); + + // + // Check For Long Recovery ... + double cLongEntry = GetEntry( + symbol, + POSITION_TYPE_BUY // + ); + bool hasLongRecovery = + !isLastLong && + rLongEntry > 0 && cLongEntry >= rLongEntry; + + // + // Check For Short Recovery ... + double cShortEntry = GetEntry( + symbol, + POSITION_TYPE_SELL // + ); + bool hasShortRecovery = + isLastLong && + rShortEntry > 0 && + cShortEntry <= rShortEntry; + + // + result = hasLongRecovery || hasShortRecovery; + if (!result) + { + return result; + } + + // + ENUM_POSITION_TYPE rType = + hasLongRecovery + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double rEntry = + hasLongRecovery + ? cLongEntry + : cShortEntry; + + // + double rTP = + hasLongRecovery + ? rZoneUpper + : rZoneLower; + + // + double rSL = + hasLongRecovery + ? rZoneLower + : rZoneUpper; + + // + result = signal.Prepare( + symbol, + provider, + period, + rType, + X_ORDER_MODE_MARKET, + rEntry, + rVolume, + 0, // rSL, // SL ... + 0 // rTP // TP ... + ); + if (result) + { + // + // set Support Token ... + string comment = GenerateSupportTag(ticket); + signal.comment = comment; + + // + rLevel++; + + // + PrepareNextRecovery( + distance, + volumeMultiplier, + rType // + ); + } + + // + return result; + } +}; + +// +// a Class For Read and Write Trade Info Data in Files ... +class XTradeInfoCollector +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XTradeInfoCollector( + string _path = NULL // Base Path + ) + { + // + mAccount = new XSCAccount(); + + // + if (IsValid(_path)) + { + mPath = _path; + } + else + { + mPath = "XTradeInfo" + "\\" + mAccount.GetCompany(); + } + } + + // + // Deconstructor ... + void ~XTradeInfoCollector() {} + + // + bool IsExists(XTradeInfo &item) + { + // + bool result = false; + + // + int mHandler = GetFileHandlerForRead(item); + result = mHandler != INVALID_HANDLE; + FileClose(mHandler); + + // + return result; + } + + // + bool Save(XTradeInfo &item) + { + // + bool result = false; + + // + // Check info is Valid ... + result = item.IsValid(); + if (!result) + { + return result; + } + + // + string content = item.ToString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + int mHandler = GetFileHandlerForWrite(item); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + bool SaveSignal(XTradeInfo &item) + { + // + bool result = false; + + // + string content = item.ToString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + int mHandler = GetSignalFileHandlerForWrite(item); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + string mPath; // Base Path ... + + // + XSCAccount *mAccount; + + // + string GetFilePath(XTradeInfo &item) + { + // + string fileName = item.GetFileName(); + + // + return GetFilePath(fileName); + } + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + "Trades" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + string GetSignalFilePath(XTradeInfo &item) + { + // + string fileName = item.GetSignalFileName(); + + // + return GetSignalFilePath(fileName); + } + string GetSignalFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + "Signals" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + int GetFileHandlerForRead(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_TXT // + ); + + // + return result; + } + int GetFileHandlerForWrite(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } + + // + int GetSignalFileHandlerForRead(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetSignalFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_TXT // + ); + + // + return result; + } + int GetSignalFileHandlerForWrite(XTradeInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetSignalFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } +}; + +// +// a Class for Holding all required data for Specified Trade +// such as: +// - Signal; +// - Position; +// - Conditions; +// - Scores; +// - etc ... +class XTradeHandler +{ + // +public: + // + // Props ... + + // + // Constructor ... + void XTradeHandler( + XSCTrade *trade // an Instance of Trader Class + ) + { + // + Clean(data); + SetSave(false); + mTrader = trade; + collector = new XTradeInfoCollector(); + } + + // + // Getter(s) / Setter(s) ... + + // + // Others ... + + // + bool GetSave() + { + return mSave; + } + + // + void SetSave(bool value) + { + mSave = value; + } + + // + bool GetSaveSignalsOnly() + { + return mSaveSignalsOnly; + } + + // + void SetSaveSignalsOnly(bool value) + { + mSaveSignalsOnly = value; + } + + // + // Hedging ... + + // + double MinProfitPerTrade() + { + return mMinProfitPerTrade; + } + + // + void MinProfitPerTrade(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinProfitPerTrade = value; + } + + // + double MinProfitPerVolumeFactor() + { + return mMinProfitPerVolumeFactor; + } + + // + void MinProfitPerVolumeFactor(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + if (value > 0 && value < 0.01) + { + value = 0.01; + } + + // + mMinProfitPerVolumeFactor = value; + } + + // + // Trailling Stop ... + + // + bool AllowTrailStop() + { + return mAllowTrailStop; + } + + // + void AllowTrailStop(bool value) + { + mAllowTrailStop = value; + } + + // + bool DisableTrailingWhenOpposit() + { + return mDisableTrailingWhenOpposit; + } + + // + void DisableTrailingWhenOpposit(bool value) + { + mDisableTrailingWhenOpposit = value; + } + + // + double NextTrailPoint() + { + return mNextTrailPoint; + } + + // + void NextTrailPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mNextTrailPoint = value; + } + + // + double FirstTrailPoint() + { + return mFirstTrailPoint; + } + + // + void FirstTrailPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mFirstTrailPoint = value; + } + + // + double NextTrailDistance() + { + return mNextTrailDistance; + } + + // + void NextTrailDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mNextTrailDistance = value; + } + + // + double FirstTrailDistance() + { + return mFirstTrailDistance; + } + + // + void FirstTrailDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mFirstTrailDistance = value; + } + + // + bool EnableTrailling() + { + // + bool result = false; + + // + result = + // + AllowTrailStop() && + NextTrailPoint() > 0 && + FirstTrailPoint() > 0 && + NextTrailDistance() > 0 && + FirstTrailDistance() > 0 + // + ; + + // + return result; + } + + // + // Supporting ... + + // + bool AllowSupport() + { + return mAllowSupport; + } + + // + void AllowSupport(bool value) + { + mAllowSupport = value; + } + + // + bool SupportOnlyForces() + { + return mSupportOnlyForces; + } + + // + void SupportOnlyForces(bool value) + { + mSupportOnlyForces = value; + } + + // + double SupportDistance() + { + return mSupportDistance; + } + + // + void SupportDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mSupportDistance = value; + } + + // + int MaxNumberOfSupports() + { + return mMaxNumberOfSupports; + } + + // + void MaxNumberOfSupports(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfSupports = value; + } + + // + double SupportVolumeMultiplier() + { + return mSupportVolumeMultiplier; + } + + // + void SupportVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mSupportVolumeMultiplier = value; + } + + // + double MaxAllowedSupportVolume() + { + return mMaxAllowedSupportVolume; + } + + // + void MaxAllowedSupportVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedSupportVolume = value; + } + + // + bool EnableSupport() + { + // + bool result = false; + + // + result = + // + AllowSupport() && + SupportDistance() > 0 && + MaxNumberOfSupports() >= 0 && + SupportVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Grid ... + + // + bool AllowGrid() + { + return mAllowGrid; + } + + // + void AllowGrid(bool value) + { + mAllowGrid = value; + } + + // + bool GridOnlyForces() + { + return mGridOnlyForces; + } + + // + void GridOnlyForces(bool value) + { + mGridOnlyForces = value; + } + + // + int MaxNumberOfGrids() + { + return mMaxNumberOfGrids; + } + + // + void MaxNumberOfGrids(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfGrids = value; + } + + // + double GridDistance() + { + return mGridDistance; + } + + // + void GridDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mGridDistance = value; + } + + // + double GridVolumeMultiplier() + { + return mGridVolumeMultiplier; + } + + // + void GridVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mGridVolumeMultiplier = value; + } + + // + double MaxAllowedGridVolume() + { + return mMaxAllowedGridVolume; + } + + // + void MaxAllowedGridVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedGridVolume = value; + } + + // + // Check Grid Properties to Validate it's Enable or not ... + bool EnableGrid() + { + // + bool result = false; + + // + result = + // + AllowGrid() && + GridDistance() > 0 && + MaxNumberOfGrids() >= 0 && + GridVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Recovery System ... + + // + bool AllowRecovery() + { + return mAllowRecovery; + } + + // + void AllowRecovery(bool value) + { + mAllowRecovery = value; + } + + // + bool RecoverOnlyForces() + { + return mRecoverOnlyForces; + } + + // + void RecoverOnlyForces(bool value) + { + mRecoverOnlyForces = value; + } + + // + int MaxNumberOfRecoveries() + { + return mMaxNumberOfRecoveries; + } + + // + void MaxNumberOfRecoveries(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxNumberOfRecoveries = value; + } + + // + double RecoveryDistance() + { + return mRecoveryDistance; + } + + // + void RecoveryDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mRecoveryDistance = value; + } + + // + double RecoveryVolumeMultiplier() + { + return mRecoveryVolumeMultiplier; + } + + // + void RecoveryVolumeMultiplier(double value) + { + // + if (value < 1) + { + value = 1; + } + + // + mRecoveryVolumeMultiplier = value; + } + + // + double MaxAllowedRecoveryVolume() + { + return mMaxAllowedRecoveryVolume; + } + + // + void MaxAllowedRecoveryVolume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mMaxAllowedRecoveryVolume = value; + } + + // + // Check Recovery Properties to Validate it's Enable or not ... + bool EnableRecovery() + { + // + bool result = false; + + // + result = + // + AllowRecovery() && + RecoveryDistance() > 0 && + MaxNumberOfRecoveries() >= 0 && + RecoveryVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Tools ... + + // + int Count() + { + return ArraySize(data); + } + + // + int FindIndex(ulong ticket) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOwn = iInfo.IsOwn( + ticket // + ); + if (isOwn) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + int FindIndex(XSignal &signal) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOWN = + // + iInfo.time == signal.time && + iInfo.symbol == signal.symbol && + iInfo.volume == signal.volume && + iInfo.period == signal.period && + iInfo.provider == signal.provider && + iInfo.type == ToPositionType(signal.type) + // + ; + + // + if (isOWN) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void Add( + XSignal &signal, + int pushers, + bool allowGrid, + bool allowRecover, + bool allowSupport, + X121SetupConditions &cConditions, + X121SetupConditions &sConditions, + X121SetupConditions &mConditions, + X121SetupConditions &lConditions, + X121SetupConditions &hConditions // + ) + { + // + XTradeInfo info; + bool isFilled = info.Fill( + signal, + pushers, + allowGrid, + allowRecover, + allowSupport, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); + if (!isFilled) + { + return; + } + + // + AddRef( + info, + data // + ); + + // + if (GetSaveSignalsOnly()) + { + collector.SaveSignal(info); + } + } + + // + void Remove(XSignal &signal) + { + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + ArrayRemove( + data, + infoIDX, + 1 // + ); + } + + // + void Update(XSignal &signal) + { + // + if (!signal.IsValid() || !signal.IsExecuted()) + { + return; + } + + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].ticket = signal.positionId; + + // + // Find Orders for Accessing Commission ... + XDeal deals[]; + int dealsCount = mTrader.GetDeals( + deals, + signal.symbol, + signal.provider, + signal.period, + NULL, + DEAL_ENTRY_IN // Position Open Deal ... + ); + if (!IsValidSize(dealsCount)) + { + return; + } + + // + for (int i = 0; i < dealsCount; i++) + { + // + XDeal iDeal = deals[i]; + + // + if (iDeal.positionId == signal.positionId) + { + data[infoIDX].commission = iDeal.commission; + } + } + + // + // Check if Grid System Enable or Not ... + if (EnableGrid()) + { + // + // Here we Prepare Handler Structure for + // Next Grid Position ... + data[infoIDX].PrepareNextGrid( + GridDistance(), + GridVolumeMultiplier() // + ); + } + + // + // Check if Recovery System Enable or Not ... + if (EnableRecovery()) + { + // + data[infoIDX].PrepareNextRecovery( + GridDistance(), + GridVolumeMultiplier(), + signal.type // + ); + } + } + + // + void Update(XDeal &deal) + { + // + if (!deal.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(deal.positionId); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = deal.swap; + data[infoIDX].endTime = deal.time; + data[infoIDX].profit = deal.profit; + + // + string message = deal.reason == DEAL_REASON_TP + ? "TP" + : "SL"; + data[infoIDX].message = message; + + // + Finish(infoIDX); + } + + // + void Update(XPosition &position) + { + // + if (!position.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(position.ticket); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = position.swap; + data[infoIDX].endTime = TimeCurrent(); + data[infoIDX].profit = position.profit; + data[infoIDX].message = position.comment; + + // + Finish(infoIDX); + } + + // + bool AllowToGrid( + XSignal &signal // + ) + { + // + bool result = false; + + // + int count = Count(); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + int infoIDX = FindIndex(signal); + result = IsValidIndex(infoIDX); + if (!result) + { + return result; + } + + // + data[infoIDX].allowGrid = true; + data[infoIDX].PrepareNextGrid( + GridDistance(), + GridVolumeMultiplier() // + ); + + // + return result; + } + + // + bool AllowToRecovery( + XSignal &signal // + ) + { + // + bool result = false; + + // + int count = Count(); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + int infoIDX = FindIndex(signal); + result = IsValidIndex(infoIDX); + if (!result) + { + return result; + } + + // + data[infoIDX].allowRecover = true; + data[infoIDX].PrepareNextRecovery( + GridDistance(), + GridVolumeMultiplier(), + signal.type // + ); + + // + return result; + } + + // + // Sync ... + void Sync() + { + // + int count = Count(); + if (!IsValidSize(count)) + { + return; + } + + // + int mustRemoved[]; + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + if (iInfo.ticket > 0 && !mTrader.IsOpen(iInfo.ticket)) + { + // + AddSpecific( + i, + mustRemoved // + ); + } + } + + // + int mustRemovedCount = ArraySize(mustRemoved); + if (!IsValidSize(mustRemovedCount)) + { + return; + } + + // + for (int i = 0; i < mustRemovedCount; i++) + { + // + ArrayRemove( + data, + i, + 1 // + ); + } + } + + // + // Protection Handlers ... + + // + // Handle Do All Protecting ... + int DoProtect( + XSignal &signals[], // if PRotecting Generate Some Support Signals, Holds them here + XSCX121SetupCycles *&setups[] // Number of Setups + ) + { + // + int result = 0; + + // + // Calling Protection Algorithms ... + + // + // Trailling ... + if (EnableTrailling()) + { + int traillings = HandleTrailling(); + } + + // + if (AllowSupport()) + { + // + XSignal supports[]; + int supportsCount = RequestForSupport( + supports, + setups // + ); + + // + if (IsValidSize(supportsCount)) + { + // + Copy( + supports, + signals, + false // + ); + } + } + + // + // Grid ... + if (EnableGrid()) + { + // + XSignal grids[]; + int gridsCount = RequestForGrid(grids); + if (IsValidSize(gridsCount)) + { + // + Copy( + grids, + signals, + false // + ); + } + } + + // + // Recovery ... + if (EnableRecovery()) + { + // + XSignal recoveries[]; + int recoveriesCount = RequestForRecovery(recoveries); + if (IsValidSize(recoveriesCount)) + { + // + Copy( + recoveries, + signals, + false // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int GetBreakoutsSignals(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + double iEntry = data[i].entry; + string iSymbol = data[i].symbol; + ENUM_TIMEFRAMES iPeriod = data[i].period; + ENUM_X_POSITION_TYPES iType = data[i].type; + + // + bool isLong = IsLong(iType); + ENUM_POSITION_TYPE iPType = isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double cEntry = GetEntry( + iSymbol, + iPType // + ); + + // + XOHCL cBar; + bool isInited = cBar.Init( + iSymbol, + iPeriod, + 1 // + ); + if (!isInited) + { + continue; + } + + // + bool isBullish = cBar.IsBullish(); + bool isBreakUp = cBar.IsBreakUp(iEntry); + + // + bool isBearish = cBar.IsBearish(); + bool isBreakDown = cBar.IsBreakDown(iEntry); + + // + bool isBreaked = + isLong + ? isBullish && isBreakUp && cEntry > iEntry + : isBearish && isBreakDown && cEntry < iEntry; + + // + if (isBreaked) + { + // + // Update Date of TradeInfo ... + data[i].entry = cEntry; + data[i].time = TimeCurrent(); + + // + // Generate Signal ... + XSignal iSignal; + bool isPrepared = iSignal.Prepare( + data[i].symbol, + data[i].provider, + data[i].period, + iPType, + X_ORDER_MODE_MARKET, + data[i].entry, + data[i].volume, + 0, + 0 // + ); + + // + // Add Signal to Result ... + if (isPrepared) + { + // + AddRef( + iSignal, + signals // + ); + } + } + + // // + // double hotLevels[]; + + // // + // AddSpecific( + // 0.25, + // hotLevels // + // ); + + // // + // AddSpecific( + // 0.20, + // hotLevels // + // ); + + // // + // AddSpecific( + // 0.12, + // hotLevels // + // ); + + // // + // XSCZonesInput zonesInput; + // zonesInput.length = 71; + // zonesInput.numberOfZones = 10; + // XSCZones *zones = new XSCZones( + // iSymbol, + // _Period // + // ); + + // // + // zonesInput.AddLevelColor( + // hotLevels[0], + // clrRed // + // ); + // zonesInput.AddLevelColor( + // hotLevels[1], + // clrOrange // + // ); + // zonesInput.AddLevelColor( + // hotLevels[2], + // clrLightCoral // + // ); + // bool canUseZones = zones.Init(zonesInput); + + // // + // XSCCFInput cfInputs; + // cfInputs.Default(); + // XSCCF *cf = new XSCCF( + // iSymbol, + // _Period // + // ); + // bool canUseCF = cf.Init(cfInputs); + + // // + // XSCTrendInput tInputs; + // tInputs.Default(); + // XSCTrend *trend = new XSCTrend( + // iSymbol, + // _Period // + // ); + // bool canUseTrend = trend.Init(tInputs); + + // if (canUseCF && canUseTrend && canUseZones) + // { + // // + // // cf.Draw(); + // trend.Draw(); + // // zones.Draw(); + // Print("Use CF ..."); + // // cf.Remove(); + // // trend.Remove(); + // // zones.Remove(); + // } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + XSCTrade *mTrader; + XTradeInfo data[]; + XTradeInfoCollector *collector; + + // + bool mSave; // Save Results ... + bool mSaveSignalsOnly; // Save Only Signals and COnditions + + // + // Hedging ... + double mMinProfitPerTrade; // Minimum Required Profit for Hedging + double mMinProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Volume + + // + // Trailling ... + bool mAllowTrailStop; // Enable Trailling Stop Losses + bool mDisableTrailingWhenOpposit; // Disable Trailling When has Opposite In Drawdown + double mNextTrailPoint; // Next Trailling Step + double mFirstTrailPoint; // First Stop Trail + double mFirstTrailDistance; // Start Trailling Distance + double mNextTrailDistance; // Next Trailling Distance + + // + // Supporting ... + bool mAllowSupport; // Allow Support Signals + bool mSupportOnlyForces; // Support Only Force Signals + double mSupportDistance; // Supporting Distance + int mMaxNumberOfSupports; // Max Number of Support Signals + double mSupportVolumeMultiplier; // Support Signals Volume Multiplier + double mMaxAllowedSupportVolume; // Max Allowed Support Signals Volume + + // + // Grid ... + bool mAllowGrid; // Allow Grid Signals + bool mGridOnlyForces; // Grid Only Force Signals + int mMaxNumberOfGrids; // Max Number of Grid Signals + double mGridDistance; // Grid Distance + double mGridVolumeMultiplier; // Grid Volume Multiplier + double mMaxAllowedGridVolume; // Max Allowed Grid Signals Volume + + // + // Recovery ... + bool mAllowRecovery; // Allow Recovery Signals + bool mRecoverOnlyForces; // Recover Only Force Signals + int mMaxNumberOfRecoveries; // Max Number of Recovery Signals + double mRecoveryDistance; // Recovery Distance + double mRecoveryVolumeMultiplier; // Recovery Volume Multiplier + double mMaxAllowedRecoveryVolume; // Max Allowed Recovery Signals Volume + + // + // Tools ... + + // + void Finish(int index) + { + // + XTradeInfo info = data[index]; + if (!info.IsValid()) + { + return; + } + + // + ArrayRemove( + data, + index, + 1 // + ); + + // + if (GetSave()) + { + collector.Save(info); + } + } + + // + // Protection Methods ... + + // + int HandleTrailling() + { + // + int result = 0; + + // + // Check Trailling is Enabled or not ... + if (!EnableTrailling()) + { + return result; + } + + // + // Do Synch Before Start Trailing ... + Sync(); + + // + // Since Trailing Done based On In Profit Positions ... + // First we Check if ... + XPosition positions[]; + XPosition inDPositions[]; + XPosition inPPositions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return result; + } + + // + int inDPositionsCount = ExtractInDrawdownPositions( + positions, + inDPositions // + ); + int inPPositionsCount = ExtractInProfitPositions( + positions, + inPPositions // + ); + if (!IsValidSize(inPPositionsCount)) + { + return result; + } + + // + for (int i = 0; i < inPPositionsCount; i++) + { + // + XPosition iPosition = inPPositions[i]; + + // + // ignore Support Positions ... + bool isSupport = IsSupport(iPosition.comment); + if (isSupport) + { + continue; + } + + // + // Only Trail Positions which they Hasnt any Support ... + bool hasSupport = mTrader.HasSupport(iPosition.ticket); + result = !hasSupport; + if (!result) + { + return result; + } + + // + // Find Positin Info Index ... + int idx = FindIndex(iPosition.ticket); + if (!IsValidIndex(idx)) + { + continue; + } + + // + bool isLong = IsLong(iPosition.type); + + // + // Here we Select Price for SL Trailling ... + double usedPrice = 0; + if (iPosition.sl != 0) + { + // + if (isLong) + { + // + if (iPosition.sl < iPosition.entry) + { + usedPrice = iPosition.entry; + } + else + { + usedPrice = iPosition.sl; + } + } + else + { + // + if (iPosition.sl > iPosition.entry) + { + usedPrice = iPosition.entry; + } + else + { + usedPrice = iPosition.sl; + } + } + } + else + { + usedPrice = iPosition.entry; + } + + // + double nextTrailPoint = NextTrailPoint(); + double firstTrailPoint = FirstTrailPoint(); + double nextTrailDistance = NextTrailDistance(); + double firstTrailDistance = FirstTrailDistance(); + + // + bool isFirstTrail = usedPrice == iPosition.entry; + + // + double usedTrailDiff = + isFirstTrail + ? MathMax(firstTrailPoint, firstTrailDistance) + : MathMax(nextTrailPoint, nextTrailDistance); + + // + double iExit = GetExit( + iPosition.symbol, + iPosition.type // + ); + double iPriceDistance = MathAbs(usedPrice - iExit); + double iPriceDistanceInPoint = PriceToPoint( + iPriceDistance, + iPosition.symbol // + ); + + // + bool canTrail = iPriceDistanceInPoint >= usedTrailDiff; + if (!canTrail) + { + continue; + } + + // + // Check Opposit Side Position ... + // if Exists, dont Trail ... + if (DisableTrailingWhenOpposit() && IsValidSize(inDPositionsCount)) + { + // + bool canTrail = true; + ENUM_POSITION_TYPE oppositType = GetOpposit(iPosition.type); + for (int j = 0; j < inDPositionsCount; j++) + { + // + XPosition inDPosition = inDPositions[j]; + + // + bool isOpposit = + inDPosition.symbol == iPosition.symbol && + inDPosition.type == oppositType; + if (isOpposit) + { + // + canTrail = false; + break; + } + } + + // + if (!canTrail) + { + continue; + } + } + + // + usedTrailDiff = + isFirstTrail + ? MathMin(firstTrailPoint, firstTrailDistance) + : MathMin(nextTrailPoint, nextTrailDistance); + double usedTrailDiffPrice = PointToPrice( + usedTrailDiff, + iPosition.symbol // + ); + + // + double sl = + isLong + ? usedPrice + usedTrailDiffPrice + : usedPrice - usedTrailDiffPrice; + string comment = PrepareSLTrailTag(iPosition.comment); + + // + bool isModified = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp, + comment // + ); + if (isModified) + { + result++; + } + } + + // + return result; + } + + // + int RequestForSupport( + XSignal &signals[], + XSCX121SetupCycles *&setups[] // + ) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!AllowSupport()) + { + return result; + } + + // + Sync(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSignal iSupport; + double iPivot = -1; + int iPivotIDX = -1; + bool hasSupport = data[i].HasSupport( + iSupport // + ); + if (hasSupport) + { + // + AddRef( + iSupport, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + // TODO: Complete this Later ... + return result; + + // + // Validate Setups Count ... + // int setupsCount = ArraySize(setups); + // if (!IsValidSize(setupsCount)) + // { + // return result; + // } + + // // + // // Implement Supporting Mechanism ... + + // // + // // Extracting In Drawdown Positions ... + // XPosition positions[]; + // int positionsCount = mTrader.GetInDrawdownPositions( + // positions // + // ); + // if (!IsValidSize(positionsCount)) + // { + // return result; + // } + + // // + // double supportDistance = SupportDistance(); + // int maxNUmberOfSupports = MaxNumberOfSupports(); + // double maxAllowedVolume = MaxAllowedSupportVolume(); + // double volumeMultiplier = SupportVolumeMultiplier(); + + // // + // X121SignalGenerator signalGenerator; + + // // + // for (int i = 0; i < positionsCount; i++) + // { + // // + // XPosition iPosition = positions[i]; + + // // + // // Check Position is not Support Position ... + // bool isSupport = IsSupport(iPosition.comment); + // if (isSupport) + // { + // continue; + // } + + // // + // // Find Related Setp ... + // int idx = FindSetupIndex( + // iPosition.symbol, + // setups // + // ); + // if (!IsValidIndex(idx)) + // { + // continue; + // } + + // // + // int index = FindIndex(iPosition.ticket); + // if (!IsValidIndex(index)) + // { + // continue; + // } + + // // + // // Check Position must atleast 20 Point in drawdown ... + + // // + // double onePointPrice = PointToPrice( + // 1, + // iPosition.symbol // + // ); + + // // + // double iExitPrice = GetExit( + // iPosition.symbol, + // iPosition.type // + // ); + + // // + // double priceDiff = MathAbs(iPosition.entry - iExitPrice); + // double priceDiffPoints = priceDiff / onePointPrice; + + // // + // bool isFarEnough = priceDiffPoints >= (supportDistance / 2); + // if (!isFarEnough) + // { + // continue; + // } + + // // + // // Check Support COunts and etc ... + // // implementing supporting mechanis ... + + // // + // } + + // // + // result = ArraySize(signals); + + // + return result; + } + + // + int RequestForGrid(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!EnableGrid()) + { + return result; + } + + // + int maxAllowed = MaxNumberOfGrids(); + double maxAllowedVolume = MaxAllowedGridVolume(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + // Check Count ... + bool isMaxPassed = + maxAllowed <= 0 + ? true + : data[i].gLevel < maxAllowed; + if (!isMaxPassed) + { + continue; + } + + // + XSignal iSignal; + bool hasGrid = data[i].HasGrid( + iSignal, + GridDistance(), + GridVolumeMultiplier() // + ); + + // + if (hasGrid) + { + // + // Check Max Volume ... + iSignal.volume = + maxAllowedVolume <= 0 + ? iSignal.volume + : MathMin(iSignal.volume, maxAllowedVolume); + + // + AddRef( + iSignal, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int RequestForRecovery(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!EnableRecovery()) + { + return result; + } + + // + int maxAllowed = MaxNumberOfRecoveries(); + double maxAllowedVolume = MaxAllowedRecoveryVolume(); + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + // Check Count ... + bool isMaxPassed = + maxAllowed <= 0 + ? true + : data[i].rLevel < maxAllowed; + if (!isMaxPassed) + { + continue; + } + + // + XSignal iSignal; + bool hasRecovery = data[i].HasRecovery( + iSignal, + RecoveryDistance(), + RecoveryVolumeMultiplier() // + ); + + // + if (hasRecovery) + { + // + // Check Max Volume ... + iSignal.volume = + maxAllowedVolume <= 0 + ? iSignal.volume + : MathMin(iSignal.volume, maxAllowedVolume); + + // + AddRef( + iSignal, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + int FindSetupIndex( + string symbol, + XSCX121SetupCycles *&setups[] // + ) + { + // + int result = 0; + + // + if (!IsValid(symbol)) + { + return result; + } + + // + for (int i = 0; i < ArraySize(setups); i++) + { + // + if (setups[i].GetSymbol() == symbol) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void AddHotLevelsToZones( + XSCZones *zones // + ) + { + // + zones.AddLevelColor( + 0.25, + clrRed // + ); + zones.AddLevelColor( + 0.20, + clrOrange // + ); + zones.AddLevelColor( + 0.15, + clrYellow // + ); + } +}; + +// +// Class ... +class XSCX121SetupEA : public XSCBaseEA +{ + // + // Public ... +public: + // + // Props ... + X121SignalGenerator signalGenerator; + + // + // Constructors ... + XSCX121SetupEA( + // + // XTrade Class Requirements ... + int slippage, // Specify Slippage + ulong magicNumber, // Specify Magic Number + // + // XSCTrade Event Handlers ... + TOnSignal onSignal = NULL, // On Signal Recieved Event Handler + TOnModify onModifyPosition = NULL, // On Modify Position Event Handler + TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler + TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler + TOnForceClose onForceClosePosition = NULL, // On Force Close Position Event Handler + TOnPartialClose onPartialClosePosition = NULL, // On Partial Close Position Event Handler + TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler + TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler + TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler + TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler + ) : XSCBaseEA(slippage, + magicNumber, + onSignal, + onModifyPosition, + onStopLossTriggered, + onTakeProfitTriggered, + onForceClosePosition, + onPartialClosePosition, + onDealsChangedHandler, + onOrdersChangedHandler, + onPositionsChangedHandler, + onTradeStateChangedHandler // + ) + { + // + mTradeHandler = new XTradeHandler(mTrader); + + // + // Implement Default Configs ... + DefaultConfigs(); + } + + // + // Deconstructor ... + ~XSCX121SetupEA() + { + // + delete mTradeHandler; + + // + Clean(mSetups); + } + + // + bool AddSetup(XSCX121SetupCycles *setup) + { + // + bool result = false; + + // + result = setup != NULL; + if (!result) + { + return result; + } + + // + Add( + setup, + mSetups // + ); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + /// Signals ... + + // + bool AllowLong() + { + return mAllowLong; + } + + // + void AllowLong(bool value) + { + mAllowLong = value; + } + + // + bool AllowShort() + { + return mAllowShort; + } + + // + void AllowShort(bool value) + { + mAllowShort = value; + } + + // + int DelayBetweenTwoSignal() + { + return mDelayBetweenTwoSignal; + } + + // + void DelayBetweenTwoSignal(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mDelayBetweenTwoSignal = value; + } + + // + int ReuiredSignalVerifications() + { + return mReuiredSignalVerifications; + } + + // + void ReuiredSignalVerifications(int value) + { + // + if (value < 1) + { + value = 1; + } + + // + mReuiredSignalVerifications = value; + } + + // + bool GetVerificationFromOtherTimeFrames() + { + return mGetVerificationFromOtherTimeFrames; + } + + // + void GetVerificationFromOtherTimeFrames(bool value) + { + mGetVerificationFromOtherTimeFrames = value; + } + + // + bool ExecuteSignalsOnBreakout() + { + return mExecuteSignalsOnBreakout; + } + + // + void ExecuteSignalsOnBreakout(bool value) + { + mExecuteSignalsOnBreakout = value; + } + + // + // Risk Management ... + + // + double Volume() + { + return mVolume; + } + + // + void Volume(double value) + { + // + if (value < 0.01) + { + value = 0.01; + } + + // + mVolume = value; + } + + // + double TPPoint() + { + return mTPPoint; + } + + // + void TPPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mTPPoint = value; + } + + // + double SLPoint() + { + return mSLPoint; + } + + // + void SLPoint(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mSLPoint = value; + } + + // + int MaxAllowedTrades() + { + return mMaxAllowedTrades; + } + + // + void MaxAllowedTrades(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedTrades = value; + // mTrader.SetMaxAllowedPositions(value); + } + + // + bool UseMaxAllowedPerDirection() + { + return mUseMaxAllowedPerDirection; + } + + // + void UseMaxAllowedPerDirection(bool value) + { + mUseMaxAllowedPerDirection = value; + } + + // + bool IgnoreTP() + { + return mIgnoreTP; + } + + // + void IgnoreTP(bool value) + { + mIgnoreTP = value; + } + + // + bool IgnoreSL() + { + return mIgnoreSL; + } + + // + void IgnoreSL(bool value) + { + mIgnoreSL = value; + } + + // + // Signalling ... + + // + int StartSignallingHoure() + { + return mStartSignallingHoure; + } + + // + void StartSignallingHoure(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mStartSignallingHoure = value; + } + + // + int EndSignallingHoure() + { + return mEndSignallingHoure; + } + + // + void EndSignallingHoure(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mEndSignallingHoure = value; + } + + // + int CloseOnSpecificTime() + { + return mCloseOnSpecificTime; + } + + // + void CloseOnSpecificTime(int value) + { + // + if (value < -1) + { + value = -1; + } + + // + mCloseOnSpecificTime = value; + } + + // + bool CloseOnOpposit() + { + return mCloseOnOpposit; + } + + // + void CloseOnOpposit(bool value) + { + mCloseOnOpposit = value; + } + + // + // Trailling ... + + // + bool AllowTrailStop() + { + return mTradeHandler.AllowTrailStop(); + } + + // + void AllowTrailStop(bool value) + { + mTradeHandler.AllowTrailStop(value); + } + + // + bool DisableTrailingWhenOpposit() + { + return mTradeHandler.DisableTrailingWhenOpposit(); + } + + // + void DisableTrailingWhenOpposit(bool value) + { + mTradeHandler.DisableTrailingWhenOpposit(value); + } + + // + double NextTrailPoint() + { + return mTradeHandler.NextTrailPoint(); + } + + // + void NextTrailPoint(double value) + { + mTradeHandler.NextTrailPoint(value); + } + + // + double FirstTrailPoint() + { + return mTradeHandler.FirstTrailPoint(); + } + + // + void FirstTrailPoint(double value) + { + mTradeHandler.FirstTrailPoint(value); + } + + // + double NextTrailDistance() + { + return mTradeHandler.NextTrailDistance(); + } + + // + void NextTrailDistance(double value) + { + mTradeHandler.NextTrailDistance(value); + } + + // + double FirstTrailDistance() + { + return mTradeHandler.FirstTrailDistance(); + } + + // + void FirstTrailDistance(double value) + { + mTradeHandler.FirstTrailDistance(value); + } + + // + // Supporting ... + + // + bool AllowSupport() + { + return mTradeHandler.AllowSupport(); + } + + // + void AllowSupport(bool value) + { + mTradeHandler.AllowSupport(value); + } + + // + bool SupportOnlyForces() + { + return mTradeHandler.SupportOnlyForces(); + } + + // + void SupportOnlyForces(bool value) + { + mTradeHandler.SupportOnlyForces(value); + } + + // + bool EnableSupport() + { + return mTradeHandler.EnableSupport(); + } + + // + double SupportDistance() + { + return mTradeHandler.SupportDistance(); + } + + // + void SupportDistance(double value) + { + mTradeHandler.SupportDistance(value); + } + + // + int MaxNumberOfSupports() + { + return mTradeHandler.MaxNumberOfSupports(); + } + + // + void MaxNumberOfSupports(int value) + { + mTradeHandler.MaxNumberOfSupports(value); + } + + // + double SupportVolumeMultiplier() + { + return mTradeHandler.SupportVolumeMultiplier(); + } + + // + void SupportVolumeMultiplier(double value) + { + mTradeHandler.SupportVolumeMultiplier(value); + } + + // + double MaxAllowedSupportVolume() + { + return mTradeHandler.MaxAllowedSupportVolume(); + } + + // + void MaxAllowedSupportVolume(double value) + { + mTradeHandler.MaxAllowedSupportVolume(value); + } + + // + // Grid ... + + // + bool AllowGrid() + { + return mTradeHandler.AllowGrid(); + } + + // + void AllowGrid(bool value) + { + mTradeHandler.AllowGrid(value); + } + + // + bool GridOnlyForces() + { + return mTradeHandler.GridOnlyForces(); + } + + // + void GridOnlyForces(bool value) + { + mTradeHandler.GridOnlyForces(value); + } + + // + bool EnableGrid() + { + return mTradeHandler.EnableGrid(); + } + + // + int MaxNumberOfGrids() + { + return mTradeHandler.MaxNumberOfGrids(); + } + + // + void MaxNumberOfGrids(int value) + { + mTradeHandler.MaxNumberOfGrids(value); + } + + // + double GridDistance() + { + return mTradeHandler.GridDistance(); + } + + // + void GridDistance(double value) + { + mTradeHandler.GridDistance(value); + } + + // + double GridVolumeMultiplier() + { + return mTradeHandler.GridVolumeMultiplier(); + } + + // + void GridVolumeMultiplier(double value) + { + mTradeHandler.GridVolumeMultiplier(value); + } + + // + double MaxAllowedGridVolume() + { + return mTradeHandler.MaxAllowedGridVolume(); + } + + // + void MaxAllowedGridVolume(double value) + { + mTradeHandler.MaxAllowedGridVolume(value); + } + + // + // Recovery System ... + + // + bool AllowRecovery() + { + return mTradeHandler.AllowRecovery(); + } + + // + void AllowRecovery(bool value) + { + mTradeHandler.AllowRecovery(value); + } + + // + bool RecoverOnlyForces() + { + return mTradeHandler.RecoverOnlyForces(); + } + + // + void RecoverOnlyForces(bool value) + { + mTradeHandler.RecoverOnlyForces(value); + } + + // + bool EnableRecovery() + { + return mTradeHandler.EnableRecovery(); + } + + // + int MaxNumberOfRecoveries() + { + return mTradeHandler.MaxNumberOfRecoveries(); + } + + // + void MaxNumberOfRecoveries(int value) + { + mTradeHandler.MaxNumberOfRecoveries(value); + } + + // + double RecoveryDistance() + { + return mTradeHandler.RecoveryDistance(); + } + + // + void RecoveryDistance(double value) + { + mTradeHandler.RecoveryDistance(value); + } + + // + double RecoveryVolumeMultiplier() + { + return mTradeHandler.RecoveryVolumeMultiplier(); + } + + // + void RecoveryVolumeMultiplier(double value) + { + mTradeHandler.RecoveryVolumeMultiplier(value); + } + + // + double MaxAllowedRecoveryVolume() + { + return mTradeHandler.MaxAllowedRecoveryVolume(); + } + + // + void MaxAllowedRecoveryVolume(double value) + { + mTradeHandler.MaxAllowedRecoveryVolume(value); + } + + // + // Others ... + + // + bool SaveResults() + { + return mTradeHandler.GetSave(); + } + + // + void SaveResults(bool value) + { + mTradeHandler.SetSave(value); + } + + // + bool SaveSignalsOnly() + { + return mTradeHandler.GetSaveSignalsOnly(); + } + + // + void SaveSignalsOnly(bool value) + { + mTradeHandler.SetSaveSignalsOnly(value); + } + + // + double MinFreeMargingForOpenTrades() + { + return mMinFreeMargingForOpenTrades; + } + + // + void MinFreeMargingForOpenTrades(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinFreeMargingForOpenTrades = value; + } + + // + // Hedging ... + + // + double MinProfitPerTrade() + { + return mTradeHandler.MinProfitPerTrade(); + } + + // + void MinProfitPerTrade(double value) + { + // + MinRequiredProfitPerTrade(value); + mTradeHandler.MinProfitPerTrade(value); + } + + // + double MinProfitPerVolumeFactor() + { + return mTradeHandler.MinProfitPerVolumeFactor(); + } + + // + void MinProfitPerVolumeFactor(double value) + { + // + MinRequiredProfitPerVolumeFactor(value); + mTradeHandler.MinProfitPerVolumeFactor(value); + } + + // + // Overrides ... + + // + // Customize Token ... + string GetToken() override + { + return GetSpecificToken(this); + } + + // + string GetTag() override + { + return this.GetToken(); + } + + // + // Tools ... + + // + // Check Provider for any Guards ... + bool CheckForGuard(XGuard &guards[]) override + { + // + bool result = false; + + // + return result; + } + + // + // Request Provider to Collect all + // Potentially Signals and then + // filters theme here and passed them + // for Executing ... + int RequestForSignal( + XSignal &signals[] // Holds Signals ... + ) override + { + // + bool result = 0; + + // + Clean(signals); + + // + if (!IsEnable()) + { + return result; + } + + // + // IMPLEMENT ... + int count = CountSetups(); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + // Current ... + double cTP = 0; + double cSL = 0; + XSignal cSignal; + int cPusher = 0; + bool cHasSignal = false; + string cProvider = NULL; + X121SetupConditions cConditions; + + // + // Short ... + double sTP = 0; + double sSL = 0; + XSignal sSignal; + int sPusher = 0; + bool sHasSignal = false; + string sProvider = NULL; + X121SetupConditions sConditions; + + // + // Medium ... + double mTP = 0; + double mSL = 0; + XSignal mSignal; + int mPusher = 0; + bool mHasSignal = false; + string mProvider = NULL; + X121SetupConditions mConditions; + + // + // Long ... + double lTP = 0; + double lSL = 0; + XSignal lSignal; + int lPusher = 0; + bool lHasSignal = false; + string lProvider = NULL; + X121SetupConditions lConditions; + + // + // Hind ... + double hTP = 0; + double hSL = 0; + XSignal hSignal; + int hPusher = 0; + bool hHasSignal = false; + string hProvider = NULL; + X121SetupConditions hConditions; + + // + bool canSupport = + // + EnableSupport() && + !SupportOnlyForces() + // + ; + bool canGrid = + // + EnableGrid() && + !GridOnlyForces() + // + ; + bool canRecover = + // + EnableRecovery() && + !RecoverOnlyForces() + // + ; + + // + double volume = Volume(); + double slPoint = SLPoint(); + double tpPoint = TPPoint(); + bool ignoreSL = IgnoreSL(); + bool ignoreTP = IgnoreTP(); + bool allowLong = AllowLong(); + bool allowShort = AllowShort(); + + // + bool useCMarket = true; + bool useSMarket = true; + bool useMMarket = true; + bool useLMarket = true; + bool useHMarket = true; + + // + for (int i = 0; i < count; i++) + { + // + // Current Market ... + + // + cPusher = 0; + cSignal.Clean(); + cProvider = NULL; + cHasSignal = false; + cConditions.Clean(); + + // + cHasSignal = !useCMarket + ? false + : mSetups[i] + .ProcessMarket( + cSignal, + cConditions, + cPusher, + cProvider, + cTP, + cSL, + X_MARKET_CYCLE_UNKNOWN, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Short Market ... + + // + sPusher = 0; + sSignal.Clean(); + sProvider = NULL; + sHasSignal = false; + sConditions.Clean(); + + // + sHasSignal = !useSMarket + ? false + : mSetups[i] + .ProcessMarket( + sSignal, + sConditions, + sPusher, + sProvider, + sTP, + sSL, + X_MARKET_CYCLE_SHORT, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Medium Market ... + + // + mPusher = 0; + mSignal.Clean(); + mProvider = NULL; + mHasSignal = false; + mConditions.Clean(); + + // + mHasSignal = !useMMarket + ? false + : mSetups[i] + .ProcessMarket( + mSignal, + mConditions, + mPusher, + mProvider, + mTP, + mSL, + X_MARKET_CYCLE_MEDIUM, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Long Market ... + + // + lPusher = 0; + lSignal.Clean(); + lProvider = NULL; + lHasSignal = false; + lConditions.Clean(); + + // + lHasSignal = !useLMarket + ? false + : mSetups[i] + .ProcessMarket( + lSignal, + lConditions, + lPusher, + lProvider, + lTP, + lSL, + X_MARKET_CYCLE_LONG, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Hind Market ... + + // + hPusher = 0; + hSignal.Clean(); + hProvider = NULL; + hHasSignal = false; + hConditions.Clean(); + + // + hHasSignal = !useHMarket + ? false + : mSetups[i] + .ProcessMarket( + hSignal, + hConditions, + hPusher, + hProvider, + hTP, + hSL, + X_MARKET_CYCLE_HIND, + canSupport, + allowLong, + allowShort, + volume, + slPoint, + ignoreSL, + tpPoint, + ignoreTP, + 0, + 5 // + ); + + // + // Parse Signals and Add them for Executing ... + + // + // Check if there is a Signal or Not ... + bool hasSignal = cHasSignal || sHasSignal || mHasSignal || lHasSignal || hHasSignal; + if (hasSignal) + { + // + XSignal signal; + X121SetupConditions otherConditions[]; + + // + if (cHasSignal) + { + // + signal = cSignal; + + // + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + // AddRef( + // lConditions, + // otherConditions // + // ); + // AddRef( + // hConditions, + // otherConditions // + // ); + } + + // + if (sHasSignal) + { + // + signal = sSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + // AddRef( + // lConditions, + // otherConditions // + // ); + // AddRef( + // hConditions, + // otherConditions // + // ); + } + + // + if (mHasSignal) + { + // + signal = mSignal; + + // + AddRef( + sConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + } + + // + if (lHasSignal) + { + // + signal = lSignal; + + // + // AddRef( + // cConditions, + // otherConditions // + // ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + if (hHasSignal) + { + // + signal = hSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + int pushers = cPusher + sPusher + mPusher + lPusher + hPusher; + + // + bool isLong = IsLong(signal.type); + + // + // Validate Signal ... + bool isValid = + // + // Handle Pusher Validations ... + (mReuiredSignalVerifications <= 0 + ? true + : pushers >= mReuiredSignalVerifications) + // + && + // + // Handle Other Conditions Validations ... + (!mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions)) + // + ; + + // + bool forceState = mForce; // mSetups[i].ForceState(); + + // + if (!forceState) + { + // + // Add Signal to Execution Result ... + AddRef( + signal, + signals // + ); + + // + // Add new Signal Info ... + mTradeHandler.Add( + signal, + pushers, + canGrid, + canRecover, + canSupport, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); + } + else + { + // + // Clear Other Conditions ... + Clean(otherConditions); + + // + // Fill All Conditions to Other Conditions ... + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // If Recieved Any Unverified Signal + // we Passed it to EQM Manager ... + EQMHandleInvalidSignal( + signal, + pushers, + isValid, + otherConditions // + ); + } + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Here we Manage Signals for Executing ... + // - Check Policies based on their Signaller ... + // - Check Same Time Open Positions ... + // - Check Signal Age for new Trade ... + // and etc ... + int HandleSignalManagement(XSignal &signals[]) override + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signalsCount)) + { + return result; + } + + // + XSignal tmpSignals[]; + XSignal eSignals[]; // Must Executed + Copy( + signals, + tmpSignals // + ); + + // + Clean(signals); + + // + int maxAllowed = MaxAllowedTrades(); + bool perDirection = UseMaxAllowedPerDirection(); + + // + for (int i = 0; i < signalsCount; i++) + { + // + XSignal iSignal = tmpSignals[i]; + + // + bool isSignalValid = false; + + // + isSignalValid = IsSignalDelayPassed(iSignal); + if (!isSignalValid) + { + continue; + } + + // + // Handle Close All Positions when Opposit Signal Recieved ... + if (mCloseOnOpposit) + { + // + // Select Signal Opposit Positions ... + ENUM_X_POSITION_TYPES iOpposit = GetOppositPositionType(iSignal.type); + + // + XPosition iPositions[]; + int iPositionsCount = mTrader.GetPositions( + iPositions, + iSignal.symbol, + NULL, // All Providers ... + NULL, // All Periods ... + iOpposit // Opposit Positions ... + ); + + // + if (IsValidSize(iPositionsCount)) + { + // + string comment = "Close due Opposit ..."; + + // + int closeds = Close( + iPositions, + comment // + ); + if (IsValidSize(closeds)) + { + // + string message = XEQMSupportToken + " Closed " + ToString(iPositionsCount) + " due Opposit Signal ..."; + + // + Alert(message); + } + } + } + + // + // TODO: Remove this ... + // isSignalValid = !AllowSupport() + // ? true + // : IsValidSize(ArraySize(iSignal.supports)); + // if (!isSignalValid) + // { + // continue; + // } + + // + // Filter Signals Based On Max Allowed ... + if (maxAllowed > 0) + { + // + // Here we Get Opposite Signals of Same Symbol Valid ... + ENUM_X_POSITION_TYPES iType = + perDirection + ? ToPositionType(iSignal.type) + : X_POSITION_TYPE_ALL; + XPosition iSymbolsPositions[]; + int iSymbolsPositionsCount = mTrader.GetPositions( + iSymbolsPositions, + iSignal.symbol, + NULL, // Provider + NULL, // Period + iType, // Type + true // + ); + + // + int iSupportsCount = 0; + if (IsValidSize(iSymbolsPositionsCount)) + { + // + // Filter Support Positions ... + XPosition iSupports[]; + iSupportsCount = ExtractSupports( + iSymbolsPositions, + iSupports // + ); + } + + // + isSignalValid = + iSupportsCount <= 0 + ? iSymbolsPositionsCount < maxAllowed + : iSymbolsPositionsCount - iSupportsCount < maxAllowed; + if (!isSignalValid) + { + continue; + } + } + else + { + isSignalValid = true; + } + + // + // Only Accept Next Same Type when Previous in Profit ... + if (isSignalValid) + { + // + ENUM_X_POSITION_TYPES iType = + ToPositionType(iSignal.type); + XPosition iSymbolsPositions[]; + int iSymbolsPositionsCount = mTrader.GetPositions( + iSymbolsPositions, + iSignal.symbol, + NULL, // Provider + NULL, // Period + iType, // Type + true // + ); + + // + int iSupportsCount = 0; + if (IsValidSize(iSymbolsPositionsCount)) + { + // + // Filter Support Positions ... + XPosition iSupports[]; + iSupportsCount = ExtractSupports( + iSymbolsPositions, + iSupports // + ); + + // + // Filter Support Positions ... + if (IsValidSize(iSupportsCount)) + { + // + XPosition tmpPositions[]; + Copy( + iSymbolsPositions, + tmpPositions // + ); + + // + Clean(iSymbolsPositions); + + // + for (int i = 0; i < iSymbolsPositionsCount; i++) + { + // + XPosition iPosition = tmpPositions[i]; + + // + bool isSupport = IsSupport(iPosition.comment); + if (isSupport) + { + continue; + } + + // + AddRef( + iPosition, + iSymbolsPositions // + ); + } + + // + iSymbolsPositionsCount = ArraySize(iSymbolsPositions); + } + } + + // + if (IsValidSize(iSymbolsPositionsCount)) + { + // + XPosition youngest; + int youngestAge = GetYoungest( + youngest, + iSymbolsPositions // + ); + + // + isSignalValid = youngest.profit > 0.1; + } + + // + if (!isSignalValid) + { + continue; + } + } + + // + // Multiply Signal Volume ... + if (isSignalValid) + { + // + XPosition iSymbolsPositions[]; + int iSymbolsPositionsCount = mTrader.GetPositions( + iSymbolsPositions, + iSignal.symbol, + NULL, // Provider + NULL, // Period + NULL, // Type + true // + ); + + // + int iSupportsCount = 0; + if (IsValidSize(iSymbolsPositionsCount)) + { + // + // Filter Support Positions ... + XPosition iSupports[]; + iSupportsCount = ExtractSupports( + iSymbolsPositions, + iSupports // + ); + } + + // + int multiplier = + iSupportsCount <= 0 + ? iSymbolsPositionsCount + : iSymbolsPositionsCount - iSupportsCount; + if (multiplier <= 0) + { + multiplier = 1; + } + else + { + multiplier++; + } + + // + // Ignore ... + iSignal.volume = iSignal.volume * multiplier; + } + + // + // Handle Signal ... + if (isSignalValid) + { + // + AddRef( + iSignal, + eSignals // + ); + } + } + + // + // Cutom Signal Execution ... + HandleSignals(eSignals); + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Handle State Management .... + // here we can manage current state ... + // - Check for Long Positions for each Signaller to Close ... + // - Handle Hedging Signaller's Positions if it's enabled ... + // - Force Closing Position when Specified Time reached ... + // - Check Start and End time or Trading Dates ... + // - handle Trailing or Risk free Signals based on several conditions ... + // and etc ... + bool HandleStateManagement(XSignal &signals[]) override + { + // + const bool result = false; + + // + // Do all State Management here ... + + // + // Check if there are open Positions + // and their doesn't have TP and SL and + // Youngest Age of Positions longest as enough + // Make State of Signalling to Force State for Recieving + // Signal and Clear their Tp and SL for allowing hedges ... + // EQMHandleForceState(signals); + // if (mForce) + // { + // result = true; + // } + + // + DoHedge(); + + // + // Handle Close All Positions on Specific Time ... + DoEQMCloseOnSpecificTime(); + + // + // Do EQM Protection if Provided ... + DoEQMProtect(); + + // + // if Returns true, Signal Execution failed ... + return result; + } + + // + // Signal Info ... + + // + void OnSignalExecuted(const XSignal &signal) override + { + // + // Signal Info Manager ... + XSignal tSignal = signal; + bool isSupport = IsSupport(signal.comment); + if (!isSupport) + { + mTradeHandler.Update(tSignal); + } + + // + mTradeHandler.Sync(); + } + + // + void OnSignalExecutionFailed( + const XSignal &signal, + const ENUM_X_SIGNAL_EXECUTION_RESULT reason // + ) override + { + // + // Signal Info Manager ... + XSignal tSignal = signal; + mTradeHandler.Remove(tSignal); + mTradeHandler.Sync(); + } + + // + void OnPositionClosed( + const XPosition &position, + const string comment // + ) override + { + // + // When a Position Closed Manually ... + // Signal Info Manager ... + XPosition tPosition = position; + bool isSupport = ExtractSupportedTicket(position.comment) > 0; + bool isEQMSupport = ExtractEQMSupportedTicket(position.comment) > 0; + tPosition.comment = comment; + if (!isSupport && !isEQMSupport) + { + mTradeHandler.Update(tPosition); + } + + // + mTradeHandler.Sync(); + } + + // + void OnStopLossTriggered(const XDeal &deal) override + { + // + // When a Position's Stop Loss Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeHandler.Update(tDeal); + mTradeHandler.Sync(); + } + + // + void OnTakeProfitTriggered(const XDeal &deal) override + { + // + // When a Position's Take Profit Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeHandler.Update(tDeal); + mTradeHandler.Sync(); + } + + // + // Protected ... +protected: + // + // Tools ... + + // + // Check Signalling Enable or not ... + bool IsEnable() + { + // + bool result = false; + + // + // Check Signal Type is Enabled or not ... + bool isTypePassed = mAllowLong || mAllowShort; + + // + // Check Signalling Time ... + MqlDateTime cTime; + bool isTimeRecieved = TimeCurrent(cTime); + + // + int endHour = EndSignallingHoure(); + int startHour = StartSignallingHoure(); + + // + bool isStartHourPassed = + startHour <= -1 + ? true + : cTime.hour >= startHour; + bool isEndHourPassed = + endHour <= -1 + ? true + : cTime.hour < endHour; + bool isTimePassed = isTimeRecieved && isStartHourPassed && isEndHourPassed; + + // + result = isTypePassed && isTimePassed; + + // + return result; + } + + // + bool CanCloseOnTime() + { + // + bool result = false; + + // + result = mCloseOnSpecificTime >= 0 && mCloseOnSpecificTime <= 23; + if (!result) + { + return result; + } + + // + MqlDateTime timeStruct; + result = TimeCurrent(timeStruct); + if (!result) + { + return result; + } + + // + result = timeStruct.hour == mCloseOnSpecificTime; + + // + return result; + } + + // + // Custom Signal Execution ... + void HandleSignals(XSignal &signals[]) + { + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signals)) + { + return; + } + + // + bool isMarginPassed = IsMarginPassed(); + if (!isMarginPassed) + { + // + string message = "No Margin For Execute Signals ..."; + + // + Alert(message); + + // + EQMHandleForceState(signals); + + // + return; + } + + // + bool isNumberOfPositionsPassed = IsNumberOfPositionsPassed(); + if (!isNumberOfPositionsPassed) + { + // + string message = "Max Allowed Signals Reached ..."; + + // + Alert(message); + + // + return; + } + + // + bool executeOnBreakouts = ExecuteSignalsOnBreakout(); + if (executeOnBreakouts) + { + // + XSignal bSignals[]; + int bSignalsCount = mTradeHandler.GetBreakoutsSignals(bSignals); + if (IsValidSize(bSignalsCount)) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executedSignalsCount = ExecuteSignals( + signals, + states, + false // + ); + } + } + else + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executedSignalsCount = ExecuteSignals( + signals, + states, + false // + ); + } + } + + // + // Check Delay Between Two Signals ... + bool IsSignalDelayPassed( + XSignal &signal // + ) + { + // + bool result = false; + + // + // Check Signal Validation ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Check Delay Signals Allowed ... + int delay = DelayBetweenTwoSignal(); + result = delay <= 0; + if (result) + { + return result; + } + + // + // Retrieve Positions ... + // Based On Provider and Symbol and TimeFrame ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions( + positions, + signal.symbol, + NULL, // signal.provider, + NULL, // signal.period, + ToPositionType(signal.type), + true // Filter By Magic ... + ); + result = !IsValidSize(positionsCount); + if (result) + { + return result; + } + + // + XPosition youngest; + int youngestAge = GetYoungest( + youngest, + positions // + ); + result = youngestAge >= delay; + + // + return result; + } + + // + bool IsMarginPassed() + { + // + double freeMargin = mTrader.mAccount.GetFreeMargin(); + double minFreeMargingForHandleForce = MinFreeMargingForOpenTrades(); + + // + bool result = minFreeMargingForHandleForce <= 0 + ? true + : freeMargin >= minFreeMargingForHandleForce; + + // + return result; + } + + // + bool IsNumberOfPositionsPassed() + { + // + bool result = false; + + // + // int maxAllowed = MaxPositionsForce(); + // result = maxAllowed <= 0; + // if (result) + // { + // return result; + // } + + // // + // XPosition positions[]; + // int positionsCount = mTrader.GetPositions(positions); + // result = !IsValidSize(positionsCount); + // if (result) + // { + // return result; + // } + + // // + // result = positionsCount < maxAllowed; + + // + result = true; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + + // + // Signals ... + bool mAllowLong; // Allow Long + bool mAllowShort; // Allow Short + int mReuiredSignalVerifications; // Required Verifications for Validate Signals + bool mExecuteSignalsOnBreakout; // Execute Signals On Breakouts + bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames + + // + // Risk Management ... + double mVolume; // Volume + double mTPPoint; // TP Point + double mSLPoint; // SL Point + int mMaxAllowedTrades; // Max Alloed Positions + bool mUseMaxAllowedPerDirection; // Use Max Allowed Positions Per Direction + bool mIgnoreTP; // Ignore Calculated TP + bool mIgnoreSL; // Ignore Calculated SL + + // + // Signalling ... + bool mCloseOnOpposit; // Close all Positions on Opposit + int mEndSignallingHoure; // End Signalling at Specific Time + int mCloseOnSpecificTime; // Close All Trades in Specific Time + int mStartSignallingHoure; // Start Signalling at Specific Time + + // + // Force State: + // we can do many things in force state: + // - Prepare Force Hedging; + // - Receive Signals with minimal Verifications; + // - Increase Volume Size of in Profit Positions; + // - etc ... + // bool mForceState; // Determine in Force State or not + int mDelayBetweenTwoSignal; // Delay between two same signal + int mMaxPositionsForce; // Max Number of Positions For Guard Handling + double mMaxDrawdownForce; // Force Handling State on Drawdown for Guard + bool mAllowSymbolHedgeOnForce; // Allow Symbol Hedging on Force States + double mMinFreeMargingForOpenTrades; // Min Free Margin for Open Trades + + // + XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions + + // + // Apply Default Configurations ... + void DefaultConfigs() + { + // + // Signals ... + AllowLong(false); + AllowShort(false); + ReuiredSignalVerifications(0); + GetVerificationFromOtherTimeFrames(false); + + // + // Risk Management ... + TPPoint(0); + SLPoint(0); + Volume(0.01); + IgnoreTP(false); + IgnoreSL(false); + MaxAllowedTrades(0); + + // + // Signalling ... + CloseOnOpposit(false); + EndSignallingHoure(-1); + CloseOnSpecificTime(-1); + StartSignallingHoure(-1); + + // + // Trailling ... + AllowTrailStop(false); + NextTrailPoint(0); + FirstTrailPoint(0); + NextTrailDistance(0); + FirstTrailDistance(0); + + // + // Supporting ... + AllowSupport(false); + MaxNumberOfSupports(0); + SupportVolumeMultiplier(0.01); + MaxAllowedSupportVolume(0.08); + + // + // Grid ... + AllowGrid(false); + GridDistance(0); + MaxNumberOfGrids(0); + GridVolumeMultiplier(0.01); + MaxAllowedGridVolume(0.08); + + // + // Recovery ... + AllowRecovery(false); + MaxNumberOfRecoveries(0); + RecoveryDistance(0); + RecoveryVolumeMultiplier(0.01); + MaxAllowedRecoveryVolume(0.08); + + // + SaveResults(false); + SaveSignalsOnly(true); + } + + // + XSCX121SetupCycles *mSetups[]; // Number of Setups + + // + // Tools ... + int CountSetups() + { + return ArraySize(mSetups); + } + + // + int FindSetupIndex( + string symbol, + ENUM_TIMEFRAMES period // + ) + { + // + int result = -1; + + // + int count = CountSetups(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSCX121SetupCycles *iSetup = mSetups[i]; + + // + X121SetupInputs iInputs = iSetup.GetInputs(); + + // + if (iInputs.symbol == symbol && iInputs.period == period) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + int FindSetupIndex( + string symbol // + ) + { + // + int result = -1; + + // + int count = CountSetups(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSCX121SetupCycles *iSetup = mSetups[i]; + + // + X121SetupInputs iInputs = iSetup.GetInputs(); + + // + if (iInputs.symbol == symbol) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + // EQM Functions ... + + // + // Force Close All Positions Due EQM Hedge ... + bool DoEQMForceClose() + { + // + bool result = false; + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + result = IsValidSize(positionsCount); + if (!result) + { + return result; + } + + // + double profit = SpecifiedCalculatePositionsProfit( + positions // + ); + + // + string comment = XEQMSupportToken + " Hedge ..."; + int closed = Close( + positions, + comment // + ); + + // + result = IsValidSize(closed); + if (result) + { + // + mForce = false; + mTradeHandler.Sync(); + } + + // + // Handle Sleeping ... + int restingTime = RestingAfterHedge(); + if (result && IsValidSize(restingTime)) + { + Sleeping(restingTime); + } + + // + return result; + } + + // + // Do Gridding Mechanism ... + void DoEQMProtect() + { + // + XSignal supports[]; + int supportsCount = mTradeHandler.DoProtect( + supports, + mSetups // + ); + + // + if (IsValidSize(supportsCount)) + { + EQMExecuteSignals(supports); + } + } + + // + // Handle Close Trades on Specific Time ... + void DoEQMCloseOnSpecificTime() + { + // + bool canClose = CanCloseOnTime(); + if (!canClose) + { + return; + } + + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + return; + } + + // + string comment = XEQMSupportToken + " Close On Specific Time ..."; + + // + int closed = Close( + positions, + comment // + ); + if (IsValidSize(closed)) + { + // + string message = XEQMSupportToken + " Closed " + ToString(closed) + " Positions on Specified Time ..."; + + // + Alert(message); + } + } + + // + // Handle Force State Management ... + bool mForce; + void EQMHandleForceState(XSignal &forceSignals[]) + { + // + // Validate Force Marigin ... + return; + double drawdown = GetDrawdownPercent(); + double marigin = mTrader.mAccount.GetMargin(); + double minFreeMarigin = MinFreeMargingForOpenTrades(); + double forceMargin = minFreeMarigin * 2; // TODO: Make It Configurable + bool isMarginForce = marigin >= forceMargin; + bool isMarginHotForce = marigin >= forceMargin * 3; + bool isHotDrawdown = drawdown >= 10; + + // + // Retrieving Positions ... + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (!IsValidSize(positionsCount)) + { + // + mForce = false; + return; + } + bool isPositionsCountHotForce = positionsCount >= 10; + + // + XPosition oldest; + int oldestAge = GetOldest( + oldest, + positions // + ); + + // + // Check Force State ... + bool isForce = isMarginForce && oldestAge >= 288; + if (!isForce) + { + // + if (mForce) + { + mForce = false; + } + return; + } + else + { + mForce = true; + } + + // + // Prevent Moving Forward From Non Force State ... + if (!mForce) + { + return; + } + return; + + // + double minProfitPerTrade = MinProfitPerTrade(); + double minProfitPerVolumeFactor = MinProfitPerVolumeFactor(); + + // + double profit = SpecifiedCalculatePositionsProfit(positions); + double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( + positions, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + + // + XSymbolPositions symbolPositions[]; + int symbolPositionsCount = ExtractSymbolPositions( + positions, + symbolPositions, + minProfitPerTrade, + minProfitPerVolumeFactor // + ); + if (!IsValidSize(symbolPositionsCount)) + { + return; + } + + // + XSignal signals[]; + int forceSignalsCount = ArraySize(forceSignals); + if (IsValidSize(forceSignalsCount)) + { + // + // Check if Symbol Contains or Not ... + for (int i = 0; i < forceSignalsCount; i++) + { + // + XSignal iForceSignal = forceSignals[i]; + + // + int symbolIDX = -1; + bool isSymbolContains = IsContainsSymbol( + iForceSignal.symbol, + symbolIDX, + symbolPositions // + ); + if (!isSymbolContains) + { + // + AddRef( + iForceSignal, + signals // + ); + + // + continue; + } + else + { + // + ENUM_POSITION_TYPE iType = iForceSignal.type; + bool isLong = IsLong(iType); + + // + XSymbolPositions iSymbolPositions = symbolPositions[symbolIDX]; + if (isLong) + { + // + if (iSymbolPositions.longsProfit > 0) + { + // + if (!isMarginHotForce && !isPositionsCountHotForce) + { + // + AddRef( + iForceSignal, + signals // + ); + } + else + { + } + } + else + { + // + // In Drawdown ... + if (isMarginHotForce && !isPositionsCountHotForce) + { + } + else + { + // + bool hasSupport = iSymbolPositions.HasLongSupport(); + if (hasSupport) + { + continue; + } + + // + mTradeHandler.AllowToGrid(iForceSignal); + AddRef( + iForceSignal, + signals // + ); + } + } + } + else + { + // + if (iSymbolPositions.shortsProfit > 0) + { + // + if (!isMarginHotForce && !isPositionsCountHotForce) + { + // + AddRef( + iForceSignal, + signals // + ); + } + else + { + } + } + else + { + // + // In Drawdown ... + if (!isMarginHotForce && !isPositionsCountHotForce) + { + } + else + { + // + bool hasSupport = iSymbolPositions.HasShortSupport(); + if (hasSupport) + { + continue; + } + + // + mTradeHandler.AllowToGrid(iForceSignal); + AddRef( + iForceSignal, + signals // + ); + } + } + } + } + } + } + + // + int signalsCount = ArraySize(signals); + if (IsValidSize(signalsCount)) + { + EQMExecuteSignals(signals); + } + else + { + // + // Handle CLosing ... + if (!isMarginHotForce && !isHotDrawdown) + { + return; + } + + // + for (int i = 0; i < symbolPositionsCount; i++) + { + // + XSymbolPositions iSymbolPositions = symbolPositions[i]; + + // + if (!iSymbolPositions.HasChild()) + { + continue; + } + + // + if (iSymbolPositions.profit > 0) + { + continue; + } + + // + // XPosition iOldest; + // int oldestAge = GetOldest( + // iOldest, + // iSymbolPositions.positions // + // ); + // if (oldestAge <= 140) + // { + // continue; + // } + + // + int maxInDPIDX = FindMaxDrawdownIndex( + iSymbolPositions.positions // + ); + if (!IsValidIndex(maxInDPIDX)) + { + continue; + } + + // + XPosition maxInDP = iSymbolPositions.positions[maxInDPIDX]; + int age = GetAge( + maxInDP, + maxInDP.period // + ); + if (age <= 288) + { + continue; + } + + // + string comment = XEQMSupportToken + " Close due Max In D ..."; + bool isClosed = mTrader.Close( + maxInDP.ticket, + comment // + ); + if (isClosed) + { + // + string message = XEQMSupportToken + " Close (" + ToString(maxInDP.ticket) + ") due Max In D ..."; + + // + Alert(message); + } + } + } + + // + } + + // + // Handle any Invalid Signals ... + void EQMHandleInvalidSignal( + XSignal &signal, // Invalid Signal + int pushers, // Pushers + bool isValid, // IsValid Signal ... + X121SetupConditions &conditions[] // All Time Frames Conditions + ) + { + // + if (!mForce) + { + return; + } + + // + XSignal signals[]; + + // + // || pushers >= 3 + if (isValid) + { + // + bool canSupport = + // + mForce && + EnableSupport() && + SupportOnlyForces() + // + ; + bool canGrid = + // + mForce && + EnableGrid() && + GridOnlyForces() + // + ; + bool canRecover = + // + mForce && + EnableRecovery() && + RecoverOnlyForces() + // + ; + + // + AddRef( + signal, + signals // + ); + + // + // Add new Signal Info ... + mTradeHandler.Add( + signal, + pushers, + canGrid, + canRecover, + canSupport, + conditions[0], + conditions[1], + conditions[2], + conditions[3], + conditions[4] // + ); + } + + // + if (ArraySize(signals) > 0) + { + // + EQMExecuteSignals(signals); + // EQMHandleForceState(signals); + } + } + + // + void EQMExecuteSignals( + XSignal &signals[] // + ) + { + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signals)) + { + return; + } + + // + // + // Execute Supports ... + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executed = ExecuteSignals( + signals, + states, + false // Ignore Policies ... + ); + if (executed != signalsCount) + { + // + // TODO: Dow What We Want ... + // Print("Error On Executing Support Signal ..."); + } + + // + // Remove Supported Signals TP and SL and leave them for Handling using HEDGE Mechanism ... + if (IsValidSize(executed)) + { + // + for (int i = 0; i < signalsCount; i++) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT iState = states[i]; + if (iState != X_SIGNAL_EXECUTION_SUCCEED) + { + continue; + } + + // + XSignal iSignal = signals[i]; + if (!iSignal.IsValid() || !iSignal.IsExecuted()) + { + continue; + } + + // + ulong iParentTicket = ExtractParentTicket(iSignal.comment); + if (iParentTicket <= 0) + { + continue; + } + + // + XPosition iParent; + bool hasParent = mTrader.GetPosition( + iParentTicket, + iParent // + ); + if (!hasParent) + { + continue; + } + + // + // Check Parent Has TP or SL ... + if (iParent.tp == 0 && iParent.sl == 0) + { + continue; + } + + // + // Remove TP and SL of Supported Positions ... + string comment = "EQM Remove TPSL ..."; + bool isModified = Modify( + iParentTicket, + 0, + 0, + comment // + ); + if (isModified) + { + // + // TODO: + // do What we want ... + } + } + } + } + + // +}; + +// diff --git a/BKPS/14030412/Documents/BKP/Old/x-saherelm.xadxtd.helper.mq5 b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xadxtd.helper.mq5 new file mode 100644 index 0000000..87b8a73 --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xadxtd.helper.mq5 @@ -0,0 +1,678 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XADXTD +// Description: provides Indicator implementation +// requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Indicator Buffers ... +enum ENUM_XADXTD_BUFFERS +{ + XADXTD_STRENGTH_LINE = 0, // Strenght Buffer ... + XADXTD_BULL_LINE = 1, // Bull Buffer ... + XADXTD_BEAR_LINE = 2, // Bear Buffer ... +}; + +// +string GetTitle(ENUM_XADXTD_BUFFERS bufferLine) +{ + // + string result = NULL; + + // + switch (bufferLine) + { + // + case XADXTD_STRENGTH_LINE: + result = "XStrength"; + break; + + // + case XADXTD_BULL_LINE: + result = "XBull"; + break; + + // + case XADXTD_BEAR_LINE: + result = "XBear"; + break; + } + + // + return result; +} + +// +// XADXTD Indicator Inputs ... +struct XADXTDInputs +{ + // + // Props ... + string version; + + // + // Market ... + + // + int length; // Length + + // + // Constructor ... + XADXTDInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Initial Inputs ... + bool Init( + int _length = 21 // Length + ) + { + // + bool result = false; + + // + this.length = _length; + + // + result = IsValid(); + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + length = 0; + } + + // + // Default ... + void Default() + { + // + length = 21; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 0 + // + ; + + // + return result; + } + + // + // Retrieve Max Length ... + int Max() + { + // + int result = 0; + + // + int values[1] = { + length // + }; + + // + result = GetMax(values); + + // + return result; + } +}; + +// +// Define Conditions ... +struct XADXTDConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double strength[]; + double bullp[]; + double bearp[]; + + // + // Conditions ... + + // + bool isStrong; + bool isBullish; + bool isBearish; + bool isSwitchedToBullish; + bool isSwitchedToBearish; + bool isStrongSwitchedToBullish; + bool isStrongSwitchedToBearish; + + // + void Clean() + { + // + Clean(strength); + Clean(bullp); + Clean(bearp); + + // + ArraySetAsSeries(strength, true); + ArraySetAsSeries(bullp, true); + ArraySetAsSeries(bearp, true); + + // + isStrong = false; + isBullish = false; + isBearish = false; + isSwitchedToBullish = false; + isSwitchedToBearish = false; + isStrongSwitchedToBullish = false; + isStrongSwitchedToBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (isBullish) + { + // + bullishScore++; + if (isStrong) + { + bullishScore++; + } + } + if (isBearish) + { + bearishScore++; + if (isStrong) + { + bearishScore++; + } + } + if (isSwitchedToBullish) + { + bullishScore++; + if (isStrong) + { + bullishScore++; + } + } + if (isSwitchedToBearish) + { + bearishScore++; + if (isStrong) + { + bearishScore++; + } + } + if (isStrongSwitchedToBullish) + { + bullishScore++; + } + if (isStrongSwitchedToBearish) + { + bearishScore++; + } + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + ToString("isStrong", isStrong, ignoreFalseConditions, separator) + + ToString("isBullish", isBullish, ignoreFalseConditions, separator) + + ToString("isBearish", isBearish, ignoreFalseConditions, separator) + + ToString("isSwitchedToBullish", isSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSwitchedToBearish", isSwitchedToBearish, ignoreFalseConditions, separator) + + ToString("isStrongSwitchedToBullish", isStrongSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isStrongSwitchedToBearish", isStrongSwitchedToBearish, ignoreFalseConditions, separator) + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XADXTD"; + } +}; + +// +// Indicator Class ... + +class XSCXADXTDHelper : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XSCXADXTDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading TimeFrame + ) + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCXADXTDHelper() {} + + // + // Initialize Indicator ... + bool Init( + XADXTDInputs &inputs // Indicator Properties + ) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + // Set Inputs ... + this.mInputs = inputs; + + // + // Validate Indicator State ... + result = this.IsValid(); + if (!result) + { + return result; + } + + // + result = DefineBuffers(); + if (!result) + { + return result; + } + + // + handler = iADX( + mSymbol, + mPeriod, + mInputs.length // + ); + result = handler != INVALID_HANDLE; + + // + return result; + } + + // + XADXTDInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XADXTDInputs &inputs // Indicator Properties + ) + { + return Init(inputs); + } + + // + // Get Tag ... + string GetTag() + { + // + string result = NULL; + + // + result = GetToken(); + + // + return result; + } + + // + // Get Token ... + string GetToken() + { + // + string result = NULL; + + // + result = GetSpecificToken(this); + + // + return result; + } + + // + string GetSymbol() + { + return mSymbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + mInputs.IsValid() && + IsSpecifiedValid(mPeriod) && + IsSpecifiedValid(mSymbol) + // + ; + + // + return result; + } + + // + // De Initialize Class ... + void DeInit(int reason) + { + // + IndicatorRelease(handler); + } + + // + // Tools ... + int CopyData( + ENUM_XADXTD_BUFFERS line, + double &dest[], + int start = 0, + int count = 1 // + ) + { + // + int result = 0; + + // + int mLine = -1; + switch (line) + { + // + case XADXTD_STRENGTH_LINE: + mLine = MAIN_LINE; + break; + + // + case XADXTD_BULL_LINE: + mLine = PLUSDI_LINE; + break; + + // + case XADXTD_BEAR_LINE: + mLine = MINUSDI_LINE; + break; + } + + // + if (mLine == -1 || handler == INVALID_HANDLE) + { + return result; + } + + // + result = CopyBuffer( + handler, + mLine, + start, + count, + dest // + ); + + // + return result; + } + + // + bool GetConditions( + XADXTDConditions &conditions, // + int barIndex = 0, // + int loopback = 3 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + CopyData( + XADXTD_STRENGTH_LINE, + conditions.strength, + zIndex, + loopback // + ); + CopyData( + XADXTD_BULL_LINE, + conditions.bullp, + zIndex, + loopback // + ); + CopyData( + XADXTD_BEAR_LINE, + conditions.bearp, + zIndex, + loopback // + ); + + // + // Calculate Conditions ... + + // + bool isStrong = conditions.strength[cIndex] >= 20; + + // + bool isBullish = conditions.bullp[cIndex] > conditions.bearp[cIndex]; + bool isBearish = conditions.bearp[cIndex] > conditions.bullp[cIndex]; + + // + bool isBullishPrev = conditions.bullp[pIndex] > conditions.bearp[pIndex]; + bool isBearishPrev = conditions.bearp[pIndex] > conditions.bullp[pIndex]; + + // + bool isSwitchedToBullish = isBullish && + !isBullishPrev; + bool isSwitchedToBearish = isBearish && + !isBearishPrev; + + // + bool isStrongSwitchedToBullish = isStrong && + isSwitchedToBullish; + bool isStrongSwitchedToBearish = isStrong && + isSwitchedToBearish; + + // + conditions.isStrong = isStrong; + conditions.isBullish = isBullish; + conditions.isBearish = isBearish; + conditions.isSwitchedToBullish = isSwitchedToBullish; + conditions.isSwitchedToBearish = isSwitchedToBearish; + conditions.isStrongSwitchedToBullish = isStrongSwitchedToBullish; + conditions.isStrongSwitchedToBearish = isStrongSwitchedToBearish; + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + int handler; + + // + // Tools ... + bool DefineBuffers() + { + // + bool result = false; + + // + result = true; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + // + string mSymbol; // Symbol + ENUM_TIMEFRAMES mPeriod; // TimeFrame + + // + XADXTDInputs mInputs; // Properties +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-saherelm.xmatd.helper.mq5 b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xmatd.helper.mq5 new file mode 100644 index 0000000..ddb4be7 --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xmatd.helper.mq5 @@ -0,0 +1,1046 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XMATD +// Description: provides Indicator implementation +// requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +// Imports ... +#include "../Classes/x-saherelm.base.class.mq5" + +// +// Indicator Buffers ... +enum ENUM_XMATD_BUFFERS +{ + XMATD_FAST_LINE = 0, // Fast Buffer ... + XMATD_MID_LINE = 1, // Mid Buffer ... + XMATD_SLOW_LINE = 2, // Slow Buffer ... + XMATD_PSAR_LINE = 3, // Parabolic Buffer ... +}; + +// +string GetTitle(ENUM_XMATD_BUFFERS bufferLine) +{ + // + string result = NULL; + + // + switch (bufferLine) + { + // + case XMATD_FAST_LINE: + result = "XFats"; + break; + + // + case XMATD_MID_LINE: + result = "XMid"; + break; + + // + case XMATD_SLOW_LINE: + result = "XSlow"; + break; + } + + // + return result; +} + +// +// XMATD Indicator Inputs ... +struct XMATDInputs +{ + // + // Props ... + string version; + + // + // Market ... + + // + int fastLength; // Fast Length + int midLength; // Mid Length + int slowLength; // Slow Length + + // + double step; // Sar Step + double maximum; // Sar Maximum + + // + // Calculation Mode ... + + // + int shift; // Shift + ENUM_MA_METHOD method; // Method of MA + ENUM_APPLIED_PRICE appliedTo; // Applied To + + // + // Constructor ... + XMATDInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Initial Inputs ... + bool Init( + int _fastLength = 21, // Fast Length + int _midLength = 50, // Mid Length + int _slowLength = 200, // Slow Length + ENUM_MA_METHOD _method = MODE_SMA, // Shift + ENUM_APPLIED_PRICE _appliedTo = PRICE_CLOSE, // Method of MA + int _shift = 0 // Applied To + ) + { + // + bool result = false; + + // + this.fastLength = _fastLength; + this.midLength = _midLength; + this.slowLength = _slowLength; + + // + this.shift = _shift; + this.method = _method; + this.appliedTo = _appliedTo; + + // + result = IsValid(); + + // + return result; + } + + // + // Cleanup ... + void Clean() + { + // + fastLength = 0; + midLength = 0; + slowLength = 0; + + // + shift = 0; + + // + step = 0; + maximum = 0; + + // + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + } + + // + // Default ... + void Default() + { + // + fastLength = 21; + midLength = 50; + slowLength = 200; + + // + method = MODE_SMA; + appliedTo = PRICE_CLOSE; + + // + step = 0.02; + maximum = 0.2; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + fastLength > 0 && + midLength > fastLength && + slowLength > midLength + // + && + // + step > 0 && + maximum > step + // + ; + + // + return result; + } + + // + // Retrieve Max Length ... + int Max() + { + // + int result = 0; + + // + int values[3] = { + fastLength, + midLength, + slowLength // + }; + + // + result = GetMax(values); + + // + return result; + } +}; + +// +// Define Conditions ... +struct XMATDConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double fast[]; + double mid[]; + double slow[]; + + // + double psar[]; + + // + // Conditions ... + + // + // Trend ... + bool isBullish; + bool isBearish; + bool isSwitchedToBullish; + bool isSwitchedToBearish; + + // + // Fast Mid ... + bool isFastOverMid; + bool isFastUnderMid; + bool isFastCrossedOverMid; + bool isFastCrossedUnderMid; + + // + // Fast Slow ... + bool isFastOverSlow; + bool isFastUnderSlow; + bool isFastCrossedOverSlow; + bool isFastCrossedUnderSlow; + + // + // Mid Slow ... + bool isMidOverSlow; + bool isMidUnderSlow; + bool isMidCrossedOverSlow; + bool isMidCrossedUnderSlow; + + // + bool isSARBullish; + bool isSARBearish; + bool isSARSwitchedToBullish; + bool isSARSwitchedToBearish; + + // + void Clean() + { + // + Clean(fast); + Clean(mid); + Clean(slow); + Clean(psar); + + // + ArraySetAsSeries(fast, true); + ArraySetAsSeries(mid, true); + ArraySetAsSeries(slow, true); + ArraySetAsSeries(psar, true); + + // + // Trend ... + isBullish = false; + isBearish = false; + isSwitchedToBullish = false; + isSwitchedToBearish = false; + + // + // Fast Mid ... + isFastOverMid = false; + isFastUnderMid = false; + isFastCrossedOverMid = false; + isFastCrossedUnderMid = false; + + // + // Fast Slow ... + isFastOverSlow = false; + isFastUnderSlow = false; + isFastCrossedOverSlow = false; + isFastCrossedUnderSlow = false; + + // + // Mid Slow ... + isMidOverSlow = false; + isMidUnderSlow = false; + isMidCrossedOverSlow = false; + isMidCrossedUnderSlow = false; + + // + isSARBullish = false; + isSARBearish = false; + isSARSwitchedToBullish = false; + isSARSwitchedToBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + // Trend ... + + // + if (isBullish) + { + bullishScore++; + } + if (isSwitchedToBullish) + { + bullishScore++; + } + + // + if (isBearish) + { + bearishScore++; + } + if (isSwitchedToBearish) + { + bearishScore++; + } + + // + // Fast Mid ... + + // + if (isFastOverMid) + { + bullishScore++; + } + if (isFastCrossedOverMid) + { + bullishScore++; + } + + // + if (isFastUnderMid) + { + bearishScore++; + } + if (isFastCrossedUnderMid) + { + bearishScore++; + } + + // + // Fast Slow ... + + // + if (isFastOverSlow) + { + bullishScore++; + } + if (isFastCrossedOverSlow) + { + bullishScore++; + } + + // + if (isFastUnderSlow) + { + bearishScore++; + } + if (isFastCrossedUnderSlow) + { + bearishScore++; + } + + // + // Mid Slow ... + + // + if (isMidOverSlow) + { + bullishScore++; + } + if (isMidCrossedOverSlow) + { + bullishScore++; + } + + // + if (isMidUnderSlow) + { + bearishScore++; + } + if (isMidCrossedUnderSlow) + { + bearishScore++; + } + + // + if (isSARBullish) + { + bullishScore++; + } + if (isSARSwitchedToBullish) + { + bullishScore++; + } + + // + if (isSARBearish) + { + bearishScore++; + } + if (isSARSwitchedToBearish) + { + bearishScore++; + } + } + + // + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string scoresStr = + // + "Scores: " + separator + + "---------------" + separator + + "Bullish: " + ToString(bullishScore) + separator + + "Bearish: " + ToString(bearishScore) + separator + + "" + // + ; + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores // + ); + + // + string conditionsStr = + // + // Trend ... + ToString("isBullish", isBullish, ignoreFalseConditions, separator) + + ToString("isBearish", isBearish, ignoreFalseConditions, separator) + + ToString("isSwitchedToBullish", isSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSwitchedToBearish", isSwitchedToBearish, ignoreFalseConditions, separator) + + // + // Fast Mid ... + ToString("isFastOverMid", isFastOverMid, ignoreFalseConditions, separator) + + ToString("isFastUnderMid", isFastUnderMid, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverMid", isFastCrossedOverMid, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderMid", isFastCrossedUnderMid, ignoreFalseConditions, separator) + + // + // Fast Slow ... + ToString("isFastOverSlow", isFastOverSlow, ignoreFalseConditions, separator) + + ToString("isFastUnderSlow", isFastUnderSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedOverSlow", isFastCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isFastCrossedUnderSlow", isFastCrossedUnderSlow, ignoreFalseConditions, separator) + + // + // Mid Slow ... + ToString("isMidOverSlow", isMidOverSlow, ignoreFalseConditions, separator) + + ToString("isMidUnderSlow", isMidUnderSlow, ignoreFalseConditions, separator) + + ToString("isMidCrossedOverSlow", isMidCrossedOverSlow, ignoreFalseConditions, separator) + + ToString("isMidCrossedUnderSlow", isMidCrossedUnderSlow, ignoreFalseConditions, separator) + + // + // Psar ... + ToString("isSARBullish", isSARBullish, ignoreFalseConditions, separator) + + ToString("isSARBearish", isSARBearish, ignoreFalseConditions, separator) + + ToString("isSARSwitchedToBullish", isSARSwitchedToBullish, ignoreFalseConditions, separator) + + ToString("isSARSwitchedToBearish", isSARSwitchedToBearish, ignoreFalseConditions, separator) + + // + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XMATD"; + } +}; + +// +// Indicator Class ... + +class XSCXMATDHelper : public XSCBase +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XSCXMATDHelper( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period // Trading TimeFrame + ) + { + // + mSymbol = symbol; + mPeriod = period; + } + + // + // Deconstructor ... + void ~XSCXMATDHelper() {} + + // + // Initialize Indicator ... + bool Init( + XMATDInputs &inputs // Indicator Properties + ) + { + // + bool result = false; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + // Set Inputs ... + this.mInputs = inputs; + + // + // Validate Indicator State ... + result = this.IsValid(); + if (!result) + { + return result; + } + + // + result = DefineBuffers(); + if (!result) + { + return result; + } + + // + fastHandler = iMA( + mSymbol, + mPeriod, + mInputs.fastLength, + mInputs.shift, + mInputs.method, + mInputs.appliedTo // + ); + midHandler = iMA( + mSymbol, + mPeriod, + mInputs.midLength, + mInputs.shift, + mInputs.method, + mInputs.appliedTo // + ); + slowHandler = iMA( + mSymbol, + mPeriod, + mInputs.slowLength, + mInputs.shift, + mInputs.method, + mInputs.appliedTo // + ); + result = + // + fastHandler != INVALID_HANDLE && + midHandler != INVALID_HANDLE && + slowHandler != INVALID_HANDLE + // + ; + if (!result) + { + return result; + } + + // + sarHandler = iSAR( + _Symbol, + _Period, + mInputs.step, + mInputs.maximum // + ); + result = sarHandler != INVALID_HANDLE; + + // + return result; + } + + // + XMATDInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XMATDInputs &inputs // Indicator Properties + ) + { + return Init(inputs); + } + + // + // Get Tag ... + string GetTag() + { + // + string result = NULL; + + // + result = GetToken(); + + // + return result; + } + + // + // Get Token ... + string GetToken() + { + // + string result = NULL; + + // + result = GetSpecificToken(this); + + // + return result; + } + + // + string GetSymbol() + { + return mSymbol; + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return mPeriod; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + mInputs.IsValid() && + IsSpecifiedValid(mPeriod) && + IsSpecifiedValid(mSymbol) + // + ; + + // + return result; + } + + // + // De Initialize Class ... + void DeInit(int reason) + { + // + IndicatorRelease(fastHandler); + IndicatorRelease(midHandler); + IndicatorRelease(slowHandler); + } + + // + // Tools ... + int CopyData( + ENUM_XMATD_BUFFERS line, + double &dest[], + int start = 0, + int count = 1 // + ) + { + // + int result = 0; + + // + int mHandler = INVALID_HANDLE; + switch (line) + { + // + case XMATD_FAST_LINE: + mHandler = fastHandler; + break; + + // + case XMATD_MID_LINE: + mHandler = midHandler; + break; + + // + case XMATD_SLOW_LINE: + mHandler = slowHandler; + break; + + // + case XMATD_PSAR_LINE: + mHandler = sarHandler; + break; + } + + // + if (mHandler == INVALID_HANDLE) + { + return result; + } + + // + result = CopyBuffer( + mHandler, + 0, + start, + count, + dest // + ); + + // + return result; + } + + // + bool GetConditions( + XMATDConditions &conditions, // + int barIndex = 0, // + int loopback = 3 // + ) + { + // + bool result = true; + + // + if (loopback < 3) + { + loopback = 3; + } + + // + conditions.Clean(); + + // + conditions.symbol = mSymbol; + conditions.period = mPeriod; + conditions.time = TimeCurrent(); + + // + int zIndex = barIndex; + int cIndex = zIndex + 1; + int pIndex = cIndex + 1; + int ppIndex = pIndex + 1; + + // + CopyData( + XMATD_FAST_LINE, + conditions.fast, + zIndex, + loopback // + ); + CopyData( + XMATD_MID_LINE, + conditions.mid, + zIndex, + loopback // + ); + CopyData( + XMATD_SLOW_LINE, + conditions.slow, + zIndex, + loopback // + ); + + // + // Calculate Conditions ... + + // + // Trend ... + + // + bool isBullish = conditions.fast[cIndex] > conditions.mid[cIndex] && + conditions.mid[cIndex] > conditions.slow[cIndex]; + bool isBearish = conditions.fast[cIndex] < conditions.mid[cIndex] && + conditions.mid[cIndex] < conditions.slow[cIndex]; + + // + bool isBullishPrev = conditions.fast[pIndex] > conditions.mid[pIndex] && + conditions.mid[pIndex] > conditions.slow[pIndex]; + bool isBearishPrev = conditions.fast[pIndex] < conditions.mid[pIndex] && + conditions.mid[pIndex] < conditions.slow[pIndex]; + + // + bool isSwitchedToBullish = isBullish && + !isBullishPrev; + bool isSwitchedToBearish = isBearish && + !isBearishPrev; + + // + // Set Conditions to Structure ... + conditions.isBullish = isBullish; + conditions.isBearish = isBearish; + conditions.isSwitchedToBullish = isSwitchedToBullish; + conditions.isSwitchedToBearish = isSwitchedToBearish; + + // + // Fast Mid ... + + // + bool isFastOverMid = conditions.fast[cIndex] > conditions.mid[cIndex]; + bool isFastUnderMid = conditions.fast[cIndex] < conditions.mid[cIndex]; + + // + bool isFastOverMidPrev = conditions.fast[pIndex] > conditions.mid[pIndex]; + bool isFastUnderMidPrev = conditions.fast[pIndex] < conditions.mid[pIndex]; + + // + bool isFastCrossedOverMid = isFastOverMid && + !isFastOverMidPrev; + bool isFastCrossedUnderMid = isFastUnderMid && + !isFastUnderMidPrev; + + // + conditions.isFastOverMid = isFastOverMid; + conditions.isFastUnderMid = isFastUnderMid; + conditions.isFastCrossedOverMid = isFastCrossedOverMid; + conditions.isFastCrossedUnderMid = isFastCrossedUnderMid; + + // + // Fast Slow ... + + // + bool isFastOverSlow = conditions.fast[cIndex] > conditions.slow[cIndex]; + bool isFastUnderSlow = conditions.fast[cIndex] < conditions.slow[cIndex]; + + // + bool isFastOverSlowPrev = conditions.fast[pIndex] > conditions.slow[pIndex]; + bool isFastUnderSlowPrev = conditions.fast[pIndex] < conditions.slow[pIndex]; + + // + bool isFastCrossedOverSlow = isFastOverSlow && + !isFastOverSlowPrev; + bool isFastCrossedUnderSlow = isFastUnderSlow && + !isFastUnderSlowPrev; + + // + conditions.isFastOverSlow = isFastOverSlow; + conditions.isFastUnderSlow = isFastUnderSlow; + conditions.isFastCrossedOverSlow = isFastCrossedOverSlow; + conditions.isFastCrossedUnderSlow = isFastCrossedUnderSlow; + + // + // Mid Slow ... + + // + bool isMidOverSlow = conditions.mid[cIndex] > conditions.slow[cIndex]; + bool isMidUnderSlow = conditions.mid[cIndex] < conditions.slow[cIndex]; + + // + bool isMidOverSlowPrev = conditions.mid[pIndex] > conditions.slow[pIndex]; + bool isMidUnderSlowPrev = conditions.mid[pIndex] < conditions.slow[pIndex]; + + // + bool isMidCrossedOverSlow = isMidOverSlow && + !isMidOverSlowPrev; + bool isMidCrossedUnderSlow = isMidUnderSlow && + !isMidUnderSlowPrev; + + // + conditions.isMidOverSlow = isMidOverSlow; + conditions.isMidUnderSlow = isMidUnderSlow; + conditions.isMidCrossedOverSlow = isMidCrossedOverSlow; + conditions.isMidCrossedUnderSlow = isMidCrossedUnderSlow; + + // + // PSar ... + + // + CopyData( + XMATD_PSAR_LINE, + conditions.psar, + zIndex, + loopback // + ); + + // + XOHCL cBar; + cBar.Init( + mSymbol, + mPeriod, + cIndex // + ); + + // + XOHCL pBar; + pBar.Init( + mSymbol, + mPeriod, + pIndex // + ); + + // + bool isSARBullish = conditions.psar[cIndex] < cBar.low; + bool isSARBearish = conditions.psar[cIndex] > cBar.high; + + // + bool isSARBullishPrev = conditions.psar[pIndex] < pBar.low; + bool isSARBearishPrev = conditions.psar[pIndex] > pBar.high; + + // + bool isSARSwitchedToBullish = isSARBullish && + !isSARBullishPrev; + bool isSARSwitchedToBearish = isSARBearish && + !isSARBearishPrev; + + // + conditions.isSARBullish = isSARBullish; + conditions.isSARBearish = isSARBearish; + conditions.isSARSwitchedToBullish = isSARSwitchedToBullish; + conditions.isSARSwitchedToBearish = isSARSwitchedToBearish; + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + int fastHandler; + int midHandler; + int slowHandler; + + // + int sarHandler; + + // + // Tools ... + bool DefineBuffers() + { + // + bool result = false; + + // + result = true; + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + // + string mSymbol; // Symbol + ENUM_TIMEFRAMES mPeriod; // TimeFrame + + // + XMATDInputs mInputs; // Properties +}; + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.cycle.mq5 b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.cycle.mq5 new file mode 100644 index 0000000..d724dd2 --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.cycle.mq5 @@ -0,0 +1,1211 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XPV +// Description: Peaks and Vales ... +// +// +// 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 XPV Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "XPV" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Makret Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +input group "Fibonacci"; +input double fiboLevel1 = 0.236; // Fibio 1st Level +input double fiboLevel2 = 0.382; // Fibio 2st Level +input double fiboLevel3 = 0.5; // Fibio 3rd Level +input double fiboLevel4 = 0.618; // Fibio 4th Level +input double fiboLevel5 = 0.764; // Fibio 5th Level + +// +input group "Boundary Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showConsolidations = false; // Show Consolidations +input bool showFibo1Levels = false; // Show Fibo 1st Level +input bool showFibo2Levels = false; // Show Fibo 2nd Level +input bool showFibo3Levels = false; // Show Fibo 3rd Level +input bool showFibo4Levels = false; // Show Fibo 4th Level +input bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 32 +#property indicator_plots 32 + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "XPV FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "XPV FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define scHHBufferIndex 16 +#define scHHBufferPlotIndex 9 +double scHHBuffer[]; + +// +#define scHHColorBufferIndex 17 +double scHHColorBuffer[]; + +// +#property indicator_label10 "XPV SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define scLLBufferIndex 18 +#define scLLBufferPlotIndex 10 +double scLLBuffer[]; + +// +#define scLLColorBufferIndex 19 +double scLLColorBuffer[]; + +// +#property indicator_label11 "XPV SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mcHHBufferIndex 20 +#define mcHHBufferPlotIndex 11 +double mcHHBuffer[]; + +// +#define mcHHColorBufferIndex 21 +double mcHHColorBuffer[]; + +// +#property indicator_label12 "XPV MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mcLLBufferIndex 22 +#define mcLLBufferPlotIndex 12 +double mcLLBuffer[]; + +// +#define mcLLColorBufferIndex 23 +double mcLLColorBuffer[]; + +// +#property indicator_label13 "XPV MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lcHHBufferIndex 24 +#define lcHHBufferPlotIndex 13 +double lcHHBuffer[]; + +// +#define lcHHColorBufferIndex 25 +double lcHHColorBuffer[]; + +// +#property indicator_label14 "XPV LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lcLLBufferIndex 26 +#define lcLLBufferPlotIndex 14 +double lcLLBuffer[]; + +// +#define lcLLColorBufferIndex 27 +double lcLLColorBuffer[]; + +// +#property indicator_label15 "XPV LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hcHHBufferIndex 28 +#define hcHHBufferPlotIndex 15 +double hcHHBuffer[]; + +// +#define hcHHColorBufferIndex 29 +double hcHHColorBuffer[]; + +// +#property indicator_label16 "XPV HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hcLLBufferIndex 30 +#define hcLLBufferPlotIndex 16 +double hcLLBuffer[]; + +// +#define hcLLColorBufferIndex 31 +double hcLLColorBuffer[]; + +// +#property indicator_label17 "XPV HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +double mHideColorIDX = 0; + +// +XMarketCycle sc; +double mLastSCHH = 0; +double mLastSCLL = 0; + +// +XMarketCycle mc; +double mLastMCHH = 0; +double mLastMCLL = 0; + +// +XMarketCycle lc; +double mLastLCHH = 0; +double mLastLCLL = 0; + +// +XMarketCycle hc; +double mLastHCHH = 0; +double mLastHCLL = 0; + +// +double lastPeak = 0; +double lastVale = 0; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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 ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... + // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + 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; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(sc.length, mc.length); + result = MathMax(result, lc.length); + result = MathMax(result, hc.length); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scHHColorBuffer, true); + SetIndexBuffer(scHHColorBufferIndex, scHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scLLColorBuffer, true); + SetIndexBuffer(scLLColorBufferIndex, scLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcHHColorBuffer, true); + SetIndexBuffer(mcHHColorBufferIndex, mcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcLLColorBuffer, true); + SetIndexBuffer(mcLLColorBufferIndex, mcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcHHColorBuffer, true); + SetIndexBuffer(lcHHColorBufferIndex, lcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcLLColorBuffer, true); + SetIndexBuffer(lcLLColorBufferIndex, lcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hcHHBuffer, true); + SetIndexBuffer(hcHHBufferIndex, hcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcHHColorBuffer, true); + SetIndexBuffer(hcHHColorBufferIndex, hcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hcLLBuffer, true); + SetIndexBuffer(hcLLBufferIndex, hcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcLLColorBuffer, true); + SetIndexBuffer(hcLLColorBufferIndex, hcLLColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Cycles ... + CalculateCycles(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// Custom ... + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Short ... + result = sc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_SHORT, + scMethod, + scPeriod + // + ); + if (!result) + { + return result; + } + + // + // Medium ... + result = mc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_MEDIUM, + mcMethod, + mcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Long ... + result = lc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_LONG, + lcMethod, + lcPeriod + // + ); + if (!result) + { + return result; + } + + // + // Hind ... + result = hc.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_HIND, + hcMethod, + hcPeriod + // + ); + + // + return result; +} + +// +// Calculate Specified Cycles HH and LL ... +void CalculateCycle( + int barIndex, + XMarketCycle &cycle, + double &lastHH, + double &hhBuffer[], + double &hhColorBuffer[], + double &lastLL, + double &llBuffer[], + double &llColorBuffer[] // +) +{ + // + cycle.Update(barIndex); + + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + barIndex + // + ); + + // + double hhValue = bar.FindHighest( + cycle.length, + hhMode + // + ); + hhBuffer[barIndex] = hhValue; + + // + double hhColorIDX = + !showLevels + ? mHideColorIDX + : (hhValue == lastHH) + ? !showConsolidations + ? mHideColorIDX + : 1 + : hhValue > lastHH + ? 2 + : hhValue < lastHH + ? 3 + : mHideColorIDX; + hhColorBuffer[barIndex] = hhColorIDX; + + // + lastHH = hhValue; + + // + double llValue = bar.FindLowest( + cycle.length, + llMode + // + ); + llBuffer[barIndex] = llValue; + + // + double llColorIDX = + !showLevels + ? mHideColorIDX + : (llValue == lastLL) + ? !showConsolidations + ? mHideColorIDX + : 1 + : llValue > lastLL + ? 2 + : llValue < lastLL + ? 3 + : mHideColorIDX; + llColorBuffer[barIndex] = llColorIDX; + + // + lastLL = llValue; +} + +// +// Calculate Cycles Up and Down Boundaries ... +void CalculateCycles( + int barIndex // Bar Index +) +{ + // + // Short ... + CalculateCycle( + barIndex, + sc, + // + mLastSCHH, + scHHBuffer, + scHHColorBuffer, + // + mLastSCLL, + scLLBuffer, + scLLColorBuffer + // + ); + + // + // Medium ... + CalculateCycle( + barIndex, + mc, + // + mLastMCHH, + mcHHBuffer, + mcHHColorBuffer, + // + mLastMCLL, + mcLLBuffer, + mcLLColorBuffer + // + ); + + // + // Long ... + CalculateCycle( + barIndex, + lc, + // + mLastLCHH, + lcHHBuffer, + lcHHColorBuffer, + // + mLastLCLL, + lcLLBuffer, + lcLLColorBuffer + // + ); + + // + // Hind ... + CalculateCycle( + barIndex, + hc, + // + mLastHCHH, + hcHHBuffer, + hcHHColorBuffer, + // + mLastHCLL, + hcLLBuffer, + hcLLColorBuffer + // + ); +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int barIndex // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double scHHValue = scHHBuffer[barIndex]; + double scLLValue = scLLBuffer[barIndex]; + + // + // Medium ... + double mcHHValue = mcHHBuffer[barIndex]; + double mcLLValue = mcLLBuffer[barIndex]; + + // + // Long ... + double lcHHValue = lcHHBuffer[barIndex]; + double lcLLValue = lcLLBuffer[barIndex]; + + // + // Hind ... + double hcHHValue = hcHHBuffer[barIndex]; + double hcLLValue = hcLLBuffer[barIndex]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (scHHValue + mcHHValue + lcHHValue + hcHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hcHHValue && + hcHHValue == lcHHValue && + lcHHValue == mcHHValue && + mcHHValue == scHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + } + + // + // SUPPORT ... + double sValue = (scLLValue + mcLLValue + lcLLValue + hcLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hcLLValue && + hcLLValue == lcLLValue && + lcLLValue == mcLLValue && + mcLLValue == scLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + + // + lastVale = sValue; + } + + // + rBuffer[barIndex] = rValue; + sBuffer[barIndex] = sValue; + peaksBuffer[barIndex] = lastPeak; + valesBuffer[barIndex] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[barIndex] = rColorIDX; + sColorBuffer[barIndex] = sColorIDX; + } + else + { + // + rColorBuffer[barIndex] = mHideColorIDX; + sColorBuffer[barIndex] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int barIndex // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[barIndex]; + double downPrice = valesBuffer[barIndex]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[barIndex] = fibLevel1Value; + fl2Buffer[barIndex] = fibLevel2Value; + fl3Buffer[barIndex] = fibLevel3Value; + fl4Buffer[barIndex] = fibLevel4Value; + fl5Buffer[barIndex] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[barIndex] = fl1ColorIdx; + fl2ColorBuffer[barIndex] = fl2ColorIdx; + fl3ColorBuffer[barIndex] = fl3ColorIdx; + fl4ColorBuffer[barIndex] = fl4ColorIdx; + fl5ColorBuffer[barIndex] = fl5ColorIdx; +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.length.mq5 b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.length.mq5 new file mode 100644 index 0000000..038dfbf --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-saherelm.xpv.length.mq5 @@ -0,0 +1,1292 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XPV +// Description: Peaks and Vales ... +// +// +// 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 XPV Indicator" +#property strict + +// +// Definitions ... + +// +#define ShortName "XPV" + +// +// Includes Common Library ... +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Makret Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period +// input int scLength = 0; // Length + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period +// input int mcLength = 0; // Length + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period +// input int lcLength = 0; // Length + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period +// input int hcLength = 0; // Length + +// +input group "Fibonacci"; +input double fiboLevel1 = 0.236; // Fibio 1st Level +input double fiboLevel2 = 0.382; // Fibio 2st Level +input double fiboLevel3 = 0.5; // Fibio 3rd Level +input double fiboLevel4 = 0.618; // Fibio 4th Level +input double fiboLevel5 = 0.764; // Fibio 5th Level + +// +input group "Boundary Detection Modes"; +input ENUM_SERIESMODE hhMode = MODE_HIGH; // Highest High Calculation Method +input ENUM_SERIESMODE llMode = MODE_LOW; // Lowest Low Calculation Method + +// +input group "Presentation"; +input bool showPeaksAndVales = true; // Show Peaks and Vales +input bool showLevels = false; // Show Levels +input bool showConsolidations = false; // Show Consolidations +input bool showFibo1Levels = false; // Show Fibo 1st Level +input bool showFibo2Levels = false; // Show Fibo 2nd Level +input bool showFibo3Levels = false; // Show Fibo 3rd Level +input bool showFibo4Levels = false; // Show Fibo 4th Level +input bool showFibo5Levels = false; // Show Fibo 5th Level + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 32 +#property indicator_plots 32 + +// +// PEAKS ... + +// +#define peaksBufferIndex 0 +double peaksBuffer[]; + +// +#property indicator_label1 "XPV PEAKS" +#property indicator_type1 DRAW_ARROW +#property indicator_color1 clrAqua +#property indicator_width1 1 + +// +// VALES ... + +// +#define valesBufferIndex 1 +double valesBuffer[]; + +// +#property indicator_label2 "XPV VALES" +#property indicator_type2 DRAW_ARROW +#property indicator_color2 clrMagenta +#property indicator_width2 1 + +// +#define rBufferIndex 2 +double rBuffer[]; + +// +#define rColorBufferIndex 3 +double rColorBuffer[]; + +// +#property indicator_label3 "XPV R" +#property indicator_type3 DRAW_COLOR_LINE +#property indicator_color3 CLR_NONE, clrAqua +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 + +// +#define sBufferIndex 4 +#define sBufferPlotIndex 3 +double sBuffer[]; + +// +#define sColorBufferIndex 5 +double sColorBuffer[]; + +// +#property indicator_label4 "XPV S" +#property indicator_type4 DRAW_COLOR_LINE +#property indicator_color4 CLR_NONE, clrMagenta +#property indicator_style4 STYLE_DOT +#property indicator_width4 1 + +// +// FIBBO Level 1 ... + +// +#define fl1BufferIndex 6 +#define fl1BufferPlotIndex 4 +double fl1Buffer[]; + +// +#define fl1ColorBufferIndex 7 +double fl1ColorBuffer[]; + +// +#property indicator_label5 "XPV FL1" +#property indicator_type5 DRAW_COLOR_LINE +#property indicator_color5 CLR_NONE, clrGold +#property indicator_style5 STYLE_DASHDOTDOT +#property indicator_width5 1 + +// +// FIBBO Level 2 ... + +// +#define fl2BufferIndex 8 +#define fl2BufferPlotIndex 5 +double fl2Buffer[]; + +// +#define fl2ColorBufferIndex 9 +double fl2ColorBuffer[]; + +// +#property indicator_label6 "XPV FL2" +#property indicator_type6 DRAW_COLOR_LINE +#property indicator_color6 CLR_NONE, clrGold +#property indicator_style6 STYLE_DASHDOTDOT +#property indicator_width6 1 + +// +// FIBBO Level 3 ... + +// +#define fl3BufferIndex 10 +#define fl3BufferPlotIndex 6 +double fl3Buffer[]; + +// +#define fl3ColorBufferIndex 11 +double fl3ColorBuffer[]; + +// +#property indicator_label7 "XPV FL3" +#property indicator_type7 DRAW_COLOR_LINE +#property indicator_color7 CLR_NONE, clrGold +#property indicator_style7 STYLE_DASHDOTDOT +#property indicator_width7 1 + +// +// FIBBO Level 4 ... + +// +#define fl4BufferIndex 12 +#define fl4BufferPlotIndex 7 +double fl4Buffer[]; + +// +#define fl4ColorBufferIndex 13 +double fl4ColorBuffer[]; + +// +#property indicator_label8 "XPV FL4" +#property indicator_type8 DRAW_COLOR_LINE +#property indicator_color8 CLR_NONE, clrGold +#property indicator_style8 STYLE_DASHDOTDOT +#property indicator_width8 1 + +// +// FIBBO Level 5 ... + +// +#define fl5BufferIndex 14 +#define fl5BufferPlotIndex 8 +double fl5Buffer[]; + +// +#define fl5ColorBufferIndex 15 +double fl5ColorBuffer[]; + +// +#property indicator_label9 "XPV FL5" +#property indicator_type9 DRAW_COLOR_LINE +#property indicator_color9 CLR_NONE, clrGold +#property indicator_style9 STYLE_DASHDOTDOT +#property indicator_width9 1 + +// +// LEVELS ... + +// +#define scHHBufferIndex 16 +#define scHHBufferPlotIndex 9 +double scHHBuffer[]; + +// +#define scHHColorBufferIndex 17 +double scHHColorBuffer[]; + +// +#property indicator_label10 "XPV SHH" +#property indicator_type10 DRAW_COLOR_LINE +#property indicator_color10 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style10 STYLE_DOT +#property indicator_width10 1 + +#define scLLBufferIndex 18 +#define scLLBufferPlotIndex 10 +double scLLBuffer[]; + +// +#define scLLColorBufferIndex 19 +double scLLColorBuffer[]; + +// +#property indicator_label11 "XPV SLL" +#property indicator_type11 DRAW_COLOR_LINE +#property indicator_color11 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style11 STYLE_DOT +#property indicator_width11 1 + +// +#define mcHHBufferIndex 20 +#define mcHHBufferPlotIndex 11 +double mcHHBuffer[]; + +// +#define mcHHColorBufferIndex 21 +double mcHHColorBuffer[]; + +// +#property indicator_label12 "XPV MHH" +#property indicator_type12 DRAW_COLOR_LINE +#property indicator_color12 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style12 STYLE_DOT +#property indicator_width12 1 + +// +#define mcLLBufferIndex 22 +#define mcLLBufferPlotIndex 12 +double mcLLBuffer[]; + +// +#define mcLLColorBufferIndex 23 +double mcLLColorBuffer[]; + +// +#property indicator_label13 "XPV MLL" +#property indicator_type13 DRAW_COLOR_LINE +#property indicator_color13 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style13 STYLE_DOT +#property indicator_width13 1 + +// +#define lcHHBufferIndex 24 +#define lcHHBufferPlotIndex 13 +double lcHHBuffer[]; + +// +#define lcHHColorBufferIndex 25 +double lcHHColorBuffer[]; + +// +#property indicator_label14 "XPV LHH" +#property indicator_type14 DRAW_COLOR_LINE +#property indicator_color14 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style14 STYLE_DOT +#property indicator_width14 1 + +// +#define lcLLBufferIndex 26 +#define lcLLBufferPlotIndex 14 +double lcLLBuffer[]; + +// +#define lcLLColorBufferIndex 27 +double lcLLColorBuffer[]; + +// +#property indicator_label15 "XPV LLL" +#property indicator_type15 DRAW_COLOR_LINE +#property indicator_color15 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style15 STYLE_DOT +#property indicator_width15 1 + +// +#define hcHHBufferIndex 28 +#define hcHHBufferPlotIndex 15 +double hcHHBuffer[]; + +// +#define hcHHColorBufferIndex 29 +double hcHHColorBuffer[]; + +// +#property indicator_label16 "XPV HHH" +#property indicator_type16 DRAW_COLOR_LINE +#property indicator_color16 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style16 STYLE_DOT +#property indicator_width16 1 + +// +#define hcLLBufferIndex 30 +#define hcLLBufferPlotIndex 16 +double hcLLBuffer[]; + +// +#define hcLLColorBufferIndex 31 +double hcLLColorBuffer[]; + +// +#property indicator_label17 "XPV HLL" +#property indicator_type17 DRAW_COLOR_LINE +#property indicator_color17 CLR_NONE, clrLightGray, clrAqua, clrMagenta +#property indicator_style17 STYLE_DOT +#property indicator_width17 1 + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +double mHideColorIDX = 0; + +// +// XMarketCycle sc; +int mSCLength = 0; +double mLastSCHH = 0; +double mLastSCLL = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// XMarketCycle mc; +int mMCLength = 0; +double mLastMCHH = 0; +double mLastMCLL = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// XMarketCycle lc; +int mLCLength = 0; +double mLastLCHH = 0; +double mLastLCLL = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// XMarketCycle hc; +int mHCLength = 0; +double mLastHCHH = 0; +double mLastHCLL = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +double lastPeak = 0; +double lastVale = 0; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // 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 ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // 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 +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... + // +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + 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; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mSCLength, mMCLength); + result = MathMax(result, mLCLength); + result = MathMax(result, mHCLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // PEAKS and VALES ... + ENUM_DRAW_TYPE pvDrawType = showPeaksAndVales ? DRAW_ARROW : DRAW_NONE; + + // + // PEAKS ... + ArraySetAsSeries(peaksBuffer, true); + SetIndexBuffer(peaksBufferIndex, peaksBuffer, INDICATOR_DATA); + PlotIndexSetInteger(peaksBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(peaksBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(peaksBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(peaksBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // VALES ... + ArraySetAsSeries(valesBuffer, true); + SetIndexBuffer(valesBufferIndex, valesBuffer, INDICATOR_DATA); + PlotIndexSetInteger(valesBufferIndex, PLOT_ARROW, 225); + PlotIndexSetDouble(valesBufferIndex, PLOT_EMPTY_VALUE, 0); + + // + PlotIndexSetInteger(valesBufferIndex, PLOT_SHOW_DATA, showPeaksAndVales); + PlotIndexSetInteger(valesBufferIndex, PLOT_DRAW_TYPE, pvDrawType); + + // + // SUPPORT and RESISTANCE ... + // + + // + // RESISTANCE ... + ArraySetAsSeries(rBuffer, true); + SetIndexBuffer(rBufferIndex, rBuffer, INDICATOR_DATA); + PlotIndexSetInteger(rBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(rBufferIndex, PLOT_DRAW_BEGIN, maxLength); + + // + // RESISTANCE Color ... + ArraySetAsSeries(rColorBuffer, true); + SetIndexBuffer(rColorBufferIndex, rColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SUPPORT ... + ArraySetAsSeries(sBuffer, true); + SetIndexBuffer(sBufferIndex, sBuffer, INDICATOR_DATA); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(sBufferPlotIndex, PLOT_SHOW_DATA, false); + + // + // SUPPORT Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // FIBBO Levels ... + + // + // LEVEL 1 ... + + // + // Buffer ... + ArraySetAsSeries(fl1Buffer, true); + SetIndexBuffer(fl1BufferIndex, fl1Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl1BufferPlotIndex, PLOT_SHOW_DATA, showFibo1Levels); + + // + // Color ... + ArraySetAsSeries(fl1ColorBuffer, true); + SetIndexBuffer(fl1ColorBufferIndex, fl1ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 2 ... + + // + // Buffer ... + ArraySetAsSeries(fl2Buffer, true); + SetIndexBuffer(fl2BufferIndex, fl2Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl2BufferPlotIndex, PLOT_SHOW_DATA, showFibo2Levels); + + // + // Color ... + ArraySetAsSeries(fl2ColorBuffer, true); + SetIndexBuffer(fl2ColorBufferIndex, fl2ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 3 ... + + // + // Buffer ... + ArraySetAsSeries(fl3Buffer, true); + SetIndexBuffer(fl3BufferIndex, fl3Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl3BufferPlotIndex, PLOT_SHOW_DATA, showFibo3Levels); + + // + // Color ... + ArraySetAsSeries(fl3ColorBuffer, true); + SetIndexBuffer(fl3ColorBufferIndex, fl3ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 4 ... + + // + // Buffer ... + ArraySetAsSeries(fl4Buffer, true); + SetIndexBuffer(fl4BufferIndex, fl4Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl4BufferPlotIndex, PLOT_SHOW_DATA, showFibo4Levels); + + // + // Color ... + ArraySetAsSeries(fl4ColorBuffer, true); + SetIndexBuffer(fl4ColorBufferIndex, fl4ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LEVEL 5 ... + + // + // Buffer ... + ArraySetAsSeries(fl5Buffer, true); + SetIndexBuffer(fl5BufferIndex, fl5Buffer, INDICATOR_DATA); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(fl5BufferPlotIndex, PLOT_SHOW_DATA, showFibo5Levels); + + // + // Color ... + ArraySetAsSeries(fl5ColorBuffer, true); + SetIndexBuffer(fl5ColorBufferIndex, fl5ColorBuffer, INDICATOR_COLOR_INDEX); + + // + // SHORT Buffers ... + + // + // HIGH ... + ArraySetAsSeries(scHHBuffer, true); + SetIndexBuffer(scHHBufferIndex, scHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scHHColorBuffer, true); + SetIndexBuffer(scHHColorBufferIndex, scHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(scLLBuffer, true); + SetIndexBuffer(scLLBufferIndex, scLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(scLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(scLLColorBuffer, true); + SetIndexBuffer(scLLColorBufferIndex, scLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // MEDIUM Buffer ... + + // + // HIGH ... + ArraySetAsSeries(mcHHBuffer, true); + SetIndexBuffer(mcHHBufferIndex, mcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcHHColorBuffer, true); + SetIndexBuffer(mcHHColorBufferIndex, mcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(mcLLBuffer, true); + SetIndexBuffer(mcLLBufferIndex, mcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(mcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(mcLLColorBuffer, true); + SetIndexBuffer(mcLLColorBufferIndex, mcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LONG Buffer ... + + // + // HIGH ... + ArraySetAsSeries(lcHHBuffer, true); + SetIndexBuffer(lcHHBufferIndex, lcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcHHColorBuffer, true); + SetIndexBuffer(lcHHColorBufferIndex, lcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(lcLLBuffer, true); + SetIndexBuffer(lcLLBufferIndex, lcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(lcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(lcLLColorBuffer, true); + SetIndexBuffer(lcLLColorBufferIndex, lcLLColorBuffer, INDICATOR_COLOR_INDEX); + + // + // HIND Buffer ... + + // + // HIGH ... + ArraySetAsSeries(hcHHBuffer, true); + SetIndexBuffer(hcHHBufferIndex, hcHHBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcHHBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcHHColorBuffer, true); + SetIndexBuffer(hcHHColorBufferIndex, hcHHColorBuffer, INDICATOR_COLOR_INDEX); + + // + // LOW ... + ArraySetAsSeries(hcLLBuffer, true); + SetIndexBuffer(hcLLBufferIndex, hcLLBuffer, INDICATOR_DATA); + + // + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_DRAW_BEGIN, maxLength); + PlotIndexSetInteger(hcLLBufferPlotIndex, PLOT_SHOW_DATA, showLevels); + + // + ArraySetAsSeries(hcLLColorBuffer, true); + SetIndexBuffer(hcLLColorBufferIndex, hcLLColorBuffer, INDICATOR_COLOR_INDEX); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculate Buffers ... +void CalculateBuffers( + int bar_index // Selected Bar Index +) +{ + // + // Calculate Cycles ... + CalculateCycles(bar_index); + + // + // Calculate Peaks and Vales ... + CalculatePeaksAndVales(bar_index); + + // + // Calculate Fibonnaci ... + CalculateFibonacci(bar_index); +} + +// +// Custom ... + +// +// Initial Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + if (IsValid(mSCPeriod)) + { + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + if (IsValid(mMCPeriod)) + { + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + if (IsValid(mLCPeriod)) + { + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + } + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + if (IsValid(mHCPeriod)) + { + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + } + + // + result = mSCLength > 0 && + mMCLength > mSCLength && + mLCLength > mMCLength && + mHCLength > mLCLength; + + // + return result; +} + +// +// Calculate Specified Cycles HH and LL ... +void CalculateCycle( + int barIndex, + ENUM_X_MARKET_CYCLES cycle, + double &lastHH, + double &hhBuffer[], + double &hhColorBuffer[], + double &lastLL, + double &llBuffer[], + double &llColorBuffer[] // +) +{ + // + XOHCL bar; + bar.Init( + _Symbol, + _Period, + barIndex + // + ); + + // + int mLength = 0; + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + mLength = mSCLength; + break; + + // + case X_MARKET_CYCLE_MEDIUM: + mLength = mMCLength; + break; + + // + case X_MARKET_CYCLE_LONG: + mLength = mLCLength; + break; + + // + case X_MARKET_CYCLE_HIND: + mLength = mHCLength; + break; + } + + // + if (mLength <= 0) + { + return; + } + + // + double hhValue = bar.FindHighest( + mLength, + hhMode + // + ); + hhBuffer[barIndex] = hhValue; + + // + double hhColorIDX = + !showLevels + ? mHideColorIDX + : (hhValue == lastHH) + ? !showConsolidations + ? mHideColorIDX + : 1 + : hhValue > lastHH + ? 2 + : hhValue < lastHH + ? 3 + : mHideColorIDX; + hhColorBuffer[barIndex] = hhColorIDX; + + // + lastHH = hhValue; + + // + double llValue = bar.FindLowest( + mLength, + llMode + // + ); + llBuffer[barIndex] = llValue; + + // + double llColorIDX = + !showLevels + ? mHideColorIDX + : (llValue == lastLL) + ? !showConsolidations + ? mHideColorIDX + : 1 + : llValue > lastLL + ? 2 + : llValue < lastLL + ? 3 + : mHideColorIDX; + llColorBuffer[barIndex] = llColorIDX; + + // + lastLL = llValue; +} + +// +// Calculate Cycles Up and Down Boundaries ... +void CalculateCycles( + int barIndex // Bar Index +) +{ + // + // Short ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_SHORT, + // + mLastSCHH, + scHHBuffer, + scHHColorBuffer, + // + mLastSCLL, + scLLBuffer, + scLLColorBuffer + // + ); + + // + // Medium ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_MEDIUM, + // + mLastMCHH, + mcHHBuffer, + mcHHColorBuffer, + // + mLastMCLL, + mcLLBuffer, + mcLLColorBuffer + // + ); + + // + // Long ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_LONG, + // + mLastLCHH, + lcHHBuffer, + lcHHColorBuffer, + // + mLastLCLL, + lcLLBuffer, + lcLLColorBuffer + // + ); + + // + // Hind ... + CalculateCycle( + barIndex, + X_MARKET_CYCLE_HIND, + // + mLastHCHH, + hcHHBuffer, + hcHHColorBuffer, + // + mLastHCLL, + hcLLBuffer, + hcLLColorBuffer + // + ); +} + +// +// Calculate Peaks and Values ... +void CalculatePeaksAndVales( + int barIndex // Bar Index +) +{ + // + // Retrieve Requirements ... + + // + // Short ... + double scHHValue = scHHBuffer[barIndex]; + double scLLValue = scLLBuffer[barIndex]; + + // + // Medium ... + double mcHHValue = mcHHBuffer[barIndex]; + double mcLLValue = mcLLBuffer[barIndex]; + + // + // Long ... + double lcHHValue = lcHHBuffer[barIndex]; + double lcLLValue = lcLLBuffer[barIndex]; + + // + // Hind ... + double hcHHValue = hcHHBuffer[barIndex]; + double hcLLValue = hcLLBuffer[barIndex]; + + // + double rColorIDX = mHideColorIDX; + double sColorIDX = mHideColorIDX; + + // + // RESISTANCE ... + double rValue = (scHHValue + mcHHValue + lcHHValue + hcHHValue) / 4; + + // + // PEAKS ... + bool isPeak = rValue == hcHHValue && + hcHHValue == lcHHValue && + lcHHValue == mcHHValue && + mcHHValue == scHHValue; + + // + if (isPeak && lastPeak != rValue) + { + // + rColorIDX = 1; + lastPeak = rValue; + } + + // + // SUPPORT ... + double sValue = (scLLValue + mcLLValue + lcLLValue + hcLLValue) / 4; + + // + // VALES ... + bool isVale = sValue == hcLLValue && + hcLLValue == lcLLValue && + lcLLValue == mcLLValue && + mcLLValue == scLLValue; + + // + if (isVale && lastVale != sValue) + { + // + sColorIDX = 1; + + // + lastVale = sValue; + } + + // + rBuffer[barIndex] = rValue; + sBuffer[barIndex] = sValue; + peaksBuffer[barIndex] = lastPeak; + valesBuffer[barIndex] = lastVale; + + // + if (showPeaksAndVales) + { + // + rColorBuffer[barIndex] = rColorIDX; + sColorBuffer[barIndex] = sColorIDX; + } + else + { + // + rColorBuffer[barIndex] = mHideColorIDX; + sColorBuffer[barIndex] = mHideColorIDX; + } +} + +// +// Calculate Fibonacci Level 1 ... +void CalculateFibonacci( + int barIndex // Bar Index +) +{ + // + // Select Requirements ... + double upPrice = peaksBuffer[barIndex]; + double downPrice = valesBuffer[barIndex]; + + // + // Level 1 ... + double fibLevel1Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel1, + 1); + // + // Level 2 ... + double fibLevel2Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel2, + 1); + + // + // Level 3 ... + double fibLevel3Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel3, + 1); + + // + // Level 4 ... + double fibLevel4Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel4, + 1); + + // + // Level 5 ... + double fibLevel5Value = GetFibonacciLevel( + upPrice, + downPrice, + fiboLevel5, + 1); + + // + fl1Buffer[barIndex] = fibLevel1Value; + fl2Buffer[barIndex] = fibLevel2Value; + fl3Buffer[barIndex] = fibLevel3Value; + fl4Buffer[barIndex] = fibLevel4Value; + fl5Buffer[barIndex] = fibLevel5Value; + + // + double fl1ColorIdx = showFibo1Levels ? 1 : mHideColorIDX; + double fl2ColorIdx = showFibo2Levels ? 1 : mHideColorIDX; + double fl3ColorIdx = showFibo3Levels ? 1 : mHideColorIDX; + double fl4ColorIdx = showFibo4Levels ? 1 : mHideColorIDX; + double fl5ColorIdx = showFibo5Levels ? 1 : mHideColorIDX; + + // + fl1ColorBuffer[barIndex] = fl1ColorIdx; + fl2ColorBuffer[barIndex] = fl2ColorIdx; + fl3ColorBuffer[barIndex] = fl3ColorIdx; + fl4ColorBuffer[barIndex] = fl4ColorIdx; + fl5ColorBuffer[barIndex] = fl5ColorIdx; +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-sample.ea.mq5 b/BKPS/14030412/Documents/BKP/Old/x-sample.ea.mq5 new file mode 100644 index 0000000..037efcc --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-sample.ea.mq5 @@ -0,0 +1,619 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XSAMPLE MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XSAMPLE +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XSAMPLE" +#property strict + +// +#include "../Libraries/x-saherelm.draw.lib.mq5" +#include "../Classes/x-saherelm.xalert.class.mq5" +#include "../Classes/x-saherelm.xtrade.class.mq5" +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +#define ShortName "XSAMPLE" + +// +int pivotLifeTime = 20; +int pivotBreakoutsLifeTime = 10; +ENUM_TIMEFRAMES destPEriod = PERIOD_H4; + +// +int xAge = 0; + +// +double lastHH = 0; +double lastUpper = 0; +double lastDestHH = 0; + +// +double lastLL = 0; +double lastLower = 0; +double lastDestLL = 0; + +// +datetime lastTime = NULL; +datetime lastDestTime = NULL; + +// +XSCAlert *mAlert; +XSCTrade *mTrader; + +// +XBarTracker xBarTracker; +XMarketCycle xDestCycle; + +// +// Initialization ... +int OnInit() +{ + // + drawPrefix = ShortName; + + // + if (!InitialEA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XSampleEA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + if (!xBarTracker.IsNewBar()) + { + return; + } + + // + xDestCycle.Update(0); + + // + Analyze(); + + // + ManxAge(); +} + +// +// + +// +bool InitialEA() +{ + // + bool result = false; + + // + mAlert = new XSCAlert(); + mAlert.SetLogAlerts(true); + mAlert.SetPrefix(ShortName); + mAlert.SetEnableAlerts(true); + mAlert.SetPushAlerts(false); + mAlert.SetMailAlerts(false); + mAlert.SetTerminalAlerts(false); + + // + mTrader = new XSCTrade( + 10, + 78692110, + 0, + 0, + 0 // + ); + + // + result = xBarTracker.Init( + _Symbol, + _Period // + ); + if (!result) + { + return result; + } + + // + result = xDestCycle.Init( + _Symbol, + _Period, + X_MARKET_CYCLE_MEDIUM, + X_PERIOD_MANUALLY, + destPEriod, + "DEST" // + ); + if (!result) + { + return result; + } + + // + result = true; + + // + return result; +} + +// +void Analyze() +{ + // + XOHCL cBar; + cBar.Init( + _Symbol, + _Period, + 1 // + ); + + // + if (IsLookingForBoundary()) + { + FindBoundary(); + return; + } + + // + double longSLPrice = 0; + double shortSLPrice = 0; + + // // + // xAge = 0; + // if (IsValid(lastTime)) + // { + // // + // xAge = iBarShift( + // _Symbol, + // _Period, + // lastTime // + // ); + // } + + // // + // if (xAge > pivotBreakoutsLifeTime) + // { + // // + // lastHH = cBar.FindHighest( + // xAge - 1, + // MODE_HIGH // + // ); + + // // + // lastLL = cBar.FindLowest( + // xAge - 1, + // MODE_LOW // + // ); + + // // + // DrawPivot(lastLL, clrAqua, "PVB_L_", true); + // DrawPivot(lastHH, clrMagenta, "PVB_H_", true); + // } + + // + // Detect Breakouts for Long ... + // - Upper Must Breaked as Resistance ... + // - Lower Must Rejects as Support ... + + // // + // bool isSupRejected = cBar.IsSupportRejected(lastLower); + // bool isResBreaked = cBar.IsResistanceBreaked(lastUpper); + // bool isLastLLRejectedAsSupport = cBar.IsSupportRejected(lastDestLL); + // bool isLastHHBreakedAsResistance = cBar.IsResistanceBreaked(lastDestHH); + + // // + // bool hasLong = + // // + // cBar.HasStrongBody() && + // ( + // // + // (isLastLLRejectedAsSupport + // // + // || + // // + // isLastHHBreakedAsResistance) + // // + // || + // // + // (cBar.GetMid() > MathMax(lastLower, lastUpper) && + // (isResBreaked + // // + // || + // // + // isSupRejected)) + // // + // ) + // // + // ; + + // // + // if (hasLong) + // { + // // + // longSLPrice = isResBreaked + // ? lastUpper + // : isLastHHBreakedAsResistance + // ? lastDestHH + // : isSupRejected + // ? lastLower + // : lastDestLL; + // } + + // + // Detect Breakouts for Long ... + // - Upper Must Rejects as Resistance ... + // - Lower Must Breaked as Support ... + + // // + // bool isResRejected = cBar.IsResistanceRejected(lastUpper); + // bool isSupBreaked = cBar.IsSupportBreaked(lastLower); + // bool isLastLLBreadedAsSupport = cBar.IsSupportBreaked(lastDestLL); + // bool isLastHHRejectedAsResistance = cBar.IsResistanceRejected(lastDestHH); + + // // + // bool hasShort = + // // + // cBar.HasStrongBody() && + // ( + // // + // (isLastLLBreadedAsSupport + // // + // || + // // + // isLastHHRejectedAsResistance) + // // + // || + // // + // (cBar.GetMid() < MathMin(lastLower, lastUpper) && + // (isSupBreaked + // // + // || + // // + // isResRejected)) + // // + // ) + // // + // ; + + // // + // if (hasShort) + // { + // // + // shortSLPrice = isSupBreaked + // ? lastLower + // : isLastLLBreadedAsSupport + // ? lastDestLL + // : isResRejected + // ? lastUpper + // : lastDestHH; + // } + + // + // + bool hasLong = false; + bool hasShort = false; + + // + bool hasSignal = hasLong || hasShort; + if (hasSignal) + { + // + double slPrice = + hasLong + ? longSLPrice + : shortSLPrice; + // double slPrice = + // hasLong + // ? shortSLPrice + // : longSLPrice; + + // + ENUM_POSITION_TYPE mType = + hasLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL + // + ; + // ENUM_POSITION_TYPE mType = + // hasLong + // ? POSITION_TYPE_BUY + // : POSITION_TYPE_SELL + // // + // ; + + // + double mEntry = GetEntry( + _Symbol, + mType // + ); + + // + double priceToRisk = PointToPrice(30, _Symbol); + double priceToReward = PointToPrice(30, _Symbol); + + // + double mSL = 0; + double mTP = 0; + CalculateTPSL( + mSL, + mTP, + mType, + mEntry, + 1, + slPrice, + 0, + priceToRisk, + priceToReward // + ); + + // + // Ignore Zero TP SL ... + if (mTP > 0 && mSL > 0) + { + // + XSignal signal; + bool isPrepared = signal.Prepare( + _Symbol, + "X92", + _Period, + mType, + X_ORDER_MODE_MARKET, + mEntry, + 0.01, + mSL, + mTP // + ); + + // + if (isPrepared) + { + // + ENUM_X_SIGNAL_EXECUTION_RESULT state; + bool isExecuted = mTrader.ExecuteSignal( + signal, + state // + ); + } + } + } + + // + bool resetLast = + xAge > pivotLifeTime || hasSignal; + + // + if (resetLast) + { + // + lastUpper = 0; + lastLower = 0; + + // + RemoveDraws(); + } +} + +// +void ManxAge() +{ + // + return; + double profit = mTrader.Profit(); + if (profit > 50 || profit < -100) + { + // + string comment = "EQM Hedge: " + ToString(profit); + + // + int numberOfClosed = mTrader.Close(comment); + if (numberOfClosed > 0) + { + mAlert.Alert(comment); + } + } +} + +// +bool IsLookingForBoundary() +{ + // + bool result = lastUpper == 0 && lastLower == 0; + return result; +} + +// +void FindBoundary() +{ + // + int zIndex = 0; + int cIndex = 1; + int pIndex = 2; + int ppIndex = 3; + + // + // Detect Inside Bar ... + XOHCL cBar; + cBar.Init( + _Symbol, + _Period, + 1 // + ); + + // + XOHCL cDestBar = xDestCycle.GetBar(1); + + // + if (cDestBar.time != lastDestTime) { + // + lastDestLL = cDestBar.low; + lastDestHH = cDestBar.high; + + // + lastDestTime = cDestBar.time; + + // + DrawPivot(lastUpper, clrOrangeRed, "Pvt_"); + DrawPivot(lastLower, clrLimeGreen, "Pvt_"); + } + + // + // if (cDestBar.IsInsideBar()) + // { + // // + // lastUpper = cDestBar.high; + // lastLower = cDestBar.low; + + // // + // lastTime = TimeCurrent(); + + // // + // DrawPivot(lastUpper, clrOrangeRed, "Pvt_"); + // DrawPivot(lastLower, clrLimeGreen, "Pvt_"); + // } + + // // + // if (lastUpper != cDestBar.high && lastLower != cDestBar.low) + // { + // // + // lastDestHH = cDestBar.high; + // lastDestLL = cDestBar.low; + + // // + // DrawPivot(lastDestLL, clrYellow, "LDST_LL_", true); + // DrawPivot(lastDestHH, clrYellow, "LDST_HH_", true); + + // // + // lastDestTime = TimeCurrent(); + // } + + // + DrawFibo(); +} + +// +void DrawPivot( + double price, + color clr, + string prefix, + bool forceRemove = false // +) +{ + // + long chartID = ChartID(); + datetime time1 = iTime( + _Symbol, + _Period, + 2 // + ); + datetime time = iTime( + _Symbol, + _Period, + 0 // + ); + + // + string pPrefix = prefix + "P_" + + ToString(price); + + // + if (IsDrawExists(prefix) && forceRemove) + { + RemoveDraws(prefix); + } + + // + if (IsDrawExists(pPrefix)) + { + return; + } + + // + DrawTrendLine( + chartID, + pPrefix, + 0, + time1, + price, + time, + price, + clr, + STYLE_SOLID, + 2, + false, + false, + true // + ); +} + +// +void DrawFibo() +{ + // + if (!IsValid(lastDestTime) || lastDestHH == 0 || lastDestLL == 0) + { + return; + } + + // + string name = "LDST_FIb"; + + // + datetime time1 = TimeCurrent(); + datetime time0 = lastDestTime; + + // + RemoveDraw(name); + + // + DrawFibonacci( + ChartID(), + name, + 0, + time0, + lastDestHH, + time1, + lastDestLL, + clrAquamarine, + STYLE_DOT // + ); +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Old/x-zone-test.mq5 b/BKPS/14030412/Documents/BKP/Old/x-zone-test.mq5 new file mode 100644 index 0000000..104f37a --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Old/x-zone-test.mq5 @@ -0,0 +1,263 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XZoneTest MQL5 Expert Advisor +// ------------------------------------------------- +// Name: XZoneTest +// Description: an Exper Advisor which used RSI and MA +// to Analyse Market ... +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +//////////////////////////////////////////////////////x +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XZoneTest" +#property strict + +// +#include "../Classes/x-saherelm.xczone.class.mq5" + +// +#define ShortName "XZoneTest" + +// +// Inputs ... +input int zoneRange = 21; +input ENUM_TIMEFRAMES zonePeriod = PERIOD_M1; + +// +// Variables ... +int barsTotal; + +// +// Initialization ... +int OnInit() +{ + // + if (!InitialEA()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // De Initialize XSampleEA Providers ... +} + +// +// On Tick Handler ... +void OnTick() +{ + // + int bars = iBars( + _Symbol, + zonePeriod // + ); + if (barsTotal == bars) + { + return; + } + + // + barsTotal = bars; + + // + datetime startTime = iTime( + _Symbol, + zonePeriod, + zoneRange + 1 // + ); + datetime endTime = iTime( + _Symbol, + zonePeriod, + 1 // + ); + + // + MqlTick ticks[]; + CopyTicksRange( + _Symbol, + ticks, + COPY_TICKS_ALL, + startTime * 1000, + endTime * 1000 // + ); + + // + double highs[]; + CopyHigh( + _Symbol, + zonePeriod, + startTime, + endTime, + highs // + ); + double iHigh = highs[ArrayMaximum(highs)]; + + // + double lows[]; + CopyLow( + _Symbol, + zonePeriod, + startTime, + endTime, + lows // + ); + double iLow = lows[ArrayMinimum(lows)]; + + // + double iSize = iHigh - iLow; + + // + CArrayObj zones; + int zCount = 10; + for (int i = 0; i < zCount; i++) + { + // + double iH = iHigh - iSize * i / zCount; + double iL = iHigh - iSize * (i + 1) / zCount; + + // + XSCZone *iZone = new XSCZone(); + iZone.high = iH; + iZone.low = iL; + + // + zones.Add(iZone); + } + + // + // Fill Ticks ... + for (int i = 0; i < ArraySize(ticks); i++) + { + // + MqlTick iTick = ticks[i]; + + // + for (int j = 0; j < zones.Total(); j++) + { + // + XSCZone *jZone = zones.At(j); + + // + bool isInRange = iTick.bid >= jZone.low && iTick.bid <= jZone.high; + if (isInRange) + { + // + jZone.ticks++; + break; + } + } + } + + // + // Sorting Zones ... + zones.Sort(); + + // + CArrayObj mChartObjects; + for (int i = 0; i < zones.Total(); i++) + { + // + XSCZone *iZone = zones.At(i); + + // + string iZoneName = "Zone " + IntegerToString(i); + + // + // Create Zone Rectangle ... + CChartObjectRectangle *iRect = new CChartObjectRectangle(); + iRect.Create( + 0, + iZoneName, + 0, + startTime, + iZone.high, + endTime, + iZone.low // + ); + iRect.Fill(true); + + // + // Create Zone Label ... + CChartObjectLabel *iLabel = new CChartObjectLabel(); + iLabel.Create( + 0, + iZoneName + "_lbl", + 0, + startTime, + iZone.high // + ); + iLabel.Color(clrWhite); + + // + // Calculate TickPercent ... + double iZoneTickPercent = (double)iZone.ticks / ArraySize(ticks) * 100; + iZoneTickPercent = NormalizeDouble(iZoneTickPercent, 2); + string iZoneTickPercentStr = (string)iZoneTickPercent + "%"; + + // + iLabel.Description(iZoneTickPercentStr); + + // + if (iZone.ticks > ArraySize(ticks) * 0.15) + { + iRect.Color(clrOrangeRed); + } + else if (iZone.ticks > ArraySize(ticks) * 0.10) + { + iRect.Color(clrOrange); + } + else + { + iRect.Color(clrLightGray); + } + + // + // mChartObjects.Add(iRect); + // mChartObjects.Add(iLabel); + } +} + +// +// + +// +bool InitialEA() +{ + // + bool result = false; + + // + result = true; + + // + return result; +} + +// \ No newline at end of file diff --git a/BKPS/14030412/Documents/BKP/Signal Filters/long filter.mq5 b/BKPS/14030412/Documents/BKP/Signal Filters/long filter.mq5 new file mode 100644 index 0000000..0f4edff --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Signal Filters/long filter.mq5 @@ -0,0 +1,202 @@ + // + // Filter Long Conditions ... + bool FilterLongConditions( + X121SetupConditions &conditions, // Conditions + int pusher, // Pushers + string provider // Provider + ) + { + // + bool result = false; + + // + // Generating Conditions Score ... + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol); + + // + bool isM5Period = conditions.period == PERIOD_M5; + bool isM15Period = conditions.period == PERIOD_M15; + bool isH1Period = conditions.period == PERIOD_H1; + bool isH4Period = conditions.period == PERIOD_H4; + + // + // Set Default Result to True ... + result = true; + + // + // Global Conditions ... + result = + // + result && + // + !( + // + ( + // + // XICH ... + conditions.ichConditions.isClosedUnderKijunSen && + conditions.ichConditions.isTenkanSenOverKijunSen + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isTenkanSenUnderKijunSen + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isSenkouSpanAOverB && + !conditions.ichConditions.isSenkouSpanAOverLast + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isSenkouSpanAUnderB && + conditions.ichConditions.isSenkouSpanAUnderLast + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isSenkouSpanAOverB && + !conditions.ichConditions.isSenkouSpanAOverLast && + conditions.ichConditions.isTenkanSenCrossedOverKijunSen && + // + // XVLM ... + conditions.vlmConditions.isVolumeUnderLast + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isClosedOverKijunSen && + conditions.ichConditions.isTenkanSenOverKijunSen && + conditions.ichConditions.isSenkouSpanAUnderB + // + ) + // + || + // + ( + // + // XPV ... + !conditions.pvConditions.isSCBullish && + !conditions.pvConditions.isSCHHBullish && + !conditions.pvConditions.isSCLLBullish && + !conditions.pvConditions.isMCBullish && + !conditions.pvConditions.isMCHHBullish && + !conditions.pvConditions.isMCLLBullish && + !conditions.pvConditions.isLCBullish && + !conditions.pvConditions.isLCHHBullish && + !conditions.pvConditions.isLCLLBullish && + !conditions.pvConditions.isHCBullish && + !conditions.pvConditions.isHCHHBullish && + !conditions.pvConditions.isHCLLBullish && + // + // XICH ... + conditions.ichConditions.isClosedOverKijunSen && + (conditions.ichConditions.isTenkanSenOverKijunSen || + conditions.ichConditions.isTenkanSenCrossedOverKijunSen) + // + ) + // + || + // + ( + // + ( + // + // XPV ... + conditions.pvConditions.isNewPeak && + conditions.pvConditions.isNewPeakOverLast && + conditions.pvConditions.isFiboIncreased && + conditions.pvConditions.isCloseOverFib1 && + conditions.pvConditions.isCloseOverFib2 && + conditions.pvConditions.isCloseOverFib3 && + conditions.pvConditions.isCloseOverFib4 && + conditions.pvConditions.isCloseOverFib5 + // + ) + // + && + // + ( + // + // XSCORES ... + bearishScore < 5 && + bullishScore > bearishScore * 10 + // + ) + // + && + // + ( + // + ( + // + // XPV ... + conditions.pvConditions.isSCBullish && + conditions.pvConditions.isSCHHBullish && + conditions.pvConditions.isSCLLBullish && + conditions.pvConditions.isMCBullish && + conditions.pvConditions.isMCHHBullish && + conditions.pvConditions.isMCLLBullish && + conditions.pvConditions.isLCBullish && + conditions.pvConditions.isLCHHBullish && + conditions.pvConditions.isLCLLBullish && + conditions.pvConditions.isHCBullish && + conditions.pvConditions.isHCHHBullish && + conditions.pvConditions.isHCLLBullish + // + ) + // + ) + // + ) + // + ) + // + ; + + // + // Apply Filter ... + // Based On Symbol and Period ... + // if necessary ... + if (isGBPUSD) + { + // + // MEDIUM ... + if (isH1Period) + { + } + } + + // + return result; + } diff --git a/BKPS/14030412/Documents/BKP/Signal Filters/short filter.mq5 b/BKPS/14030412/Documents/BKP/Signal Filters/short filter.mq5 new file mode 100644 index 0000000..c161878 --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Signal Filters/short filter.mq5 @@ -0,0 +1,222 @@ + // + // Filter Short Conditions ... + bool FilterShortConditions( + X121SetupConditions &conditions, // Conditions + int pusher, // Pushers + string provider // Provider + ) + { + // + bool result = false; + + // + // Generating Conditions Score ... + double bullishScore = 0; + double bearishScore = 0; + conditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isGBPUSD = symbolParser.IsGBPUSD(conditions.symbol); + + // + bool isM5Period = conditions.period == PERIOD_M5; + bool isM15Period = conditions.period == PERIOD_M15; + bool isH1Period = conditions.period == PERIOD_H1; + bool isH4Period = conditions.period == PERIOD_H4; + + // + // Set Default Result to True ... + result = true; + + // + // Global Conditions ... + result = + // + result && + // + !( + // + ( + // + // XICH ... + conditions.ichConditions.isClosedOverKijunSen && + conditions.ichConditions.isTenkanSenUnderKijunSen + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isTenkanSenOverKijunSen + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isSenkouSpanAUnderB && + !conditions.ichConditions.isSenkouSpanAUnderLast + // + ) + // + || + // + ( + // + // XPV ... + conditions.pvConditions.isNewVale && + conditions.pvConditions.isNewValeUnderLast && + conditions.pvConditions.isFiboDecreased && + conditions.pvConditions.isSCBearish && + !conditions.pvConditions.isMCBearish && + // + // XICH ... + conditions.ichConditions.isClosedOverKijunSen && + // + // XHK ... + conditions.hkConditions.isHKSwitchedToBearish && + conditions.hkConditions.isSMHKSwitchedToBearish + + ) + // + || + // + ( + // + // XPV ... + conditions.pvConditions.isNewVale && + conditions.pvConditions.isNewValeUnderLast && + conditions.pvConditions.isFiboDecreased && + !conditions.pvConditions.isSCBearish && + !conditions.pvConditions.isSCHHBearish && + // + // XVLM ... + conditions.vlmConditions.isVolumeBearish && + !conditions.vlmConditions.isVolumeOverLast + // + ) + // + || + // + ( + // + ( + // + // XPV ... + conditions.pvConditions.isNewVale && + conditions.pvConditions.isNewValeUnderLast && + conditions.pvConditions.isFiboDecreased && + conditions.pvConditions.isCloseUnderFib1 && + conditions.pvConditions.isCloseUnderFib2 && + conditions.pvConditions.isCloseUnderFib3 && + conditions.pvConditions.isCloseUnderFib4 && + conditions.pvConditions.isCloseUnderFib5 + // + ) + // + && + // + ( + // + ( + // + ( + // + // XVLM ... + conditions.vlmConditions.isVolumeBearish && + conditions.vlmConditions.isVolumeOverLast + // + ) + // + && + // + ( + // + ( + // + conditions.pvConditions.isSCBearish && + conditions.pvConditions.isSCHHBearish && + conditions.pvConditions.isSCLLBearish && + conditions.pvConditions.isMCBearish && + conditions.pvConditions.isMCHHBearish && + conditions.pvConditions.isMCLLBearish && + conditions.pvConditions.isLCBearish && + conditions.pvConditions.isLCHHBearish && + conditions.pvConditions.isLCLLBearish && + conditions.pvConditions.isHCBearish && + conditions.pvConditions.isHCHHBearish && + conditions.pvConditions.isHCLLBearish && + // + // XICH ... + conditions.ichConditions.isClosedUnderKijunSen && + conditions.ichConditions.isTenkanSenUnderKijunSen && + conditions.ichConditions.isSenkouSpanAUnderB && + conditions.ichConditions.isSenkouSpanAUnderLast && + conditions.ichConditions.isFutureSenkouSpanAUnderB && + conditions.ichConditions.isFutureSenkouSpanAUnderLast && + conditions.ichConditions.isSenkouSpanACrossedUnderLast + // + ) + // + || + // + ( + // + // XICH ... + conditions.ichConditions.isSenkouSpanACrossedUnderB + // + ) + // + ) + // + ) + // + || + // + ( + // + // XRL ... + conditions.rlConditions.isFastBearish && + conditions.rlConditions.isSlowBearish && + conditions.rlConditions.isFastOverSlow && + conditions.rlConditions.isVerifierBearish + // + ) + // + ) + // + && + // + // XSCORES ... + bullishScore < 5 && + bearishScore > bullishScore * 10 + // + ) + // + ) + // + ; + + // + // Apply Filter ... + // Based On Symbol and Period ... + // if necessary ... + if (isGBPUSD) + { + // + // MEDIUM ... + if (isH1Period) + { + } + } + + // + return result; + } diff --git a/BKPS/14030412/Documents/BKP/Source Codes/CiCustom.mq5 b/BKPS/14030412/Documents/BKP/Source Codes/CiCustom.mq5 new file mode 100644 index 0000000..83b8a3e --- /dev/null +++ b/BKPS/14030412/Documents/BKP/Source Codes/CiCustom.mq5 @@ -0,0 +1,194 @@ +//+------------------------------------------------------------------+ +//| Custom.mqh | +//| Copyright 2000-2024, MetaQuotes Ltd. | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#include "Indicator.mqh" +//+------------------------------------------------------------------+ +//| Class CiCustom. | +//| Purpose: Class of custom indicators. | +//| Derives from class CIndicator. | +//+------------------------------------------------------------------+ +class CiCustom : public CIndicator + { +protected: + int m_num_params; // number of creation parameters + MqlParam m_params[]; // creation parameters + +public: + CiCustom(void); + ~CiCustom(void); + //--- methods of access to protected data + bool NumBuffers(const int buffers); + int NumParams(void) const { return(m_num_params); } + ENUM_DATATYPE ParamType(const int ind) const; + long ParamLong(const int ind) const; + double ParamDouble(const int ind) const; + string ParamString(const int ind) const; + //--- method of identifying + virtual int Type(void) const { return(IND_CUSTOM); } + +protected: + //--- methods of tuning + virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); + }; +//+------------------------------------------------------------------+ +//| Constructor | +//+------------------------------------------------------------------+ +CiCustom::CiCustom(void) : m_num_params(0) + { + } +//+------------------------------------------------------------------+ +//| Destructor | +//+------------------------------------------------------------------+ +CiCustom::~CiCustom(void) + { + } +//+------------------------------------------------------------------+ +//| Set number of buffers of indicator | +//+------------------------------------------------------------------+ +bool CiCustom::NumBuffers(const int buffers) + { + bool result=true; +//--- + if(m_buffers_total==0) + { + m_buffers_total=buffers; + return(true); + } + if(m_buffers_total!=buffers) + { + Shutdown(); + result=CreateBuffers(m_symbol,m_period,buffers); + if(result) + { + //--- create buffers + for(int i=0;i=m_num_params) + return(WRONG_VALUE); +//--- + return(m_params[ind].type); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creatiob as a long value | +//+------------------------------------------------------------------+ +long CiCustom::ParamLong(const int ind) const + { + if(ind>=m_num_params) + return(0); + switch(m_params[ind].type) + { + case TYPE_DOUBLE: + case TYPE_FLOAT: + case TYPE_STRING: + return(0); + } +//--- + return(m_params[ind].integer_value); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creation as a double value | +//+------------------------------------------------------------------+ +double CiCustom::ParamDouble(const int ind) const + { + if(ind>=m_num_params) + return(EMPTY_VALUE); + switch(m_params[ind].type) + { + case TYPE_DOUBLE: + case TYPE_FLOAT: + break; + default: + return(EMPTY_VALUE); + } +//--- + return(m_params[ind].double_value); + } +//+------------------------------------------------------------------+ +//| Get specified parameter of creation as a string value | +//+------------------------------------------------------------------+ +string CiCustom::ParamString(const int ind) const + { + if(ind>=m_num_params || m_params[ind].type!=TYPE_STRING) + return(""); +//--- + return(m_params[ind].string_value); + } +//+------------------------------------------------------------------+ +//| Initialize the indicator with universal parameters | +//+------------------------------------------------------------------+ +bool CiCustom::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) + { + int i; +//--- tune + if(m_buffers_total==0) + m_buffers_total=256; + if(CreateBuffers(symbol,period,m_buffers_total)) + { + //--- string of status of drawing + m_name ="Custom "+params[0].string_value; + m_status="("+symbol+","+PeriodDescription(); + for(i=1;irates_total || prev_calculated<=0) { + limit=rates_total-min_rates_total; + } else { + limit=rates_total-prev_calculated; + } + ArraySetAsSeries(open,true); + ArraySetAsSeries(high,true); + ArraySetAsSeries(low,true); + ArraySetAsSeries(close,true); + +//--- + + for(int i=limit; i>=0 && !IsStopped(); i--) { + BullishDCCPBuffer[i]=0.0; + BearishDCCPBuffer[i]=0.0; + + + BearishDCCPBuffer[0]=0.0; + if(open[i]>close[i] && open[i+1]close[i+1]) + BearishDCCPBuffer[i]=high[i]; + + BullishDCCPBuffer[0]=0.0; + if(open[i]close[i+1] && open[i]=close[i+1] && low[i]open[i]) + crearFlecha(prefix+"Bull_Dominanat"+IntegerToString(i),time[i],low[i+1],clr,225,ANCHOR_TOP); + + if(open[i]>close[i] && open[i+1]>close[i+1] && open[i]<=close[i+1] && high[i]>close[i+1] && low[i+1]