diff --git a/Classes/x-saherelm.x121.setup.class.mq5 b/Classes/x-saherelm.x121.setup.class.mq5 index 0e5129e9..4f392757 100644 --- a/Classes/x-saherelm.x121.setup.class.mq5 +++ b/Classes/x-saherelm.x121.setup.class.mq5 @@ -37,6 +37,7 @@ #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.xasct.helper.mq5" #include "../Helpers/x-saherelm.xsslc.helper.mq5" #include "../Helpers/x-saherelm.xhull.helper.mq5" @@ -67,6 +68,7 @@ enum ENUM_X121_SIGNAL_PROVIDER PROVIDER_XSSLC = 14, PROVIDER_XHULL = 15, PROVIDER_XASCT = 16, + PROVIDER_XVLM = 17, }; // @@ -210,6 +212,7 @@ struct X121SetupInputs XSTRInputs strInputs; // XSTR Inputs XMRBInputs mrbInputs; // XMRB Inputs XOSCInputs oscInputs; // XOSC Inputs + XVLMInputs vlmInputs; // XVLM Inputs XMATDInputs matdInputs; // XMATD Inputs XASCTInputs asctInputs; // XASCT Inputs XSSLCInputs sslcInputs; // XSSLC Inputs @@ -245,6 +248,7 @@ struct X121SetupInputs XSTRInputs &_strInputs, // XSTR Inputs XMRBInputs &_mrbInputs, // XMRB Inputs XOSCInputs &_oscInputs, // XOSC Inputs + XVLMInputs &_vlmInputs, // XVLM Inputs XMATDInputs &_matdInputs, // XMATD Inputs XASCTInputs &_asctInputs, // XASCT Inputs XSSLCInputs &_sslcInputs, // XSSLC Inputs @@ -265,6 +269,7 @@ struct X121SetupInputs this.strInputs = _strInputs; this.mrbInputs = _mrbInputs; this.oscInputs = _oscInputs; + this.vlmInputs = _vlmInputs; this.matdInputs = _matdInputs; this.asctInputs = _asctInputs; this.sslcInputs = _sslcInputs; @@ -297,6 +302,7 @@ struct X121SetupInputs strInputs.Clean(); mrbInputs.Clean(); oscInputs.Clean(); + vlmInputs.Clean(); matdInputs.Clean(); asctInputs.Clean(); sslcInputs.Clean(); @@ -316,6 +322,7 @@ struct X121SetupInputs strInputs.Default(); mrbInputs.Default(); oscInputs.Default(); + vlmInputs.Default(); matdInputs.Default(); asctInputs.Default(); sslcInputs.Default(); @@ -349,66 +356,84 @@ struct X121SetupInputs 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 = matdInputs.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) { @@ -438,6 +463,7 @@ struct X121SetupConditions XICHConditions ichConditions; XSTRConditions strConditions; XMRBConditions mrbConditions; + XVLMConditions vlmConditions; XMATDConditions matdConditions; XASCTConditions asctConditions; XSSLCConditions sslcConditions; @@ -476,6 +502,7 @@ struct X121SetupConditions ichConditions.Clean(); strConditions.Clean(); mrbConditions.Clean(); + vlmConditions.Clean(); matdConditions.Clean(); asctConditions.Clean(); sslcConditions.Clean(); @@ -569,6 +596,14 @@ struct X121SetupConditions bullishScore += tempBullishScore; bearishScore += tempBearishScore; + // + vlmConditions.GenerateScore( + tempBullishScore, + tempBearishScore // + ); + bullishScore += tempBullishScore; + bearishScore += tempBearishScore; + // sslcConditions.GenerateScore( tempBullishScore, @@ -625,32 +660,34 @@ struct X121SetupConditions ); // - string matdSummary = matdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); - string adxtdSummary = adxtdConditions.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 asctSummary = asctConditions.GenerateSummary(false, true, false, ignoreFalseConditions); - string tdSummary = tdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); string ichSummary = ichConditions.GenerateSummary(false, true, false, ignoreFalseConditions); - string hkSummary = hkConditions.GenerateSummary(false, true, false, ignoreFalseConditions); string mrbSummary = mrbConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string vlmSummary = vlmConditions.GenerateSummary(false, true, false, ignoreFalseConditions); + string matdSummary = matdConditions.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 adxtdSummary = adxtdConditions.GenerateSummary(false, true, false, ignoreFalseConditions); // string conditionsStr = // - matdSummary + separator + - adxtdSummary + separator + + tdSummary + separator + + hkSummary + separator + + ichSummary + separator + + mrbSummary + separator + + vlmSummary + separator + strSummary + separator + cheSummary + separator + asctSummary + separator + - tdSummary + separator + - ichSummary + separator + - hkSummary + separator + - mrbSummary + separator + sslcSummary + separator + hullSummary + separator + + matdSummary + separator + + adxtdSummary + separator + "" // ; @@ -818,7 +855,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long1) @@ -846,7 +884,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long2) @@ -872,7 +911,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long3) @@ -899,7 +939,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long4) @@ -926,7 +967,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long5) @@ -953,7 +995,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long6) @@ -982,7 +1025,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long7) @@ -1011,7 +1055,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long8) @@ -1040,7 +1085,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long9) @@ -1068,7 +1114,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long10) @@ -1095,7 +1142,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long11) @@ -1122,7 +1170,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long12) @@ -1149,7 +1198,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBullish && conditions.hkConditions.isSMHKBullish && conditions.sslcConditions.isBullish && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long13) @@ -1176,7 +1226,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBullish && conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && - conditions.hullConditions.isBullish + conditions.hullConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long14) @@ -1203,7 +1254,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBullish && conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && - conditions.sslcConditions.isBullish + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long15) @@ -1231,7 +1283,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBullish && conditions.mrbConditions.isFastOverSlow && conditions.hullConditions.isBullish && - conditions.sslcConditions.isBullish + conditions.sslcConditions.isBullish && + conditions.vlmConditions.isVolumeBullish // ; if (long16) @@ -1241,6 +1294,34 @@ struct X121SignalGenerator provider = ToString(PROVIDER_XASCT); } + // + // XVLM ... + bool long17 = + // + // Starting Conditions ... + conditions.vlmConditions.isVolumeChangedToBullish && + // + // Verifications ... + conditions.tdConditions.isBullish && + conditions.matdConditions.isBullish && + 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 + // + ; + if (long17) + { + // + pusher++; + provider = ToString(PROVIDER_XVLM); + } + // result = // @@ -1311,6 +1392,10 @@ struct X121SignalGenerator // long16 // + || + // + long17 + // ) // ; @@ -1367,7 +1452,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short1) @@ -1395,7 +1481,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short2) @@ -1421,7 +1508,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short3) @@ -1448,7 +1536,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short4) @@ -1475,7 +1564,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short5) @@ -1502,7 +1592,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short6) @@ -1531,7 +1622,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short7) @@ -1560,7 +1652,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short8) @@ -1589,7 +1682,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short9) @@ -1617,7 +1711,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short10) @@ -1644,7 +1739,8 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short11) @@ -1671,7 +1767,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short12) @@ -1698,7 +1795,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBearish && conditions.hkConditions.isSMHKBearish && conditions.sslcConditions.isBearish && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short13) @@ -1725,7 +1823,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBearish && conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && - conditions.hullConditions.isBearish + conditions.hullConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short14) @@ -1752,7 +1851,8 @@ struct X121SignalGenerator conditions.hkConditions.isHKBearish && conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && - conditions.sslcConditions.isBearish + conditions.sslcConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; if (short15) @@ -1780,16 +1880,45 @@ struct X121SignalGenerator conditions.hkConditions.isSMHKBearish && conditions.mrbConditions.isFastUnderSlow && conditions.hullConditions.isBearish && - conditions.sslcConditions.isBearish + conditions.sslcConditions.isBearish && + conditions.vlmConditions.isVolumeBearish // ; - if (short15) + if (short16) { // pusher++; provider = ToString(PROVIDER_XASCT); } + // + // XVLM ... + bool short17 = + // + // Starting Conditions ... + conditions.vlmConditions.isVolumeChangedToBearish && + // + // Verifications ... + conditions.tdConditions.isBearish && + conditions.matdConditions.isBearish && + 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 + // + ; + if (short17) + { + // + pusher++; + provider = ToString(PROVIDER_XVLM); + } + // result = // @@ -1860,6 +1989,10 @@ struct X121SignalGenerator // short16 // + || + // + short17 + // ) // ; @@ -1881,7 +2014,7 @@ struct X121SignalGenerator // // TODO Filter ... - result = true; + result = provider == ToString(PROVIDER_XVLM); // return result; @@ -1900,7 +2033,7 @@ struct X121SignalGenerator // // TODO Filter ... - result = true; + result = provider == ToString(PROVIDER_XVLM); // return result; @@ -1913,6 +2046,7 @@ struct X121SignalGenerator XSignal &signal, // Signal if Exists int &pusher, // Pushers string &provider, // Signal Provider Name + bool _useSupport, // Generate Support Signals bool _allowLong, // Allow Long Signals bool _allowShort, // Allow Short Signals double _volume = 0.01, // Volume @@ -2052,10 +2186,60 @@ struct X121SignalGenerator return result; } + // + // Generate Support Signals ... + if (_useSupport) + { + // + GenerateSupportSignals( + signal // + ); + } + // return result; } + // + void GenerateSupportSignals( + XSignal &signal // Source Signal for Support Generating ... + ) { + // + // Validate Signal ... + if (!signal.IsValid()) { + return; + } + + // + // Check Signal Has TP and SL ... + if (signal.tp > 0 && signal.sl > 0) { + // + // Here we Can Provide Orders based on Signal TP and SL ... + + // + // Retrieve Signal Direction ... + bool isLong = IsLong(signal.type); + + // + // Calculate TP/Entry Distance ... + double tpDistance = + isLong + ? signal.tp - signal.entry + : signal.entry - signal.tp; + + // + // Calculate Recovery Zone Step ... + double slDistance = + isLong + ? signal.entry - signal.sl + : signal.sl - signal.entry; + + // + // Calculate Ticks Zone ... + + } + } + // string GetTag() { @@ -2079,6 +2263,7 @@ public: XSCXSTRHelper *strHelper; XSCXMRBHelper *mrbHelper; XSCXOSCHelper *oscHelper; + XSCXVLMHelper *vlmHelper; XSCXMATDHelper *matdHelper; XSCXASCTHelper *asctHelper; XSCXSSLCHelper *sslcHelper; @@ -2101,6 +2286,7 @@ public: delete strHelper; delete mrbHelper; delete oscHelper; + delete vlmHelper; delete matdHelper; delete asctHelper; delete sslcHelper; @@ -2238,6 +2424,19 @@ public: return result; } + // + // XVLM ... + vlmHelper = new XSCXVLMHelper(); + result = vlmHelper.Init( + inputs.symbol, + inputs.period, + inputs.vlmInputs // + ); + if (!result) + { + return result; + } + // // XMATD ... matdHelper = new XSCXMATDHelper( @@ -2429,6 +2628,17 @@ public: return result; } + // + result = vlmHelper.GetConditions( + conditions.vlmConditions, + barIndex, + loopback // + ); + if (!result) + { + return result; + } + // result = sslcHelper.GetConditions( conditions.sslcConditions, diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index 90099f82..f7fa8990 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -25,6 +25,7 @@ // #include "../Classes/x-saherelm.xea.class.mq5" +#include "../Classes/x-saherelm.xczone.class.mq5" #include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" // @@ -121,6 +122,7 @@ struct XSignalInfo pushers = _pushers; symbol = _signal.symbol; period = _signal.period; + volume = _signal.volume; provider = _signal.provider; // @@ -750,9 +752,40 @@ public: } // - bool IsEnable() + int CloseOnSpecificTime() { - return mAllowLong || mAllowShort; + return mCloseOnSpecificTime; + } + + // + void CloseOnSpecificTime(int value) + { + // + if (value < 0) + { + value = -1; + } + + // + if (value > 23) + { + value = 23; + } + + // + mCloseOnSpecificTime = value; + } + + // + bool UseSupport() + { + return mUseSupport; + } + + // + void UseSupport(bool value) + { + mUseSupport = value; } // @@ -907,7 +940,10 @@ public: } // + mVolumeOSC = 0; + mBullishSigns = 0; mBullishScore = 0; + mBearishSigns = 0; mBearishScore = 0; // @@ -921,6 +957,9 @@ public: mBullishScore += bullishScore; mBearishScore += bearishScore; + // + mVolumeOSC += cConditions.vlmConditions.volume[1]; + // // Parse Conditions for Signal ... bool hasSignal = signalGenerator.HasSignal( @@ -928,6 +967,7 @@ public: cSignal, cPusher, cProvider, + mUseSupport, mAllowLong, mAllowShort, mVolume, @@ -980,6 +1020,9 @@ public: mBullishScore += bullishScore; mBearishScore += bearishScore; + // + mVolumeOSC += sConditions.vlmConditions.volume[1]; + // // Parse Conditions for Signal ... bool hasSignal = signalGenerator.HasSignal( @@ -1039,6 +1082,9 @@ public: mBullishScore += bullishScore; mBearishScore += bearishScore; + // + mVolumeOSC += mConditions.vlmConditions.volume[1]; + // // Parse Conditions for Signal ... bool hasSignal = signalGenerator.HasSignal( @@ -1046,6 +1092,7 @@ public: mSignal, mPusher, mProvider, + mUseSupport, mAllowLong, mAllowShort, mVolume, @@ -1098,6 +1145,9 @@ public: mBullishScore += bullishScore; mBearishScore += bearishScore; + // + mVolumeOSC += lConditions.vlmConditions.volume[1]; + // // Parse Conditions for Signal ... bool hasSignal = signalGenerator.HasSignal( @@ -1105,6 +1155,7 @@ public: lSignal, lPusher, lProvider, + mUseSupport, mAllowLong, mAllowShort, mVolume, @@ -1157,6 +1208,9 @@ public: mBullishScore += bullishScore; mBearishScore += bearishScore; + // + mVolumeOSC += hConditions.vlmConditions.volume[1]; + // // Parse Conditions for Signal ... bool hasSignal = signalGenerator.HasSignal( @@ -1164,6 +1218,7 @@ public: hSignal, hPusher, hProvider, + mUseSupport, mAllowLong, mAllowShort, mVolume, @@ -1188,113 +1243,276 @@ public: // // Current Signals ... - if (cPusher >= mReuiredSignalVerifications && cSignal.IsValid()) + if (cSignal.IsValid()) { // - AddRef( - cSignal, - signals // - ); + bool isLong = IsLong(cSignal.type); + if (isLong) + { + mBullishSigns += cPusher; + } + else + { + mBearishSigns += cPusher; + } // - AddNewSignal( - cPusher, - cSignal, - mBullishScore, - mBearishScore, - cConditions // - ); + if (cPusher >= mReuiredSignalVerifications) + { + // + // Check Final Bullish and Bearish Score ... + bool isScorePassed = + // + IsLong(cSignal.type) + ? mBullishScore > (mBearishScore * 2) + : mBearishScore > (mBullishScore * 2) + // + ; + + // + if (isScorePassed) + { + // + AddRef( + cSignal, + signals // + ); + + // + AddNewSignal( + cPusher, + cSignal, + mBullishScore, + mBearishScore, + cConditions // + ); + } + } } // // Short Signals ... - if (sPusher >= mReuiredSignalVerifications && sSignal.IsValid()) + if (sSignal.IsValid()) { // - AddRef( - sSignal, - signals // - ); + bool isLong = IsLong(sSignal.type); + if (isLong) + { + mBullishSigns += sPusher; + } + else + { + mBearishSigns += sPusher; + } // - AddNewSignal( - sPusher, - sSignal, - mBullishScore, - mBearishScore, - sConditions // - ); + if (sPusher >= mReuiredSignalVerifications) + { + // + // Check Final Bullish and Bearish Score ... + bool isScorePassed = + // + IsLong(cSignal.type) + ? mBullishScore > (mBearishScore * 2) + : mBearishScore > (mBullishScore * 2) + // + ; + + // + if (isScorePassed) + { + // + AddRef( + sSignal, + signals // + ); + + // + AddNewSignal( + sPusher, + sSignal, + mBullishScore, + mBearishScore, + sConditions // + ); + } + } } // // Medium Signals ... - if (mPusher >= mReuiredSignalVerifications && mSignal.IsValid()) + if (mSignal.IsValid()) { // - AddRef( - mSignal, - signals // - ); + bool isLong = IsLong(mSignal.type); + if (isLong) + { + mBullishSigns += mPusher; + } + else + { + mBearishSigns += mPusher; + } // - AddNewSignal( - mPusher, - mSignal, - mBullishScore, - mBearishScore, - mConditions // - ); + if (mPusher >= mReuiredSignalVerifications) + { + // + // Check Final Bullish and Bearish Score ... + bool isScorePassed = + // + IsLong(cSignal.type) + ? mBullishScore > (mBearishScore * 2) + : mBearishScore > (mBullishScore * 2) + // + ; + + // + if (isScorePassed) + { + // + AddRef( + mSignal, + signals // + ); + + // + AddNewSignal( + mPusher, + mSignal, + mBullishScore, + mBearishScore, + mConditions // + ); + } + } } // // Long Signals ... - if (lPusher >= mReuiredSignalVerifications && lSignal.IsValid()) + if (lSignal.IsValid()) { // - AddRef( - lSignal, - signals // - ); + bool isLong = IsLong(lSignal.type); + if (isLong) + { + mBullishSigns += lPusher; + } + else + { + mBearishSigns += lPusher; + } // - AddNewSignal( - lPusher, - lSignal, - mBullishScore, - mBearishScore, - lConditions // - ); + if (lPusher >= mReuiredSignalVerifications) + { + // + // Check Final Bullish and Bearish Score ... + bool isScorePassed = + // + IsLong(cSignal.type) + ? mBullishScore > (mBearishScore * 2) + : mBearishScore > (mBullishScore * 2) + // + ; + + // + if (isScorePassed) + { + // + AddRef( + lSignal, + signals // + ); + + // + AddNewSignal( + lPusher, + lSignal, + mBullishScore, + mBearishScore, + lConditions // + ); + } + } } // // Hind Signals ... - if (hPusher >= mReuiredSignalVerifications && hSignal.IsValid()) + if (hSignal.IsValid()) { // - AddRef( - hSignal, - signals // - ); + bool isLong = IsLong(hSignal.type); + if (isLong) + { + mBullishSigns += hPusher; + } + else + { + mBearishSigns += hPusher; + } // - AddNewSignal( - hPusher, - hSignal, - mBullishScore, - mBearishScore, - hConditions // - ); + if (hPusher >= mReuiredSignalVerifications) + { + // + // Check Final Bullish and Bearish Score ... + bool isScorePassed = + // + IsLong(cSignal.type) + ? mBullishScore > (mBearishScore * 2) + : mBearishScore > (mBullishScore * 2) + // + ; + + // + if (isScorePassed) + { + // + AddRef( + hSignal, + signals // + ); + + // + AddNewSignal( + hPusher, + hSignal, + mBullishScore, + mBearishScore, + hConditions // + ); + } + } } } + // + if (mBullishScore == mBearishScore || + mBullishScore < 10 || + mBullishScore == 0 || + mBullishScore > 200 || + mBearishScore < 10 || + mBearishScore == 0 || + mBearishScore > 200) + { + // + // Print("Custom Scores ..."); + } + // // Create Score Summary for Commenting on Chart ... string scoreSummary = // - "Scores:" + separator + "----------" + separator + - "Bullish: " + ToString(mBullishScore) + separator + - "Bearish: " + ToString(mBearishScore) + separator + + "Bullish Score: " + ToString(mBullishScore) + separator + + "Bullish Signs: " + ToString(mBullishSigns) + separator + + "----------" + separator + + "Bearish Score: " + ToString(mBearishScore) + separator + + "Bearish Signs: " + ToString(mBearishSigns) + separator + + "----------" + separator + + "Volume: " + ToString(mVolumeOSC) + separator + + "DrawDown: " + ToString(GetDrawdownPercent()) + "%" + "" // ; @@ -1446,6 +1664,10 @@ public: // // Check EQM Orders and Handle Hedging ... // DoEQMHedge(); + // + // Handle Close All Positions on Specific Time ... + HandleEQMCloseOnSpecificTime(); + // // if Returns true, Signal Execution failed ... return result; @@ -1495,6 +1717,40 @@ protected: // // Tools ... + // + bool IsEnable() + { + return mAllowLong || mAllowShort; + } + + // + 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; + } + // // Private ... private: @@ -1507,10 +1763,12 @@ private: double mVolume; // Volume double mTPPoint; // TP Point double mSLPoint; // SL Point + bool mUseSupport; // Use Support Signals bool mIgnoreTP; // Ignore Calculated TP bool mIgnoreSL; // Ignore Calculated SL int mMaxAllowedTrades; // Max Alloed Positions bool mCloseOnOpposit; // Close all Positions on Opposit + int mCloseOnSpecificTime; // Close All Trades in Specific Time int mReuiredSignalVerifications; // Required Verifications for Validate Signals // @@ -1755,9 +2013,16 @@ private: } // + int mBullishSigns; double mBullishScore; + + // + int mBearishSigns; double mBearishScore; + // + double mVolumeOSC; + // XSCX121SetupCycles *mSetups[]; // Number of Setups @@ -2041,6 +2306,43 @@ private: Alert(message); } } + + // + // Handle Close Trades on Specific Time ... + void HandleEQMCloseOnSpecificTime() + { + // + 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); + } + } }; // diff --git a/Classes/x-saherelm.xczone.class.mq5 b/Classes/x-saherelm.xczone.class.mq5 new file mode 100644 index 00000000..cff23ddc --- /dev/null +++ b/Classes/x-saherelm.xczone.class.mq5 @@ -0,0 +1,642 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Class Library +// ---------------------------------------------- +// Name: XSCZone +// 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 +#include +#include "../Classes/x-saherelm.base.class.mq5" +#include + +// +// Definitions ... +#define defZoneBGColor 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); + + // + // 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; + + // + // 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); + } + + // + 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 ... + mRangeHigh = mHighs[ArrayMaximum(mHighs)]; + + // + // Retrieve Lows ... + Clean(mLows); + CopyLow( + mSymbol, + mPeriod, + mStartTime, + mEndTime, + mLows // + ); + + // + // Find Lowest Value in Range ... + mRangeLow = mLows[ArrayMaximum(mLows)]; + + // + 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; + } + } + } + + // + mZones.Sort(); + } + + // + 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; + } + + // + result = (double)zone.ticks / CountTicks() * 100; + result = NormalizeDouble(result, normalizationDigits); + + // + return result; + } + + // + bool DrawZones( + 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; + } + + // + 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); + + // + double iPercentage = CalculateZoneTickPercent(iZone); + iLabel.Description(ToString(iPercentage) + "%"); + + // + // Set Levels and Colors if Provided ... + if (canSetLevels) { + + } + + // + mChartObjects.Add(iRect); + mChartObjects.Add(iLabel); + } + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + + // + datetime mStartTime; + datetime mEndTime; + + // + MqlTick mTicks[]; + double mHighs[]; + double mLows[]; + double mRangeHigh; + double mRangeLow; + + // + 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/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index 89eba490..08866b55 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -1724,6 +1724,7 @@ public: // mIsInTestMode = IsRunningOnTestMode(); + mStaticBalanceForCalculateDrawdown = 0; // Ignore ... // // Set Event Handlers ... @@ -1834,6 +1835,12 @@ public: ); } + // + double GetDrawdownPercent() + { + return mDrawdownPercent; + } + // // Overrides ... @@ -1868,6 +1875,17 @@ public: // OnTick Handler ... virtual void OnTick() { + // + double mEquity = mTrader.mAccount.GetEquity(); + if (mEquity > mMaxDrawdown) + { + mMaxDrawdown = mEquity; + } + + // + mDrawdownPercent = (mMaxDrawdown - mEquity) / (mStaticBalanceForCalculateDrawdown > 0 ? mStaticBalanceForCalculateDrawdown : mMaxDrawdown) * 100; + mDrawdownPercent = NormalizeDouble(mDrawdownPercent, 3); + // // Draw ... Draw(); @@ -2230,6 +2248,12 @@ protected: // Check in Test Mode or not ... bool mIsInTestMode; + // + // Save Max Drawdown ... + double mMaxDrawdown; + double mDrawdownPercent; + double mStaticBalanceForCalculateDrawdown; + // // Tools ... diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index a5213f70..a424aefb 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -36,24 +36,26 @@ int x121EASlippage = 10; // Slippgae // // Trading Symbols ... -string x121EASymbols = "EURUSDb"; // Symbols +input string x121EASymbols = "EURUSDb"; // Symbols // EURUSDb,GBPUSDb,XAUUSDb,USDCHFb,USDJPYb // // Signals ... bool x121EAAllowLong = true; // Allow Long Trades bool x121EAAllowShort = true; // Allow Short Trades -int x121EAReuiredSignalVerifications = 5; // Required Verifications for Signals +int x121EAReuiredSignalVerifications = 4; // Required Verifications for Signals // // Risk Management ... -double x121EAVolume = 0.01; // Static Volume -double x121EATPPoint = 50; // TP Point -double x121EASLPoint = 500; // SL Point -int x121EAMaxAllowedTrades = 1; // Max Allowed Positions -bool x121EAIgnoreSL = false; // Ignore Calculated SL -bool x121EAIgnoreTP = false; // Ignore Calculated TP -bool x121EACloseOnOpposit = false; // Close all Positions on Opposit +double x121EAVolume = 0.01; // Static Volume +double x121EATPPoint = 100; // TP Point +double x121EASLPoint = 500; // SL Point +int x121EAMaxAllowedTrades = 10; // Max Allowed Positions +bool x121EAIgnoreSL = false; // Ignore Calculated SL +bool x121EAIgnoreTP = false; // Ignore Calculated TP +bool x121EAUseSupport = true; // Use Support Signals +int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time +bool x121EACloseOnOpposit = false; // Close all Positions on Opposit // // Alert ... @@ -167,7 +169,10 @@ bool InitialEA() x121EA.IgnoreTP(x121EAIgnoreTP); x121EA.AllowLong(x121EAAllowLong); x121EA.AllowShort(x121EAAllowShort); + x121EA.UseSupport(x121EAUseSupport); x121EA.CloseOnOpposit(x121EACloseOnOpposit); + x121EA.MaxAllowedTrades(x121EAMaxAllowedTrades); + x121EA.CloseOnSpecificTime(x121EACloseOnSpecificTime); x121EA.ReuiredSignalVerifications(x121EAReuiredSignalVerifications); // diff --git a/Experts/x-zone-test.mq5 b/Experts/x-zone-test.mq5 new file mode 100644 index 00000000..104f37a4 --- /dev/null +++ b/Experts/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/Helpers/x-saherelm.xvlm.helper.mq5 b/Helpers/x-saherelm.xvlm.helper.mq5 new file mode 100644 index 00000000..48149c7f --- /dev/null +++ b/Helpers/x-saherelm.xvlm.helper.mq5 @@ -0,0 +1,551 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Helper Class Library +// ---------------------------------------------- +// Name: XSCXVLMHelper +// Description: provides all Indicator +// Helper requirements ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://www.saherelm.ir" +#property version "1.00" +#property strict + +// +#include "../Classes/x-saherelm.xhelper.class.mq5" + +// +// Definitions ... + +// +enum ENUM_XVLM_BUFFERS +{ + XVLM_VOLUME_LINE = 0 +}; + +// +// Input Models ... +struct XVLMInputs +{ + // + // Props ... + + // + int length; // Length + + // + // Constructor(s) ... + XVLMInputs() + { + Clean(); + } + + // + // Tools ... + + // + // Clean ... + void Clean() + { + length = 0; + } + + // + // Default ... + void Default() + { + length = 14; + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + length > 1 + // + ; + + // + return result; + } + + // + // Retrieve MAx Length ... + int Max() + { + // + int result = 0; + + // + result = length; + + // + return result; + } +}; + +// +// Define Conditions ... +struct XVLMConditions +{ + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Buffers ... + double volume[]; + + // + // Conditions ... + + // + bool isVolumeBullish; + bool isVolumeBearish; + bool isVolumeOverLast; + bool isVolumeUnderLast; + bool isVolumeChangedToBullish; + bool isVolumeChangedToBearish; + + // + void Clean() + { + // + Clean(volume); + + // + ArraySetAsSeries(volume, true); + + // + isVolumeBullish = false; + isVolumeBearish = false; + isVolumeOverLast = false; + isVolumeUnderLast = false; + isVolumeChangedToBullish = false; + isVolumeChangedToBearish = false; + } + + // + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (isVolumeBullish) + { + bullishScore++; + } + if (isVolumeOverLast) + { + bullishScore++; + } + if (isVolumeChangedToBullish) + { + bullishScore++; + } + + // + if (isVolumeBearish) + { + bearishScore++; + } + if (isVolumeUnderLast) + { + bearishScore++; + } + if (isVolumeChangedToBearish) + { + 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("isVolumeBullish", isVolumeBullish, ignoreFalseConditions, separator) + + ToString("isVolumeBearish", isVolumeBearish, ignoreFalseConditions, separator) + + ToString("isVolumeOverLast", isVolumeOverLast, ignoreFalseConditions, separator) + + ToString("isVolumeUnderLast", isVolumeUnderLast, ignoreFalseConditions, separator) + + ToString("isVolumeChangedToBullish", isVolumeChangedToBullish, ignoreFalseConditions, separator) + + ToString("isVolumeChangedToBearish", isVolumeChangedToBearish, ignoreFalseConditions, separator) + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + (onlyConditions + ? "" + : commonStr) + + (!includeScores + ? "" + : scoresStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return "XVLM"; + } +}; + +// +// Class ... +class XSCXVLMHelper : public XSCBaseHelper +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructors ... + XSCXVLMHelper() : XSCBaseHelper(_Symbol, _Period) + { + } + + // + // Deconstructor ... + ~XSCXVLMHelper() {} + + // + // Tools ... + bool Init( + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + XVLMInputs &inputs // Inputs + ) + { + // + bool result = false; + + // + mSymbol = symbol; + mPeriod = period; + + // + result = inputs.IsValid(); + if (!result) + { + return result; + } + + // + mInputs = inputs; + + // + ArraySetAsSeries(volumeBuffer, true); + + // + mHandler = iCustom( + mSymbol, + mPeriod, + "x-saherelm.xvlm", + // + // Inputs ... + mInputs.length // Length + ); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + return result; + } + + // + // Inputs ... + + // + XVLMInputs GetInputs() + { + return mInputs; + } + + // + bool SetInputs( + XVLMInputs &inputs // Configs + ) + { + // + return Init( + mSymbol, + mPeriod, + inputs); + } + + // + // Buffers ... + + // + // Volume ... + + // + double GetVolume( + int barIndex // Bar Index + ) + { + // + if (barIndex < 0) + { + barIndex = 0; + } + + // + Calculate(); + + // + return volumeBuffer[barIndex]; + } + + // + // Copy Required Buffer ... + int CopyVolume( + int start, // Start + int count, // Number of Items for read + double &buffer[], // Dest Buffer + bool forceClean = true // Force To Clean buffer + ) + { + // + // Update Calculations ... + Calculate(); + + // + // Copy Items ... + return Copy( + start, + count, + volumeBuffer, + buffer, + forceClean + // + ); + } + + // + // Tools ... + + // + bool IsBullish(double volume) + { + // + bool result = false; + + // + result = + // + volume > 0; + // + ; + + // + return result; + } + + // + bool IsBearish(double volume) + { + // + bool result = false; + + // + result = + // + volume < 0 + // + ; + + // + return result; + } + + // + bool GetConditions( + XVLMConditions &conditions, // + int barIndex = 0, // + int loopback = 4 // + ) + { + // + bool result = true; + + // + if (loopback < 4) + { + loopback = 4; + } + + // + 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; + + // + CopyVolume( + zIndex, + loopback, + conditions.volume // + ); + + // + // Calculate Conditions ... + + // + bool isVolumeBullish = conditions.volume[cIndex] > 0; + bool isVolumeBullishPrev = conditions.volume[pIndex] > 0; + + // + bool isVolumeBearish = conditions.volume[cIndex] < 0; + bool isVolumeBearishPrev = conditions.volume[pIndex] < 0; + + // + bool isVolumeOverLast = conditions.volume[cIndex] > conditions.volume[pIndex]; + bool isVolumeOverLastPrev = conditions.volume[pIndex] > conditions.volume[ppIndex]; + + // + bool isVolumeUnderLast = conditions.volume[cIndex] < conditions.volume[pIndex]; + bool isVolumeUnderLastPrev = conditions.volume[pIndex] < conditions.volume[ppIndex]; + + // + bool isVolumeChangedToBullish = isVolumeBullish && + !isVolumeBullishPrev; + bool isVolumeChangedToBearish = isVolumeBearish && + !isVolumeBearishPrev; + + // + conditions.isVolumeBullish = isVolumeBullish; + conditions.isVolumeBearish = isVolumeBearish; + conditions.isVolumeOverLast = isVolumeOverLast; + conditions.isVolumeUnderLast = isVolumeUnderLast; + conditions.isVolumeChangedToBullish = isVolumeChangedToBullish; + conditions.isVolumeChangedToBearish = isVolumeChangedToBearish; + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + XVLMInputs mInputs; // Inputs ... + + // + // Buffers ... + double volumeBuffer[]; + + // + // Tools ... + + // + // Calculate Values Until Now ... + void Calculate() + { + // + int totalBars = CountBars(); + int calculatedBars = CountCalculatedBars(); + + // + // Trend ... + CopyBuffer( + mHandler, + XVLM_VOLUME_LINE, + 0, + totalBars, + volumeBuffer + // + ); + } +}; + +// +// Tools ... diff --git a/Indicators/x-saherelm.xvlm.mq5 b/Indicators/x-saherelm.xvlm.mq5 new file mode 100644 index 00000000..7aa93a91 --- /dev/null +++ b/Indicators/x-saherelm.xvlm.mq5 @@ -0,0 +1,231 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XVLM +// Description: Volume Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XVLM Indicator" +#property strict + +// +// Imports ... +#include + +// +// Definitions ... + +// +#define ShortName "XVLM" + +// +// Inputs ... + +// +input int length = 14; // Length + +// +// Buffers ... + +// +#property indicator_chart_window + +// +#property indicator_buffers 2 +#property indicator_plots 0 + +/// +#define volumeBufferIndex 0 +double volumeBuffer[]; + +// +#define volumeColorBufferIndex 1 +double volumeColorBuffer[]; + +// +#property indicator_label1 "XVLM" +#property indicator_type1 DRAW_COLOR_HISTOGRAM +#property indicator_color1 clrLime, clrRed + +// +#define bullishColorIndex 0 +#define bearishColorIndex 1 + +// +// Variables ... + +// +int maxLength; + +// +double volumes[]; +double distances[]; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + 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(); + + // + ArrayResize(volumes, maxLength, 0); + ArrayResize(distances, maxLength, 0); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// 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 ... +) +{ + // + static int i = maxLength * 2; + for (i; i < rates_total; i++) + { + // + for (int x = 0; x < length; x++) + { + // + volumes[x] = (double)tick_volume[i - x]; + distances[x] = + (close[i - x] > open[i - x]) + ? high[i - x] - low[i - x] + : low[i - x] - high[i - x]; + } + + // + double iValue = MathMean(volumes) * MathMean(distances); + + // + volumeBuffer[i] = iValue; + volumeColorBuffer[i] = iValue > 0 + ? bullishColorIndex + : bearishColorIndex; + } + + // + i = rates_total - 1; + + // + return rates_total; +} + +// +// Custom Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + length >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + 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() +{ + // + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_CALCULATIONS); + SetIndexBuffer(volumeColorBufferIndex, volumeColorBuffer, INDICATOR_CALCULATIONS); +} \ No newline at end of file diff --git a/Indicators/x-saherelm.xvlm.osc.mq5 b/Indicators/x-saherelm.xvlm.osc.mq5 new file mode 100644 index 00000000..98f5bdb2 --- /dev/null +++ b/Indicators/x-saherelm.xvlm.osc.mq5 @@ -0,0 +1,231 @@ +////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// --------------------------------------------- +// Name: XVLM +// Description: Volume Trend Indicator ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XVLM Indicator" +#property strict + +// +// Imports ... +#include + +// +// Definitions ... + +// +#define ShortName "XVLM" + +// +// Inputs ... + +// +input int length = 14; // Length + +// +// Buffers ... + +// +#property indicator_separate_window + +// +#property indicator_buffers 2 +#property indicator_plots 2 + +/// +#define volumeBufferIndex 0 +double volumeBuffer[]; + +// +#define volumeColorBufferIndex 1 +double volumeColorBuffer[]; + +// +#property indicator_label1 "XVLM" +#property indicator_type1 DRAW_COLOR_HISTOGRAM +#property indicator_color1 clrLime, clrRed + +// +#define bullishColorIndex 0 +#define bearishColorIndex 1 + +// +// Variables ... + +// +int maxLength; + +// +double volumes[]; +double distances[]; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + 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(); + + // + ArrayResize(volumes, maxLength, 0); + ArrayResize(distances, maxLength, 0); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed + + // + // Here we can handle De Initialization Reasons ... +} + +// +// 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 ... +) +{ + // + static int i = maxLength * 2; + for (i; i < rates_total; i++) + { + // + for (int x = 0; x < length; x++) + { + // + volumes[x] = (double)tick_volume[i - x]; + distances[x] = + (close[i - x] > open[i - x]) + ? high[i - x] - low[i - x] + : low[i - x] - high[i - x]; + } + + // + double iValue = MathMean(volumes) * MathMean(distances); + + // + volumeBuffer[i] = iValue; + volumeColorBuffer[i] = iValue > 0 + ? bullishColorIndex + : bearishColorIndex; + } + + // + i = rates_total - 1; + + // + return rates_total; +} + +// +// Custom Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + // Validate Args ... + result = + // + length >= 2 + // + ; + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = length; + + // + 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() +{ + // + SetIndexBuffer(volumeBufferIndex, volumeBuffer, INDICATOR_DATA); + SetIndexBuffer(volumeColorBufferIndex, volumeColorBuffer, INDICATOR_COLOR_INDEX); +} \ No newline at end of file