diff --git a/Classes/x-saherelm.x121.provider.class.mq5 b/Classes/x-saherelm.x121.provider.class.mq5 index 0ec8bb96..511f3252 100644 --- a/Classes/x-saherelm.x121.provider.class.mq5 +++ b/Classes/x-saherelm.x121.provider.class.mq5 @@ -100,6 +100,7 @@ public: XCTInputs ctInputs; XZGInputs zgInputs; XPVInputs pvInputs; + XHKInputs hkInputs; XMCInputs mcInputs; XICHInputs ichInputs; XCHEInputs cheInputs; @@ -154,6 +155,10 @@ public: { mcInputs.Default(); } + if (!hkInputs.IsValid()) + { + hkInputs.Default(); + } if (!cheInputs.IsValid()) { cheInputs.Default(); @@ -175,28 +180,6 @@ public: ichInputs.Default(); } - // // - // if (!cMarketInputs.IsValid()) - // { - // cMarketInputs.Default(); - // } - // if (!sMarketInputs.IsValid()) - // { - // sMarketInputs.Default(); - // } - // if (!mMarketInputs.IsValid()) - // { - // mMarketInputs.Default(); - // } - // if (!lMarketInputs.IsValid()) - // { - // lMarketInputs.Default(); - // } - // if (!hMarketInputs.IsValid()) - // { - // hMarketInputs.Default(); - // } - // // Initialize Market Inputs ... @@ -205,6 +188,7 @@ public: cMarketInputs.pvInputs = this.pvInputs; cMarketInputs.zgInputs = this.zgInputs; cMarketInputs.mcInputs = this.mcInputs; + cMarketInputs.hkInputs = this.hkInputs; cMarketInputs.strInputs = this.strInputs; cMarketInputs.oscInputs = this.oscInputs; cMarketInputs.cheInputs = this.cheInputs; @@ -229,6 +213,7 @@ public: sMarketInputs.pvInputs = this.pvInputs; sMarketInputs.zgInputs = this.zgInputs; sMarketInputs.mcInputs = this.mcInputs; + sMarketInputs.hkInputs = this.hkInputs; sMarketInputs.strInputs = this.strInputs; sMarketInputs.oscInputs = this.oscInputs; sMarketInputs.cheInputs = this.cheInputs; @@ -253,6 +238,7 @@ public: mMarketInputs.pvInputs = this.pvInputs; mMarketInputs.zgInputs = this.zgInputs; mMarketInputs.mcInputs = this.mcInputs; + mMarketInputs.hkInputs = this.hkInputs; mMarketInputs.strInputs = this.strInputs; mMarketInputs.oscInputs = this.oscInputs; mMarketInputs.cheInputs = this.cheInputs; @@ -277,6 +263,7 @@ public: lMarketInputs.pvInputs = this.pvInputs; lMarketInputs.zgInputs = this.zgInputs; lMarketInputs.mcInputs = this.mcInputs; + lMarketInputs.hkInputs = this.hkInputs; lMarketInputs.strInputs = this.strInputs; lMarketInputs.oscInputs = this.oscInputs; lMarketInputs.cheInputs = this.cheInputs; @@ -301,6 +288,7 @@ public: hMarketInputs.pvInputs = this.pvInputs; hMarketInputs.zgInputs = this.zgInputs; hMarketInputs.mcInputs = this.mcInputs; + hMarketInputs.hkInputs = this.hkInputs; hMarketInputs.strInputs = this.strInputs; hMarketInputs.oscInputs = this.oscInputs; hMarketInputs.cheInputs = this.cheInputs; @@ -350,6 +338,7 @@ public: zgInputs.IsValid() && pvInputs.IsValid() && mcInputs.IsValid() && + hkInputs.IsValid() && cheInputs.IsValid() && strInputs.IsValid() && donInputs.IsValid() && @@ -402,6 +391,7 @@ public: zgInputs.Clean(); pvInputs.Clean(); mcInputs.Clean(); + hkInputs.Clean(); cheInputs.Clean(); strInputs.Clean(); donInputs.Clean(); @@ -449,6 +439,7 @@ public: zgInputs.Default(); pvInputs.Default(); mcInputs.Default(); + hkInputs.Default(); cheInputs.Default(); strInputs.Default(); donInputs.Default(); @@ -791,9 +782,11 @@ public: // // Constructor ... XSCX121Provider( - string symbol, // Trading Symbol - ENUM_TIMEFRAMES period // Trading PEriod - ) : XSCBaseProvider(symbol, period) + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + double staticVolume // Static Volume for Positions + + ) : XSCBaseProvider(symbol, period, staticVolume) { // ccHelper = new XSCXCCHelper(); @@ -1441,25 +1434,6 @@ public: return result; } - // - // Generate EQM Support Signals ... - int GenerateEQMSupportSignals(XSignal &supports[]) - { - // - int result = 0; - - // - Clean(supports); - - // - // TODO: Implement Support Mechanism ... - // we are in EQUITY STATE ... - // so we have to - - // - return result; - } - // // Tools ... @@ -2715,6 +2689,25 @@ protected: AddSRValue(selectedHCLL); } + // + // Add Candelstick Pivots ... + + // + // XOHCL sPBar = sMarket.GetBar(barIndex + 1); + // AddSRValue(sPBar); + + // + XOHCL mPBar = mMarket.GetBar(barIndex + 1); + AddSRValue(mPBar); + + // + XOHCL lPBar = lMarket.GetBar(barIndex + 1); + AddSRValue(lPBar); + + // + XOHCL hPBar = hMarket.GetBar(barIndex + 1); + AddSRValue(hPBar); + // int after = CountSupportResistances(); @@ -2722,7 +2715,7 @@ protected: if (after > before) { // - string message = "Found: " + ToString(after - before) + " new Pivot ..."; + string message = "Found: " + ToString(after - before) + " new Pivot for " + GetSymbol() + " ..."; Print(message); } } @@ -2780,6 +2773,22 @@ protected: ); } + // + void AddSRValue(XOHCL &bar) + { + // + if (!bar.IsValid()) + { + return; + } + + // + AddSRValue(bar.open); + AddSRValue(bar.high); + AddSRValue(bar.close); + AddSRValue(bar.low); + } + // // Private ... private: @@ -4017,7 +4026,7 @@ private: } // - // Use Scores ... + // Use XHK ... bool X92HasSpecifiedLongSignal( X121MarketConditions &mConditions, // double &sl, // Provided SL ... @@ -4028,6 +4037,183 @@ private: // bool result = false; + // + int curr = 0; + int prev = 1; + + // + bool isCSMHKSwitchedToBullish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.cMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isCSMHKBullish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBullish() && + mConditions.cMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.cMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.cMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isSSMHKSwitchedToBullish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.sMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isSSMHKBullish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBullish() && + mConditions.sMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.sMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.sMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isMSMHKSwitchedToBullish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.mMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isMSMHKBullish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBullish() && + mConditions.mMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.mMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.mMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isLSMHKSwitchedToBullish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.lMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isLSMHKBullish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBullish() && + mConditions.lMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.lMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.lMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isHSMHKSwitchedToBullish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBullish() && + !mConditions.hMarketConditions.smHKBars[prev].IsBullish() + // + ; + + // + bool isHSMHKBullish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBullish() && + mConditions.hMarketConditions.smHKBars[prev].IsBullish() && + !mConditions.bars[curr].open > mConditions.hMarketConditions.smHKBars[curr].GetUp() && + !mConditions.bars[prev].close > mConditions.hMarketConditions.smHKBars[prev].GetUp() + // + ; + + // + bool isCSMHKLong = + // + (isCSMHKBullish || + isCSMHKSwitchedToBullish) && + isSSMHKBullish && + isMSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isSSMHKLong = + // + (isSSMHKBullish || + isSSMHKSwitchedToBullish) && + isCSMHKBullish && + isMSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isMSMHKLong = + // + (isMSMHKBullish || + isMSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isLSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isLSMHKLong = + // + (isLSMHKBullish || + isLSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isMSMHKBullish && + isHSMHKBullish + // + ; + + // + bool isHSMHKLong = + // + (isHSMHKBullish || + isHSMHKSwitchedToBullish) && + isSSMHKBullish && + isCSMHKBullish && + isMSMHKBullish && + isLSMHKBullish + // + ; + + // + result = + // + isCSMHKLong + // + || + // + isSSMHKLong + // + || + // + isMSMHKLong + // + || + // + isLSMHKLong + // + || + // + isHSMHKLong + // + ; + // return result; } @@ -4456,7 +4642,7 @@ private: } // - // Use Scores ... + // Use XHK ... bool X92HasSpecifiedShortSignal( X121MarketConditions &mConditions, // double &sl, // Provided SL ... @@ -4467,6 +4653,183 @@ private: // bool result = false; + // + int curr = 0; + int prev = 1; + + // + bool isCSMHKSwitchedToBearish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.cMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isCSMHKBearish = + // + mConditions.cMarketConditions.smHKBars[curr].IsBearish() && + mConditions.cMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.cMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.cMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isSSMHKSwitchedToBearish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.sMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isSSMHKBearish = + // + mConditions.sMarketConditions.smHKBars[curr].IsBearish() && + mConditions.sMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.sMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.sMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isMSMHKSwitchedToBearish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.mMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isMSMHKBearish = + // + mConditions.mMarketConditions.smHKBars[curr].IsBearish() && + mConditions.mMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.mMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.mMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isLSMHKSwitchedToBearish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.lMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isLSMHKBearish = + // + mConditions.lMarketConditions.smHKBars[curr].IsBearish() && + mConditions.lMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.lMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.lMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isHSMHKSwitchedToBearish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBearish() && + !mConditions.hMarketConditions.smHKBars[prev].IsBearish() + // + ; + + // + bool isHSMHKBearish = + // + mConditions.hMarketConditions.smHKBars[curr].IsBearish() && + mConditions.hMarketConditions.smHKBars[prev].IsBearish() && + !mConditions.bars[curr].open < mConditions.hMarketConditions.smHKBars[curr].GetDown() && + !mConditions.bars[prev].close < mConditions.hMarketConditions.smHKBars[prev].GetDown() + // + ; + + // + bool isCSMHKShort = + // + (isCSMHKBearish || + isCSMHKSwitchedToBearish) && + isSSMHKBearish && + isMSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isSSMHKShort = + // + (isSSMHKBearish || + isSSMHKSwitchedToBearish) && + isCSMHKBearish && + isMSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isMSMHKShort = + // + (isMSMHKBearish || + isMSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isLSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isLSMHKShort = + // + (isLSMHKBearish || + isLSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isMSMHKBearish && + isHSMHKBearish + // + ; + + // + bool isHSMHKShort = + // + (isHSMHKBearish || + isHSMHKSwitchedToBearish) && + isSSMHKBearish && + isCSMHKBearish && + isMSMHKBearish && + isLSMHKBearish + // + ; + + // + result = + // + isCSMHKShort + // + || + // + isSSMHKShort + // + || + // + isMSMHKShort + // + || + // + isLSMHKShort + // + || + // + isHSMHKShort + // + ; + // return result; } @@ -4500,6 +4863,7 @@ struct X121ProviderDescriptor // string symbol; // Trading Symbol ENUM_TIMEFRAMES period; // Trading Timeframe + double staticVolume; // Static Volume for Positions bool allowLong; // Allow Long Signals bool allowShort; // Allow Short Signals ENUM_X121_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers @@ -4527,7 +4891,8 @@ struct X121ProviderDescriptor this.period, this.signallers, this.allowLong, - this.allowShort // + this.allowShort, + this.staticVolume // ); // @@ -4538,7 +4903,8 @@ struct X121ProviderDescriptor bool Init( ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -4550,7 +4916,8 @@ struct X121ProviderDescriptor this.period, mSignallers, mAllowLong, - mAllowShort // + mAllowShort, + mStaticVolume // ); // @@ -4563,7 +4930,8 @@ struct X121ProviderDescriptor ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ENUM_X121_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -4575,6 +4943,7 @@ struct X121ProviderDescriptor inputs.IsValid() && IsValid(mSymbol) && IsValid(mPeriod) && + NotEmpty(mStaticVolume) && (allowLong || allowShort) && ArraySize(mSignallers) > 0 // @@ -4589,6 +4958,7 @@ struct X121ProviderDescriptor this.period = mPeriod; this.allowLong = mAllowLong; this.allowShort = mAllowShort; + this.staticVolume = mStaticVolume; // ENUM_X121_SIGNAL_PROVIDERS tmp[]; @@ -4605,7 +4975,8 @@ struct X121ProviderDescriptor // Instantiate Provider ... provider = new XSCX121Provider( this.symbol, - this.period // + this.period, + this.staticVolume // ); // @@ -4664,6 +5035,7 @@ struct X121ProviderDescriptor // IsValid(symbol) && IsValid(period) && + NotEmpty(staticVolume) && (validateInputs ? inputs.IsValid() : true) && diff --git a/Classes/x-saherelm.x121.xea.class.mq5 b/Classes/x-saherelm.x121.xea.class.mq5 index fc9b47a9..b46e3a56 100644 --- a/Classes/x-saherelm.x121.xea.class.mq5 +++ b/Classes/x-saherelm.x121.xea.class.mq5 @@ -22,6 +22,7 @@ // // Imports ... +#include #include "../Classes/x-saherelm.xea.class.mq5" #include "../Classes/x-saherelm.x121.provider.class.mq5" @@ -29,6 +30,450 @@ // Define On Signal Event Handler Type Specified for X5 ... typedef void (*TX121OnSignal)(X121ProviderDescriptor &descriptor); +// +class XSCPositionHolder +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + + // + XSCPositionHolder() + { + Clear(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clear() + { + Clean(mItems); + } + + // + bool AddItem(XPosition &item) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + result = !HasItem(item); + if (!result) + { + return result; + } + + // + AddRef( + item, + mItems // + ); + + // + return result; + } + + // + int AddItems(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isAdded = AddItem(iItem); + if (isAdded) + { + result++; + } + } + + // + return result; + } + + // + bool AddOrUpdateItem(XPosition &item) + { + // + bool result = false; + + // + result = item.IsValid(); + if (!result) + { + return result; + } + + // + bool hasItem = HasItem(item); + if (!hasItem) + { + result = AddItem(item); + } + else + { + // + result = RemoveItem(item); + if (result) + { + result = AddItem(item); + } + } + + // + return result; + } + + // + int AddOrUpdateItem(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isAddOrUpdated = AddOrUpdateItem(iItem); + if (isAddOrUpdated) + { + result++; + } + } + + // + return result; + } + + // + bool HasItem(XPosition &item) + { + // + bool result = false; + + // + int itemIDX = FindItem(item); + result = itemIDX >= 0; + + // + return result; + } + + // + int FindItem(XPosition &item) + { + // + int result = -1; + + // + if (!item.IsValid()) + { + return result; + } + + // + int itemsCount = CountItems(); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool isSame = IsItemSameAs(item, iItem); + if (isSame) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + bool GetByIndex( + int index, + XPosition &item // + ) + { + // + bool result = false; + + // + NormalizeIndex( + index, + mItems // + ); + + // + item = mItems[index]; + + // + result = item.IsValid(); + + // + return result; + } + + // + bool RemoveItem(XPosition &item) + { + // + bool result = false; + + // + result = HasItem(item); + if (!result) + { + return result; + } + + // + int itemIDX = FindItem(item); + result = ArrayRemove( + mItems, + itemIDX, + 1 // + ); + + // + return result; + } + + // + int RemoveItems(XPosition &items[]) + { + // + int result = 0; + + // + int itemsCount = ArraySize(items); + if (itemsCount <= 0) + { + return result; + } + + // + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = items[i]; + + // + bool isRemoved = RemoveItem(iItem); + if (isRemoved) + { + result++; + } + } + + // + return result; + } + + // + int CountItems() + { + return ArraySize(mItems); + } + + // + bool IsItemSameAs( + XPosition &source, + XPosition &dest // Compare Source with this ... + ) + { + // + bool result = false; + + // + result = + // + dest.IsValid() && + source.IsValid() && + source.symbol == dest.symbol && + source.period == dest.period && + source.ticket == dest.ticket && + source.openAt == dest.openAt && + source.provider == dest.provider + // + ; + + // + return result; + } + + // + // Custom Functions ... + + // + bool GetMaxInDrawdown( + XPosition &item // Result + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + int maxIDX = -1; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool canSelect = + // + iItem.profit < 0 + // + && + // + ( + // + (maxIDX == -1 && !item.IsValid()) + ? true + : item.profit < iItem.profit + // + ) + // + ; + if (canSelect) + { + // + maxIDX = i; + item = iItem; + } + } + + // + result = maxIDX > -1 && item.IsValid(); + + // + return result; + } + + // + bool GetMaxInProfit( + XPosition &item // Result + ) + { + // + bool result = false; + + // + item.Clean(); + + // + int itemsCount = CountItems(); + result = IsValidSize(itemsCount); + if (!result) + { + return result; + } + + // + int maxIDX = -1; + for (int i = 0; i < itemsCount; i++) + { + // + XPosition iItem = mItems[i]; + + // + bool canSelect = + // + iItem.profit > 0 + // + && + // + ( + // + (maxIDX == -1 && !item.IsValid()) + ? true + : item.profit < iItem.profit + // + ) + // + ; + if (canSelect) + { + // + maxIDX = i; + item = iItem; + } + } + + // + result = maxIDX > -1 && item.IsValid(); + + // + return result; + } + + // + // Private ... +private: + // + // Props ... + XPosition mItems[]; +}; + // // Class Definition ... @@ -51,6 +496,7 @@ public: double maxAllowedSpread, // Max Allowed Spred for Opening Trades int maxAllowedPositions, // Max Allowed Positions double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + double staticVolume, // Static Volume for Positions // // Position Management ... bool allowLong = true, // Allow Long Trades @@ -80,6 +526,7 @@ public: maxAllowedSpread, maxAllowedPositions, maxAllowedDrawdownFactor, + staticVolume, allowLong, allowShort, minProfitPerTrade, @@ -501,9 +948,8 @@ public: // TODO: // Make them Configurable ... int levelsOnClose = 6; - int requiredAgeForSLTrail = 0; - int requiredDistanceForSLTrail = 100; - return; + int requiredAgeForTrail = 0; + int requiredDistanceForTrail = 5; // int positionsCount = ArraySize(positions); @@ -531,7 +977,7 @@ public: if (canManageState) { // - // Check Position in Profit or not ... + // When Position in Profit, Trail SL ... if (iPosition.profit > 0) { // @@ -550,7 +996,7 @@ public: // // Check Position Age ... int iPositionAge = iPosition.GetAge(iPosition.period); - if (iPositionAge < requiredAgeForSLTrail) + if (iPositionAge < requiredAgeForTrail) { continue; } @@ -559,7 +1005,7 @@ public: // Check Position Profit Distance ... double priceDistanceInPoint = PriceToPoint(iPosition.profit / iPosition.volume, iPosition.symbol); double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); - if (priceDistance < requiredDistanceForSLTrail) + if (priceDistance < requiredDistanceForTrail) { continue; } @@ -568,17 +1014,17 @@ public: double slDiff = PointToPrice(priceDistance, iPosition.symbol); double appliedSL = slDiff / 2; - // // - // double sl = - // IsLong(iPosition.type) - // ? iPosition.sl + slDiff - // : iPosition.sl - slDiff; - // double sl = IsLong(iPosition.type) - ? iPosition.entry + appliedSL - : iPosition.entry - appliedSL; + ? iPosition.sl + slDiff + : iPosition.sl - slDiff; + + // + // double sl = + // IsLong(iPosition.type) + // ? iPosition.entry + appliedSL + // : iPosition.entry - appliedSL; // bool isInit = trail.Init( @@ -614,7 +1060,7 @@ public: trail.time, false // ); - if (age < requiredAgeForSLTrail) + if (age < requiredAgeForTrail) { continue; } @@ -622,7 +1068,7 @@ public: // double priceDistanceInPoint = PriceToPoint((iPosition.profit - trail.profit) / iPosition.volume, iPosition.symbol); double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); - if (priceDistance < (requiredDistanceForSLTrail / 2)) + if (priceDistance < (requiredDistanceForTrail / 2)) { // // // // int positionAge = iPosition.GetAge(iPosition.period); @@ -660,15 +1106,18 @@ public: double appliedSL = slDiff / 2; // - double selectedValue = - // - trail.level == 1 || (isLong - ? iPosition.sl < iPosition.entry - : iPosition.sl > iPosition.entry) - ? iPosition.entry - : iPosition.sl - // - ; + double selectedValue = iPosition.sl; + + // // + // double selectedValue = + // // + // trail.level == 1 || (isLong + // ? iPosition.sl < iPosition.entry + // : iPosition.sl > iPosition.entry) + // ? iPosition.entry + // : iPosition.sl + // // + // ; // double sl = @@ -713,6 +1162,142 @@ public: } } } + + // + // When Position in Drawdown Trail TP ... + if (iPosition.profit < 0) + { + // + XTrail trail; + bool isTrailedBefore = GetTPTrail( + iPosition.ticket, + trail // + ); + + // + if (!isTrailedBefore) + { + // + // Add First Time ... + + // + // Check Position Age ... + int iPositionAge = iPosition.GetAge(iPosition.period); + if (iPositionAge < requiredAgeForTrail) + { + continue; + } + + // + // Check Position Profit Distance ... + double priceDistanceInPoint = PriceToPoint(MathAbs(iPosition.profit) / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + if (priceDistance < requiredDistanceForTrail) + { + continue; + } + + // + double tpDiff = PointToPrice(priceDistance, iPosition.symbol); + + // + double tp = + IsLong(iPosition.type) + ? iPosition.tp - tpDiff + : iPosition.tp + tpDiff; + + // + bool isInit = trail.Init( + iPosition.ticket, + iPosition.type, + iPosition.profit, + iPosition.tp, + tp // + ); + if (!isInit) + { + continue; + } + } + else + { + // + // Update Exists ... + + // + // Check Profit ... + bool isProfitPassed = MathAbs(iPosition.profit) > MathAbs(trail.profit); + if (!isProfitPassed) + { + continue; + } + + // + // Check Age Distance from Last ... + int age = iBarShift( + iPosition.symbol, + iPosition.period, + trail.time, + false // + ); + if (age < requiredAgeForTrail) + { + continue; + } + + // + double priceDistanceInPoint = PriceToPoint((MathAbs(iPosition.profit) - MathAbs(trail.profit)) / iPosition.volume, iPosition.symbol); + double priceDistance = PointToPrice(priceDistanceInPoint, iPosition.symbol); + + // + bool isLong = IsLong(iPosition.type); + + // + double tpDiff = PointToPrice(priceDistance, iPosition.symbol); + + // + double tp = + isLong + ? iPosition.tp - tpDiff + : iPosition.tp + tpDiff; + + // + // Update Trail Values ... + bool isUpdated = trail.Update( + tp, + iPosition.profit // + ); + if (!isUpdated) + { + continue; + } + } + + // + if (trail.IsValid()) + { + // + string comment = trail.GenerateTag(); + bool isModified = mTrader.Modify( + trail.ticket, + iPosition.sl, + trail.after, + comment // + ); + if (isModified) + { + // + RemoveTrail(trail.ticket); + + // + AddTPTrail(trail); + + // + string message = "Position (" + ToString(trail.ticket) + ") Trailed TP on Level: " + ToString(trail.level); + mAlert.Alert(message); + } + } + } } } } @@ -745,8 +1330,6 @@ public: // Cleaning Source ... Clean(signals); - // - // // Loop through Signals for Management ... for (int i = 0; i < tmpsCount; i++) @@ -755,6 +1338,7 @@ public: XSignal iSignal = tmps[i]; // + // dont Manage NON Signal Provider's signals ... string provider = iSignal.provider; if (!IsValid(provider)) { @@ -777,13 +1361,23 @@ public: NULL, // All Periods ... iSignal.type // ); + XPosition symbolPositions[]; + int positionsCount = mTrader.GetPositions( + positions, + iSignal.symbol, + NULL, // All Providers ... + NULL, // All Periods ... + iSignal.type // + ); + double profit = CalculatePositionsProfit(positions); + double symbolProfit = CalculatePositionsProfit(symbolPositions); if (positionsCount <= 0) { // // First Signal in a While of Specific Provider ... // - iSignal.volume *= 2; + // iSignal.volume *= 2; // AddRef( @@ -808,6 +1402,14 @@ public: // continue; } + else if (profit > 0 && symbolProfit > 0) + { + // + AddRef( + iSignal, + signals // + ); + } } // @@ -838,9 +1440,15 @@ public: return false; } + // + // Tools ... + + // + // Management Tracker/Profit etc ... + // // Handle Position Changed Event ... - void OnPositionsChangedHandler(int count) + void OnPositionsChangedHandler(int count) override { // // Synchronize Tracker ... @@ -848,77 +1456,135 @@ public: } // - // Tools ... - - // - // Position Tracker ... - - // - // Synchronize Positions and Position Tracker ... - void SyncPositionTracker() + // Called when a Position Going in Profit ... + void OnPositionGoingInProfit(XPositionTrack &track) override { // - static datetime lastSyncPositionTracker = NULL; - datetime cTime = TimeCurrent(); + string message = "Position (" + ToString(track.ticket) + ", " + track.symbol + ") Dropped in Profit ..."; + mAlert.Alert(message); + } + + // + // Called when a Position Going to Drawdown ... + void OnPositionGoingToDrawdown(XPositionTrack &track) override + { + // + string message = "Position (" + ToString(track.ticket) + ", " + track.symbol + ") Dropped in Drawdown ..."; + mAlert.Alert(message); + } + + // + // Called when Account Going in Profit ... + void OnGoingToProfit(XProfitTrack &track) override + { + // + string message = "Account In Profit ..."; // - int syncInterval = PeriodSeconds(PERIOD_M5); - int lastDiff = (int)cTime - (int)lastSyncPositionTracker; + mAlert.Alert(message); + } + + // + // Called when Account Going in Drawdown ... + void OnGoingToDrawdown(XProfitTrack &track) override + { + // + string message = "Account In Drawdown ..."; // - bool canSync = - lastSyncPositionTracker == NULL - ? true - : lastDiff >= syncInterval; - if (!canSync) + mAlert.Alert(message); + + // + // Here i Have to Detect In DrawDown Positions ... + + // + XPosition positions[]; + int positionsCount = mTrader.GetInDrawdownPositions( + positions); + if (!IsValidSize(positionsCount)) { return; } // - XPositionTrackerState state; - int synced = mPositionTracker.Sync( - state, - mTrader // - ); - if (synced > 0) + // Create a HashMap for Holding Positions ... + CHashMap symbolMap; + + // + // Loop Through Positions ... + for (int i = 0; i < positionsCount; i++) { // - // Check State and Do What we Want ... - int onProfitsCount = ArraySize(state.onProfits); - int onDrawdownCount = ArraySize(state.onDrawdowns); + XPosition iPosition = positions[i]; // - // Do What we want whe a Position Dropped to Prefit ... - if (onProfitsCount > 0) + bool hasIKey = symbolMap.ContainsKey(iPosition.symbol); + + // + // Empty Class Pointer ... + XSCPositionHolder *mHolder = NULL; + + // + // Add new to Map ... + if (!hasIKey) { // - for (int i = 0; i < onProfitsCount; i++) + mHolder = new XSCPositionHolder(); + if (symbolMap.TrySetValue(iPosition.symbol, mHolder)) { - // - XPositionTrack iTrack = state.onProfits[i]; - - // - string message = "Position (" + ToString(iTrack.ticket) + ", " + iTrack.symbol + ") Dropped in Profit ..."; - mAlert.Alert(message); + mHolder.AddOrUpdateItem(iPosition); } } + // + // Update Exists in Map ... + else + { + // + if (symbolMap.TryGetValue(iPosition.symbol, mHolder)) + { + mHolder.AddOrUpdateItem(iPosition); + } + } + } + + // + // Now we Have a Map which Filled Based on Separate Symbols and InDrawDown Positions ... + int mapCount = symbolMap.Count(); + if (!IsValidSize(mapCount)) + { + return; + } + + // + string mSymbols[]; + XSCPositionHolder *mHolders[]; + mapCount = symbolMap.CopyTo( + mSymbols, + mHolders // + ); + if (!IsValidSize(mapCount)) + { + return; + } + + // + for (int i = 0; i < mapCount; i++) + { + // + string iSymbol = mSymbols[i]; + XSCPositionHolder *iHolder = mHolders[i]; + + // + XPosition iMaxInDP; + bool hasMaxInDP = iHolder.GetMaxInDrawdown(iMaxInDP); + if (!hasMaxInDP) + { + continue; + } // - // Do what we want when a Position Dropped to Drawdown ... - if (onDrawdownCount > 0) - { - // - for (int i = 0; i < onDrawdownCount; i++) - { - // - XPositionTrack iTrack = state.onDrawdowns[i]; - - // - string message = "Position (" + ToString(iTrack.ticket) + ", " + iTrack.symbol + ") Dropped in Drawdown ..."; - mAlert.Alert(message); - } - } + // Try to Protect a Position ... + ProtectPosition(iMaxInDP); } } @@ -949,6 +1615,21 @@ protected: } } + // + // Protect Specified Position ... + void ProtectPosition(XPosition &position) + { + // + // Here i Can Protect Position ... + + // + string message = "For (" + position.symbol + ") Max In Drawdown Position is: (" + + ToString(position.ticket) + "), by Profit: " + ToString(position.profit); + + // + mAlert.Alert(message); + } + // // Private ... private: diff --git a/Classes/x-saherelm.x121.xmcycle.class.mq5 b/Classes/x-saherelm.x121.xmcycle.class.mq5 index accf3255..3d96ff89 100644 --- a/Classes/x-saherelm.x121.xmcycle.class.mq5 +++ b/Classes/x-saherelm.x121.xmcycle.class.mq5 @@ -27,6 +27,7 @@ #include "../Libraries/x-saherelm.draw.lib.mq5" // +#include "../Helpers/x-saherelm.xhk.helper.mq5" #include "../Helpers/x-saherelm.xmc.helper.mq5" #include "../Helpers/x-saherelm.xpv.helper.mq5" #include "../Helpers/x-saherelm.xzg.helper.mq5" @@ -74,6 +75,7 @@ public: bool drawPBarMid; // Draw Previous Bar Mid Line // + XHKInputs hkInputs; // HK Inputs ... XMCInputs mcInputs; // MC Inputs ... XPVInputs pvInputs; // XPV Inputs ... XZGInputs zgInputs; // XZG Inputs ... @@ -126,6 +128,7 @@ public: if (useDefaults) { // + hkInputs.Default(); mcInputs.Default(); pvInputs.Default(); zgInputs.Default(); @@ -153,6 +156,7 @@ public: string mSymbol, // Trading Symbol ENUM_TIMEFRAMES mHostPeriod, // Host Period ENUM_X_MARKET_CYCLES mCycle, // Init Cycle + XHKInputs &mHkInputs, // HK Inputs XMCInputs &mMcInputs, // MC Inputs XPVInputs &mPvInputs, // XPV Inputs ... XZGInputs &mZgInputs, // XZG Inputs ... @@ -183,6 +187,7 @@ public: } // + hkInputs = mHkInputs; mcInputs = mMcInputs; pvInputs = mPvInputs; zgInputs = mZgInputs; @@ -211,6 +216,7 @@ public: cycle.Clean(); // + hkInputs.Clean(); mcInputs.Clean(); pvInputs.Clean(); zgInputs.Clean(); @@ -239,6 +245,7 @@ public: virtual void Default() { // + hkInputs.Default(); mcInputs.Default(); pvInputs.Default(); zgInputs.Default(); @@ -270,6 +277,13 @@ public: return result; } + // + result = hkInputs.IsValid(); + if (!result) + { + return result; + } + // result = mcInputs.IsValid(); if (!result) @@ -341,6 +355,7 @@ public: result = MathMax(mcInputs.Max(), strInputs.Max()); // + result = MathMax(result, hkInputs.Max()); result = MathMax(result, mcInputs.Max()); result = MathMax(result, pvInputs.Max()); result = MathMax(result, zgInputs.Max()); @@ -387,6 +402,10 @@ public: // // Buffers ... + // + XOHCL hkBars[]; + XOHCL smHKBars[]; + // // XICH ... double ichTenkanSens[]; @@ -467,6 +486,23 @@ public: double oscStochSignals[]; double oscStddevs[]; + // + // XHK ... + + // + bool isHKBullish; + bool isSMHKBullish; + bool isHKBearish; + bool isSMHKBearish; + bool isClosedOverSMHK; + bool isClosedUnderSMHK; + bool isHKBullishPrev; + bool isSMHKBullishPrev; + bool isHKBearishPrev; + bool isSMHKBearishPrev; + bool isClosedOverSMHKPrev; + bool isClosedUnderSMHKPrev; + // // XZG ... @@ -1012,6 +1048,8 @@ public: // // Buffers ... Clean(bars); + Clean(hkBars); + Clean(smHKBars); Clean(ichTenkanSens); Clean(ichKijunSens); Clean(ichChikouSpans); @@ -1072,6 +1110,8 @@ public: // // Buffers ... ArraySetAsSeries(bars, true); + ArraySetAsSeries(hkBars, true); + ArraySetAsSeries(smHKBars, true); ArraySetAsSeries(ichTenkanSens, true); ArraySetAsSeries(ichKijunSens, true); ArraySetAsSeries(ichChikouSpans, true); @@ -1130,6 +1170,18 @@ public: ArraySetAsSeries(pvHCLLs, true); // + isHKBullish = false; + isSMHKBullish = false; + isHKBearish = false; + isSMHKBearish = false; + isClosedOverSMHK = false; + isClosedUnderSMHK = false; + isHKBullishPrev = false; + isSMHKBullishPrev = false; + isHKBearishPrev = false; + isSMHKBearishPrev = false; + isClosedOverSMHKPrev = false; + isClosedUnderSMHKPrev = false; isZigZagInPeak = false; isZigZagInVale = false; isDONAttachedMaxLower = false; @@ -1357,6 +1409,85 @@ public: bearScore++; } + // + // XHK ... + + // + if (isHKBullish) + { + // + bullScore++; + bearScore--; + } + if (isSMHKBullish) + { + // + bullScore++; + bearScore--; + } + if (isHKBearish) + { + // + bullScore--; + bearScore++; + } + if (isSMHKBearish) + { + // + bullScore--; + bearScore++; + } + if (isClosedOverSMHK) + { + // + bullScore++; + bearScore--; + } + if (isClosedUnderSMHK) + { + // + bullScore--; + bearScore++; + } + + // + if (isHKBullishPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isSMHKBullishPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isHKBearishPrev) + { + // + bullScore--; + bearScore += 2; + } + if (isSMHKBearishPrev) + { + // + bullScore--; + bearScore += 2; + } + if (isClosedOverSMHKPrev) + { + // + bullScore += 2; + bearScore--; + } + if (isClosedUnderSMHKPrev) + { + // + bullScore--; + bearScore += 2; + } + // // XZG ... if (isZigZagInPeak) @@ -2167,6 +2298,27 @@ public: ; candlesticStr = SetLabel("Candelstick: ", candlesticStr, separator); + // + // XHK ... + string hkStr = + // + ToString("isHKBullish", isHKBullish, ignoreFalseConditions) + + ToString("isSMHKBullish", isSMHKBullish, ignoreFalseConditions) + + ToString("isHKBearish", isHKBearish, ignoreFalseConditions) + + ToString("isSMHKBearish", isSMHKBearish, ignoreFalseConditions) + + ToString("isClosedOverSMHK", isClosedOverSMHK, ignoreFalseConditions) + + ToString("isClosedUnderSMHK", isClosedUnderSMHK, ignoreFalseConditions) + + ToString("isHKBullishPrev", isHKBullishPrev, ignoreFalseConditions) + + ToString("isSMHKBullishPrev", isSMHKBullishPrev, ignoreFalseConditions) + + ToString("isHKBearishPrev", isHKBearishPrev, ignoreFalseConditions) + + ToString("isSMHKBearishPrev", isSMHKBearishPrev, ignoreFalseConditions) + + ToString("isClosedOverSMHKPrev", isClosedOverSMHKPrev, ignoreFalseConditions) + + ToString("isClosedUnderSMHKPrev", isClosedUnderSMHKPrev, ignoreFalseConditions) + + "" + // + ; + hkStr = SetLabel("XHK: ", hkStr, separator); + // // XZG ... string zigzagStr = @@ -2455,7 +2607,8 @@ public: candlesticStr + (onlySummary ? "" - : zigzagStr + + : hkStr + + zigzagStr + strStr + cheStr + donStr + @@ -2523,6 +2676,7 @@ class XSCX121Market : XSCBase public: // // Props ... + XSCXHKHelper hk; XSCXMCHelper mc; XSCXPVHelper pv; XSCXZGHelper zg; @@ -2767,6 +2921,55 @@ public: conditions.isCurrentMidLineOverLastMidLine = isCurrentMidLineOverLastMidLine; conditions.isCurrentMidLineUnderLastMidLine = isCurrentMidLineUnderLastMidLine; + // + // XHK ... + + // + hk.CopyAsOHCL( + barIndex, + mNumberOfItems, + conditions.hkBars // + ); + + // + hk.CopySMAsOHCL( + barIndex, + mNumberOfItems, + conditions.smHKBars // + ); + + // + bool isHKBullish = conditions.hkBars[curr].IsBullish(); + bool isHKBullishPrev = conditions.hkBars[prev].IsBullish(); + bool isSMHKBullish = conditions.smHKBars[curr].IsBullish(); + bool isSMHKBullishPrev = conditions.smHKBars[prev].IsBullish(); + + // + bool isHKBearish = conditions.hkBars[curr].IsBearish(); + bool isHKBearishPrev = conditions.hkBars[prev].IsBearish(); + bool isSMHKBearish = conditions.smHKBars[curr].IsBearish(); + bool isSMHKBearishPrev = conditions.smHKBars[prev].IsBearish(); + + // + bool isClosedOverSMHK = conditions.bars[curr].close > conditions.smHKBars[curr].GetUp(); + bool isClosedUnderSMHK = conditions.bars[curr].close < conditions.smHKBars[curr].GetDown(); + bool isClosedOverSMHKPrev = conditions.bars[prev].close > conditions.smHKBars[prev].GetUp(); + bool isClosedUnderSMHKPrev = conditions.bars[prev].close < conditions.smHKBars[prev].GetDown(); + + // + conditions.isHKBullish = isHKBullish; + conditions.isSMHKBullish = isSMHKBullish; + conditions.isHKBearish = isHKBearish; + conditions.isSMHKBearish = isSMHKBearish; + conditions.isClosedOverSMHK = isClosedOverSMHK; + conditions.isClosedUnderSMHK = isClosedUnderSMHK; + conditions.isHKBullishPrev = isHKBullishPrev; + conditions.isSMHKBullishPrev = isSMHKBullishPrev; + conditions.isHKBearishPrev = isHKBearishPrev; + conditions.isSMHKBearishPrev = isSMHKBearishPrev; + conditions.isClosedOverSMHKPrev = isClosedOverSMHKPrev; + conditions.isClosedUnderSMHKPrev = isClosedUnderSMHKPrev; + // // XZG ... @@ -4258,6 +4461,19 @@ public: // // Init Helpers ... + // + // XHK ... + result = hk.Init( + symbol, + period, + mInputs.hkInputs + // + ); + if (!result) + { + return result; + } + // // XMC ... result = mc.Init( diff --git a/Classes/x-saherelm.x5.provider.class.mq5 b/Classes/x-saherelm.x5.provider.class.mq5 index 6babc825..a23bcc2c 100644 --- a/Classes/x-saherelm.x5.provider.class.mq5 +++ b/Classes/x-saherelm.x5.provider.class.mq5 @@ -2156,9 +2156,10 @@ public: // // Constructor ... XSCX5Provider( - string symbol, // Trading Symbol - ENUM_TIMEFRAMES period // Trading PEriod - ) : XSCBaseProvider(symbol, period) + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + double staticVolume // Static Volume for Positions + ) : XSCBaseProvider(symbol, period, staticVolume) { // tsHelper = new XSCXTSHelper(); @@ -2516,7 +2517,7 @@ public: { // mConditions.Clear(); - + // if (barIndex < 0) { @@ -2539,8 +2540,7 @@ public: mConditions.time = iTime( mConditions.symbol, mConditions.period, - barIndex - ); + barIndex); // GetBars( @@ -95116,6 +95116,7 @@ struct X5ProviderDescriptor // string symbol; // Trading Symbol ENUM_TIMEFRAMES period; // Trading Timeframe + double staticVolume; // Static Volume for Positions bool allowLong; // Allow Long Signals bool allowShort; // Allow Short Signals ENUM_X5_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers @@ -95143,7 +95144,8 @@ struct X5ProviderDescriptor this.period, this.signallers, this.allowLong, - this.allowShort // + this.allowShort, + this.staticVolume // ); // @@ -95154,7 +95156,8 @@ struct X5ProviderDescriptor bool Init( ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -95166,7 +95169,8 @@ struct X5ProviderDescriptor this.period, mSignallers, mAllowLong, - mAllowShort // + mAllowShort, + mStaticVolume // ); // @@ -95179,7 +95183,8 @@ struct X5ProviderDescriptor ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -95191,6 +95196,7 @@ struct X5ProviderDescriptor inputs.IsValid() && IsValid(mSymbol) && IsValid(mPeriod) && + NotEmpty(mStaticVolume) && (allowLong || allowShort) && ArraySize(mSignallers) > 0 // @@ -95205,6 +95211,7 @@ struct X5ProviderDescriptor this.period = mPeriod; this.allowLong = mAllowLong; this.allowShort = mAllowShort; + this.staticVolume = mStaticVolume; // ENUM_X5_SIGNAL_PROVIDERS tmp[]; @@ -95221,7 +95228,8 @@ struct X5ProviderDescriptor // Instantiate Provider ... provider = new XSCX5Provider( this.symbol, - this.period // + this.period, + this.staticVolume // ); // @@ -95280,6 +95288,7 @@ struct X5ProviderDescriptor // IsValid(symbol) && IsValid(period) && + NotEmpty(staticVolume) && (validateInputs ? inputs.IsValid() : true) && diff --git a/Classes/x-saherelm.x5.xea.class.mq5 b/Classes/x-saherelm.x5.xea.class.mq5 index 938cae7f..e03f1488 100644 --- a/Classes/x-saherelm.x5.xea.class.mq5 +++ b/Classes/x-saherelm.x5.xea.class.mq5 @@ -51,6 +51,7 @@ public: double maxAllowedSpread, // Max Allowed Spred for Opening Trades int maxAllowedPositions, // Max Allowed Positions double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + double staticVolume, // Static Volume for Positions // // Position Management ... bool allowLong = true, // Allow Long Trades @@ -84,6 +85,7 @@ public: allowShort, minProfitPerTrade, minProfitPerVolumeFactor, + staticVolume, onStopLossTriggered, onTakeProfitTriggered, onDealsChangedHandler, @@ -226,7 +228,7 @@ public: // // Handl Management Actions ... // if returns true, it is going to prevent for processing forward ... - bool HandleStateManagement() override + bool HandleStateManagement(XSignal &signals[]) override { // // TODO: Implement this ... diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index 912d1fd1..f19e932c 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -1287,6 +1287,7 @@ public: double maxAllowedSpread, // Max Allowed Spred for Opening Trades int maxAllowedPositions, // Max Allowed Positions double maxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + double staticVolume, // Static Volume for Positions // // Position Management ... bool allowLong = true, // Allow Long Trades @@ -1331,6 +1332,7 @@ public: mAllowShort = allowShort; mMinProfitPerTrade = minProfitPerTrade; mMinProfitPerVolumeFactor = minProfitPerVolumeFactor; + mStaticVolume = staticVolume; // // Set Event Handlers ... @@ -1451,6 +1453,25 @@ public: return mTrader.GetMaxAllowedDrawdownFactor(); } + // + double GetStaticVolume() + { + return mStaticVolume; + } + + // + void SetStaticVolume(double value) + { + // + if (value <= 0) + { + value = 0.01; + } + + // + mStaticVolume = value; + } + // bool GetAllowLong() { @@ -1953,6 +1974,10 @@ public: virtual void OnLongsGoingToDrawdown(XProfitTrack &track) {} virtual void OnShortsGoingToDrawdown(XProfitTrack &track) {} + // + virtual void OnPositionGoingInProfit(XPositionTrack &track) {} + virtual void OnPositionGoingToDrawdown(XPositionTrack &track) {} + // // Protected ... protected: @@ -2267,6 +2292,36 @@ protected: // void HandleProfitManageMent() { + // + // Check Tracking Interval ... + + // + static datetime lastProfitTracked = NULL; + datetime cTime = TimeCurrent(); + + // + int profitManagementInterval = PeriodSeconds(PERIOD_M5); + int timeDiff = (int)cTime - (int)lastProfitTracked; + + // + bool canManage = + // + lastProfitTracked == NULL + ? true + : timeDiff >= profitManagementInterval + // + ; + if (!canManage) + { + return; + } + + // + lastProfitTracked = cTime; + + // + // Do Track ... + // AddProfitTrack(); @@ -2376,6 +2431,85 @@ protected: } } + // + // Synchronize Positions and Position Tracker ... + void SyncPositionTracker() + { + // + // Check Syncing Interval ... + + // + static datetime lastSyncPositionTracker = NULL; + datetime cTime = TimeCurrent(); + + // + int syncInterval = PeriodSeconds(PERIOD_M5); + int lastDiff = (int)cTime - (int)lastSyncPositionTracker; + + // + bool canSync = + // + lastSyncPositionTracker == NULL + ? true + : lastDiff >= syncInterval + // + ; + if (!canSync) + { + return; + } + + // + lastSyncPositionTracker = cTime; + + // + // Do Sync ... + + // + XPositionTrackerState state; + int synced = mPositionTracker.Sync( + state, + mTrader // + ); + if (synced > 0) + { + // + // Check State and Do What we Want ... + int onProfitsCount = ArraySize(state.onProfits); + int onDrawdownCount = ArraySize(state.onDrawdowns); + + // + // Do What we want whe a Position Dropped to Prefit ... + if (onProfitsCount > 0) + { + // + for (int i = 0; i < onProfitsCount; i++) + { + // + XPositionTrack iTrack = state.onProfits[i]; + + // + OnPositionGoingInProfit(iTrack); + } + } + + // + // Do what we want when a Position Dropped to Drawdown ... + if (onDrawdownCount > 0) + { + // + for (int i = 0; i < onDrawdownCount; i++) + { + // + XPositionTrack iTrack = state.onDrawdowns[i]; + + // + OnPositionGoingToDrawdown(iTrack); + } + } + } + } + // // Guards ... @@ -2855,6 +2989,7 @@ private: bool mAllowShort; // Allow Short Trades double mMinProfitPerTrade; // Min Profit Per Trade based On Volume Factor (Hedge) double mMinProfitPerVolumeFactor; // Min Volume Factor for Calculating Profit (Hedge) + double mStaticVolume; // Static Volume for Positions // // Event Handlers ... diff --git a/Classes/x-saherelm.xprovider.class.mq5 b/Classes/x-saherelm.xprovider.class.mq5 index 58bb1dbc..753864d5 100644 --- a/Classes/x-saherelm.xprovider.class.mq5 +++ b/Classes/x-saherelm.xprovider.class.mq5 @@ -108,8 +108,9 @@ public: // // Constructor ... XSCBaseProvider( - string symbol, // Trading Symbol - ENUM_TIMEFRAMES period // Trading Period + string symbol, // Trading Symbol + ENUM_TIMEFRAMES period, // Trading Period + double staticVolume // Static Volume for Positions ) { // @@ -123,6 +124,9 @@ public: "HOST Period" // ); + + // + mStaticVolume = staticVolume; } // @@ -183,6 +187,12 @@ public: return mCycle.hostPeriod; } + // + double GetStaticVolume() + { + return mStaticVolume; + } + // // Count Bars ... int CountBars() @@ -207,6 +217,9 @@ protected: // // Props ... + // + double mStaticVolume; // Static Volume for Positions + // XMarketCycle mCycle; diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index ddf872bd..c75db8b6 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -2164,7 +2164,6 @@ public: bool isSelectionMethodFilterPassed = // (method == NULL || - method == X_POSITION_SELECT_ALL || method == X_POSITION_SELECT_ALL) ? true : false; @@ -2296,7 +2295,6 @@ public: bool isSelectionMethodFilterPassed = // (method == NULL || - method == X_POSITION_SELECT_ALL || method == X_POSITION_SELECT_ALL) ? true : false; diff --git a/Experts/x-test.x121ea.mq5 b/Experts/x-test.x121ea.mq5 index 974bb9f4..4bb37951 100644 --- a/Experts/x-test.x121ea.mq5 +++ b/Experts/x-test.x121ea.mq5 @@ -40,7 +40,7 @@ bool x121EAAllowShort = true; // Allow Short Trades int x121EAManageInterval = 0; // Manager Check Intervals Seconds int x121EAMaxAllowedPositions = 10; // Max Allowed Positions double x121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades -double x121EAMinProfitPerTrade = 5; // Min Profit Per Trade based On Volume Factor (Hedge) +double x121EAMinProfitPerTrade = 3; // Min Profit Per Trade based On Volume Factor (Hedge) double x121EAMinProfitPerVolumeFactor = 0.01; // Min Volume Factor for Calculating Profit (Hedge) double x121EAMaxAllowedDrawdownFactor = 0.002; // Max Allowed Drawdown Factor // @@ -207,6 +207,7 @@ bool InitialEA() x121EAMaxAllowedSpread, // Max Allowed Spred for Opening Trades x121EAMaxAllowedPositions, // Max Allowed Positions x121EAMaxAllowedDrawdownFactor, // Max Allowed Drawdown Factor + x121EAVolume, // Static Volume for Positions x121EAAllowLong, // Allow Long Trades x121EAAllowShort, // Allow Short Trades x121EAMinProfitPerTrade, // Min Profit Per Trade based On Volume Factor (Hedge) @@ -229,6 +230,7 @@ bool InitialEA() // iDescriptor.symbol = iSymbol; iDescriptor.period = iPeriod; + iDescriptor.staticVolume = x121EAVolume; iDescriptor.allowLong = x121EAAllowLong; iDescriptor.allowShort = x121EAAllowShort; Copy( @@ -242,181 +244,12 @@ bool InitialEA() // // Prepare Input Requirements ... - // - // XMC ... - iDescriptor.inputs.mcInputs.showFastMa = false; - iDescriptor.inputs.mcInputs.showSlowMa = false; - iDescriptor.inputs.mcInputs.showVerifierMa = false; - - // - // XICH ... - iDescriptor.inputs.ichInputs.showKumo = false; - iDescriptor.inputs.ichInputs.showKijunSen = false; - iDescriptor.inputs.ichInputs.showTenkanSen = false; - iDescriptor.inputs.ichInputs.showChikouSpan = false; - iDescriptor.inputs.ichInputs.showSenkouSpanA = false; - iDescriptor.inputs.ichInputs.showSenkouSpanB = false; - iDescriptor.inputs.ichInputs.showKijunSenPlus = false; - iDescriptor.inputs.ichInputs.showKijunSenNegative = false; - - // - // XCHE ... - iDescriptor.inputs.cheInputs.showLongExit1Line = false; - iDescriptor.inputs.cheInputs.showShortExit1Line = false; - iDescriptor.inputs.cheInputs.showLongExit2Line = false; - iDescriptor.inputs.cheInputs.showShortExit2Line = false; - - // - // XPV ... - iDescriptor.inputs.pvInputs.showPeaksAndVales = true; - iDescriptor.inputs.pvInputs.showLevels = false; - iDescriptor.inputs.pvInputs.showConsolidations = false; - iDescriptor.inputs.pvInputs.showFibo1Levels = false; - iDescriptor.inputs.pvInputs.showFibo2Levels = false; - iDescriptor.inputs.pvInputs.showFibo3Levels = false; - iDescriptor.inputs.pvInputs.showFibo4Levels = false; - iDescriptor.inputs.pvInputs.showFibo5Levels = false; - - // - // XZG ... - iDescriptor.inputs.zgInputs.showZigZag = false; - iDescriptor.inputs.zgInputs.showPeaksAndVales = false; - - // - // XDON ... - iDescriptor.inputs.donInputs.showOpen = false; - iDescriptor.inputs.donInputs.showHigh = false; - iDescriptor.inputs.donInputs.showClose = false; - iDescriptor.inputs.donInputs.showLow = false; - - // - // XSTR ... - iDescriptor.inputs.strInputs.showTrends = false; - iDescriptor.inputs.strInputs.fillTrends = false; - // iDescriptor.inputs.symbol = iSymbol; iDescriptor.inputs.period = iPeriod; // - // Short MArket ... - iDescriptor.inputs.sMarketPeriod = NULL; - iDescriptor.inputs.sMarketMethod = X_PERIOD_AUTO; - - // - // Medium Market ... - iDescriptor.inputs.mMarketPeriod = NULL; - iDescriptor.inputs.mMarketMethod = X_PERIOD_AUTO; - - // - // Long Market ... - iDescriptor.inputs.lMarketPeriod = NULL; - iDescriptor.inputs.lMarketMethod = X_PERIOD_AUTO; - - // - int fontSize = 12; - double fontAngel = 90; - string fontName = "Arial"; - ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER; - - // - // Hind Market ... - iDescriptor.inputs.hMarketPeriod = NULL; - iDescriptor.inputs.hMarketMethod = X_PERIOD_AUTO; - iDescriptor.inputs.hMarketInputs.drawLabels = false; - iDescriptor.inputs.hMarketInputs.drawCBar = false; - iDescriptor.inputs.hMarketInputs.drawPBar = false; - iDescriptor.inputs.hMarketInputs.drawCBarMid = false; - iDescriptor.inputs.hMarketInputs.drawPBarMid = false; - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.Default(); - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.Default(); - - // - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.openStyle.Label( - "C Hind Open", - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.openStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.highStyle.Label( - "C Hind High", - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.highStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.closeStyle.Label( - "C Hind Close", - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.closeStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.lowStyle.Label( - "C Hind Low", - iDescriptor.inputs.hMarketInputs.cBarDrawSpecs.lowStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - - // - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.openStyle.Label( - "P Hind Open", - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.openStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.highStyle.Label( - "P Hind High", - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.highStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.closeStyle.Label( - "P Hind Close", - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.closeStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.lowStyle.Label( - "P Hind Low", - iDescriptor.inputs.hMarketInputs.pBarDrawSpecs.lowStyle.clr, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - - iDescriptor.inputs.hMarketInputs.cBarMidDrawSpecs.clr = clrYellow; - iDescriptor.inputs.hMarketInputs.cBarMidDrawSpecs.Label( - "C Hind Mid", - clrYellow, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); - iDescriptor.inputs.hMarketInputs.pBarMidDrawSpecs.clr = clrYellow; - iDescriptor.inputs.hMarketInputs.pBarMidDrawSpecs.Label( - "P Hind Mid", - clrYellow, - fontName, - fontSize, - fontAnchor, - fontAngel // - ); + ConfigureDescriptor(iDescriptor); // // Init Inputs ... @@ -446,4 +279,675 @@ bool InitialEA() return result; } +// +// Configurators ... + +// +// Configuring Descriptors ... +void ConfigureDescriptor( + X121ProviderDescriptor &iDescriptor // +) +{ + // + // XHK ... + iDescriptor.inputs.hkInputs.drawHikenAshi = false; + iDescriptor.inputs.hkInputs.drawSmoothedHikenAshi = true; + + // + // XMC ... + iDescriptor.inputs.mcInputs.showFastMa = false; + iDescriptor.inputs.mcInputs.showSlowMa = false; + iDescriptor.inputs.mcInputs.showVerifierMa = false; + + // + // XICH ... + iDescriptor.inputs.ichInputs.showKumo = false; + iDescriptor.inputs.ichInputs.showKijunSen = false; + iDescriptor.inputs.ichInputs.showTenkanSen = false; + iDescriptor.inputs.ichInputs.showChikouSpan = false; + iDescriptor.inputs.ichInputs.showSenkouSpanA = false; + iDescriptor.inputs.ichInputs.showSenkouSpanB = false; + iDescriptor.inputs.ichInputs.showKijunSenPlus = false; + iDescriptor.inputs.ichInputs.showKijunSenNegative = false; + + // + // XCHE ... + iDescriptor.inputs.cheInputs.showLongExit1Line = false; + iDescriptor.inputs.cheInputs.showShortExit1Line = false; + iDescriptor.inputs.cheInputs.showLongExit2Line = false; + iDescriptor.inputs.cheInputs.showShortExit2Line = false; + + // + // XPV ... + iDescriptor.inputs.pvInputs.showPeaksAndVales = true; + iDescriptor.inputs.pvInputs.showLevels = false; + iDescriptor.inputs.pvInputs.showConsolidations = false; + iDescriptor.inputs.pvInputs.showFibo1Levels = false; + iDescriptor.inputs.pvInputs.showFibo2Levels = false; + iDescriptor.inputs.pvInputs.showFibo3Levels = false; + iDescriptor.inputs.pvInputs.showFibo4Levels = false; + iDescriptor.inputs.pvInputs.showFibo5Levels = false; + + // + // XZG ... + iDescriptor.inputs.zgInputs.showZigZag = false; + iDescriptor.inputs.zgInputs.showPeaksAndVales = false; + + // + // XDON ... + iDescriptor.inputs.donInputs.showOpen = false; + iDescriptor.inputs.donInputs.showHigh = false; + iDescriptor.inputs.donInputs.showClose = false; + iDescriptor.inputs.donInputs.showLow = false; + + // + // XSTR ... + iDescriptor.inputs.strInputs.showTrends = false; + iDescriptor.inputs.strInputs.fillTrends = false; + + // + // Short MArket ... + iDescriptor.inputs.sMarketPeriod = NULL; + iDescriptor.inputs.sMarketMethod = X_PERIOD_AUTO; + + // + // Medium Market ... + iDescriptor.inputs.mMarketPeriod = NULL; + iDescriptor.inputs.mMarketMethod = X_PERIOD_AUTO; + + // + // Long Market ... + iDescriptor.inputs.lMarketPeriod = NULL; + iDescriptor.inputs.lMarketMethod = X_PERIOD_AUTO; + + // + int fontSize = 12; + double fontAngel = 90; + string fontName = "Arial"; + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER; + + // + // Current Market ... + ConfigureCurrentMarketDrawSpecs( + // + iDescriptor, + // + "Current", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Short Market ... + ConfigureShortMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.sMarketPeriod, + iDescriptor.inputs.sMarketMethod, + // + "Short", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Medium Market ... + ConfigureMediumMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.mMarketPeriod, + iDescriptor.inputs.mMarketMethod, + // + "Medium", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Long Market ... + ConfigureLongMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.lMarketPeriod, + iDescriptor.inputs.lMarketMethod, + // + "Long", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); + + // + // Hind Market ... + ConfigureHindMarketDrawSpecs( + // + iDescriptor, + // + iDescriptor.inputs.hMarketPeriod, + iDescriptor.inputs.hMarketMethod, + // + "Hind", + // + false, // Draw Labels ... + false, // Draw C Bar ... + false, // Draw P Bar ... + false, // Draw C Bar Mid Line ... + false, // Draw P Bar Mid Line ... + // + fontSize, + fontAngel, + fontName, + fontAnchor // , + // + // cBarPrefix + // pBarPrefix + // openLabel + // closeLabel + // highLabel + // lowLabel + // midLineLabel + ); +} + +// +// Current ... +void ConfigureCurrentMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + string prefix = "Current", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.cMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Short ... +void ConfigureShortMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Short", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Short Market ... + iDescriptor.inputs.sMarketPeriod = period; + iDescriptor.inputs.sMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.sMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Medium ... +void ConfigureMediumMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Medium", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Medium Market ... + iDescriptor.inputs.mMarketPeriod = period; + iDescriptor.inputs.mMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.mMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Long ... +void ConfigureLongMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Long", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Long Market ... + iDescriptor.inputs.lMarketPeriod = period; + iDescriptor.inputs.lMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.lMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Hind ... +void ConfigureHindMarketDrawSpecs( + X121ProviderDescriptor &iDescriptor, + ENUM_TIMEFRAMES period = NULL, + ENUM_X_PERIOD_METHOD method = X_PERIOD_AUTO, + string prefix = "Hind", + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + // + // Hind Market ... + iDescriptor.inputs.hMarketPeriod = period; + iDescriptor.inputs.hMarketMethod = method; + + // + ConfigureMarketDrawSpecs( + iDescriptor.inputs.hMarketInputs, + // + drawLabels, + drawCBar, + drawPBar, + drawCBarMid, + drawPBarMid, + fontSize, + fontAngel, + fontName, + fontAnchor, + prefix, + cBarPrefix, + pBarPrefix, + openLabel, + closeLabel, + highLabel, + lowLabel, + midLineLabel // + ); +} + +// +// Configure Market ... +void ConfigureMarketDrawSpecs( + X121MCycleInputs &inputs, + bool drawLabels = false, + bool drawCBar = false, + bool drawPBar = false, + bool drawCBarMid = false, + bool drawPBarMid = false, + int fontSize = 12, + double fontAngel = 90, + string fontName = "Arial", + ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER, + string prefix = "", + string cBarPrefix = "C", + string pBarPrefix = "P", + string openLabel = "O", + string closeLabel = "C", + string highLabel = "H", + string lowLabel = "L", + string midLineLabel = "Mid" // +) +{ + inputs.drawLabels = drawLabels; + inputs.drawCBar = drawCBar; + inputs.drawPBar = drawPBar; + inputs.drawCBarMid = drawCBarMid; + inputs.drawPBarMid = drawPBarMid; + inputs.cBarDrawSpecs.Default(); + inputs.pBarDrawSpecs.Default(); + + // + if (drawCBarMid) + { + inputs.cBarMidDrawSpecs.clr = clrYellow; + } + + // + if (drawPBarMid) + { + inputs.pBarMidDrawSpecs.clr = clrYellow; + } + + // + if (drawLabels) + { + // + string cBarStr = prefix + " " + cBarPrefix + " "; + string pBarStr = prefix + " " + pBarPrefix + " "; + + // + if (drawCBar) + { + // + inputs.cBarDrawSpecs.openStyle.Label( + cBarStr + openLabel, + inputs.cBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.highStyle.Label( + cBarStr + highLabel, + inputs.cBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.closeStyle.Label( + cBarStr + closeLabel, + inputs.cBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.cBarDrawSpecs.lowStyle.Label( + cBarStr + lowLabel, + inputs.cBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawPBar) + { + // + inputs.pBarDrawSpecs.openStyle.Label( + pBarStr + openLabel, + inputs.pBarDrawSpecs.openStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.highStyle.Label( + pBarStr + highLabel, + inputs.pBarDrawSpecs.highStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.closeStyle.Label( + pBarStr + closeLabel, + inputs.pBarDrawSpecs.closeStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + + // + inputs.pBarDrawSpecs.lowStyle.Label( + pBarStr + lowLabel, + inputs.pBarDrawSpecs.lowStyle.clr, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawCBarMid) + { + // + inputs.cBarMidDrawSpecs.Label( + cBarStr + midLineLabel, + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + + // + if (drawPBarMid) + { + // + inputs.pBarMidDrawSpecs.Label( + pBarStr + midLineLabel, + clrYellow, + fontName, + fontSize, + fontAnchor, + fontAngel // + ); + } + } +} + // \ No newline at end of file diff --git a/Experts/x-test.x5121ea.mq5 b/Experts/x-test.x5121ea.mq5 index a4090013..2081bdd9 100644 --- a/Experts/x-test.x5121ea.mq5 +++ b/Experts/x-test.x5121ea.mq5 @@ -38,6 +38,7 @@ struct X5121ProviderDescriptor ENUM_TIMEFRAMES period; // Trading Timeframe bool allowLong; // Allow Long Signals bool allowShort; // Allow Short Signals + double staticVolume; // Static Volume for Positions ENUM_X5_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers // @@ -70,7 +71,8 @@ struct X5121ProviderDescriptor this.period, this.signallers, this.allowLong, - this.allowShort // + this.allowShort, + this.staticVolume // ); // @@ -81,7 +83,8 @@ struct X5121ProviderDescriptor bool Init( ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -93,7 +96,8 @@ struct X5121ProviderDescriptor this.period, mSignallers, mAllowLong, - mAllowShort // + mAllowShort, + mStaticVolume // ); // @@ -106,7 +110,8 @@ struct X5121ProviderDescriptor ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals - bool mAllowShort = true // Allow Short Signals + bool mAllowShort = true, // Allow Short Signals + double mStaticVolume = 0.01 // Static Volume for Positions ) { // @@ -118,6 +123,7 @@ struct X5121ProviderDescriptor x5Inputs.IsValid() && IsValid(mSymbol) && IsValid(mPeriod) && + NotEmpty(mStaticVolume) && (allowLong || allowShort) && ArraySize(mSignallers) > 0 // @@ -132,6 +138,7 @@ struct X5121ProviderDescriptor this.period = mPeriod; this.allowLong = mAllowLong; this.allowShort = mAllowShort; + this.staticVolume = mStaticVolume; // ENUM_X5_SIGNAL_PROVIDERS tmp[]; @@ -148,14 +155,16 @@ struct X5121ProviderDescriptor // Instantiate Provider ... x5Provider = new XSCX5Provider( this.symbol, - this.period // + this.period, + this.staticVolume // ); // // Instantiate Provider ... x121Provider = new XSCX121Provider( this.symbol, - this.period // + this.period, + this.staticVolume // ); // @@ -238,6 +247,7 @@ struct X5121ProviderDescriptor // IsValid(symbol) && IsValid(period) && + NotEmpty(staticVolume) && (validateInputs ? x5Inputs.IsValid() && x121Inputs.IsValid() : true) && @@ -675,6 +685,7 @@ bool InitialEA() // iDescriptor.symbol = symbols[i]; iDescriptor.period = PERIOD_M5; + iDescriptor.staticVolume = x5121EAVolume; iDescriptor.allowLong = x5121EAAllowLong; iDescriptor.allowShort = x5121EAAllowShort; Copy( @@ -971,33 +982,33 @@ int RequestForSignal( x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) - // - || - // + // + || + // (x121Conditions.lMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) - // - || - // + // + || + // (x121Conditions.mMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) - // - || - // + // + || + // (x121Conditions.sMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) - // - || - // + // + || + // (x121Conditions.cMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && diff --git a/Experts/x-test.x5ea.mq5 b/Experts/x-test.x5ea.mq5 index a2fcc378..cae3ad7f 100644 --- a/Experts/x-test.x5ea.mq5 +++ b/Experts/x-test.x5ea.mq5 @@ -218,6 +218,7 @@ bool InitialEA() // iDescriptor.symbol = symbols[i]; iDescriptor.period = PERIOD_M5; + iDescriptor.staticVolume = x5EAVolume; iDescriptor.allowLong = x5EAAllowLong; iDescriptor.allowShort = x5EAAllowShort; Copy( diff --git a/Helpers/x-saherelm.xhk.helper.mq5 b/Helpers/x-saherelm.xhk.helper.mq5 index 13da70c0..c9b26980 100644 --- a/Helpers/x-saherelm.xhk.helper.mq5 +++ b/Helpers/x-saherelm.xhk.helper.mq5 @@ -714,6 +714,9 @@ public: Clean(buffer); } + // + int before = ArraySize(buffer); + // if (start < 0) { @@ -727,8 +730,8 @@ public: } // - XOHCL tmp[]; - ArraySetAsSeries(tmp, false); + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); // for (int i = start; i < start + count; i++) @@ -743,30 +746,20 @@ public: // AddRef( iBar, - tmp + buffer // ); } } // - ArraySetAsSeries(tmp, true); + ArraySetAsSeries(buffer, asSeriesBuffer); // - CopyRef( - 0, - ArraySize(tmp), - tmp, - buffer, - forceClean - // - ); + int after = ArraySize(buffer); // - result = ArraySize(tmp); - - // - Clean(tmp); + result = after - before; // return result; @@ -842,6 +835,9 @@ public: Clean(buffer); } + // + int before = ArraySize(buffer); + // if (start < 0) { @@ -855,8 +851,8 @@ public: } // - XOHCL tmp[]; - ArraySetAsSeries(tmp, false); + bool asSeriesBuffer = ArrayGetAsSeries(buffer); + ArraySetAsSeries(buffer, true); // for (int i = start; i < start + count; i++) @@ -871,30 +867,20 @@ public: // AddRef( iBar, - tmp + buffer // ); } } // - ArraySetAsSeries(tmp, true); + ArraySetAsSeries(buffer, asSeriesBuffer); // - CopyRef( - 0, - ArraySize(tmp), - tmp, - buffer, - forceClean - // - ); + int after = ArraySize(buffer); // - result = ArraySize(tmp); - - // - Clean(tmp); + result = after - before; // return result; diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index 87784476..5c42ad03 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -2763,6 +2763,47 @@ ENUM_X_MARKET_CYCLES NormalizeCycle(ENUM_X_MARKET_CYCLES value) return value; } +// +// Validate a Buffer Size for Looping or etc ... +bool IsValidSize(int size) +{ + // + bool result = size > 0; + + // + return result; +} + +// +// Normalize Index Based On Specified Buffer ... +template +void NormalizeIndex( + int &index, + T &buffer[] // +) +{ + // + int bufferSize = ArraySize(buffer); + + // + if (bufferSize <= 0) + { + index = 0; + } + + // + if (index <= 0) + { + index = 0; + } + + // + if (index > bufferSize - 1) + { + index = bufferSize - 1; + } +} + // // Normalize a give Volume ... double NormalizeVolume(