diff --git a/Classes/x-saherelm.x121.setup.cycle.class.mq5 b/Classes/x-saherelm.x121.setup.cycle.class.mq5 index 2683ef8c..d8dda788 100644 --- a/Classes/x-saherelm.x121.setup.cycle.class.mq5 +++ b/Classes/x-saherelm.x121.setup.cycle.class.mq5 @@ -30,35 +30,6 @@ // // Definitions ... -// -class X121SetupCycleScoreTracker : public XSCBase -{ - // - // Public ... -public: - // - // Define Bullish and Bearish Score ... - CArrayObj bullishScore; - CArrayObj bearishScore; - - // - // Tools ... - void AddScores( - double bullScore, - double bearScore // - ) { - // - // bullishScore - } - - // - // Protected ... -protected: - // - // Private ... -private: -}; - // // Inputs ... struct X121SetupCycleInputs diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index f2a52f2f..1fa5d7c8 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -31,35 +31,48 @@ // Definitions ... // -struct XSignalInfo +// Model all Trades Data as this Structure ... +struct XTradeInfo { // - ulong ticket; // Position Ticket - string symbol; // Trading Symbol - string provider; // Signaller - int pushers; // Signal Pushers - ENUM_TIMEFRAMES period; // Trading Timeframe - datetime time; // Issue Time (Open Position) + int pushers; // Signal Pushers + datetime time; // Issue Time (Open Position) + string symbol; // Trading Symbol + double entry; // Entry Price + double volume; // Volume + string provider; // Signaller + ENUM_TIMEFRAMES period; // Trading Timeframe + ENUM_X_POSITION_TYPE type; // Position Type // + ulong ticket; // Position Ticket double profit; // Profit on Close double commission; // Commission double swap; // Swap - double volume; // Volume - datetime endTime; // End Time string message; // Close Reason + datetime endTime; // End Time + + // + int bullishSigns; // Bullish Signs On Signal Time + int bearishSigns; // Bearish Signs On Signal Time // double bullishScore; // Bullish Score On Signal Time double bearishScore; // Bearish Score On Signal Time // - XSignal signal; // Generated Signal - X121SetupConditions conditions; // Generated Conditions + double volumeOSC; // Volume Weight On Signal Time + + // + X121SetupConditions cConditions; // Generated Current Conditions + X121SetupConditions sConditions; // Generated Short Conditions + X121SetupConditions mConditions; // Generated Medium Conditions + X121SetupConditions lConditions; // Generated Long Conditions + X121SetupConditions hConditions; // Generated Hind Conditions // // Constructor ... - void XSignalInfo() + void XTradeInfo() { Clean(); } @@ -72,31 +85,53 @@ struct XSignalInfo void Clean() { // - ticket = 0; + time = NULL; + type = NULL; symbol = NULL; period = NULL; - provider = NULL; - pushers = 0; - time = NULL; - profit = 0; - commission = 0; - swap = 0; - volume = 0; endTime = NULL; message = NULL; + provider = NULL; + + // + swap = 0; + entry = 0; + ticket = 0; + profit = 0; + volume = 0; + pushers = 0; + volumeOSC = 0; + commission = 0; + bullishSigns = 0; + bearishSigns = 0; bullishScore = 0; bearishScore = 0; - signal.Clean(); - conditions.Clean(); + + // + cConditions.Clean(); + sConditions.Clean(); + mConditions.Clean(); + lConditions.Clean(); + hConditions.Clean(); + + // + ResetGrid(); } // bool Fill( + const XSignal &_signal, int _pushers, - XSignal &_signal, + double _volumeOSC, + int _bullishSigns, + int _bearishSigns, double _bullishScore, double _bearishScore, - X121SetupConditions &_conditions // + X121SetupConditions &_cConditions, + X121SetupConditions &_sConditions, + X121SetupConditions &_mConditions, + X121SetupConditions &_lConditions, + X121SetupConditions &_hConditions // ) { // @@ -119,14 +154,27 @@ struct XSignalInfo // pushers = _pushers; + time = _signal.time; + entry = _signal.entry; symbol = _signal.symbol; period = _signal.period; volume = _signal.volume; provider = _signal.provider; + type = ToPositionType(_signal.type); // - signal = _signal; - conditions = _conditions; + cConditions = _cConditions; + sConditions = _sConditions; + mConditions = _mConditions; + lConditions = _lConditions; + hConditions = _hConditions; + + // + volumeOSC = _volumeOSC; + + // + bullishSigns = _bullishSigns; + bearishSigns = _bearishSigns; // bullishScore = _bullishScore; @@ -255,7 +303,7 @@ struct XSignalInfo result = // symbol + "\\" + - ToString(signal.type) + "\\" + + ToString(type) + "\\" + (profit >= 0 ? "Profit" : "Loss") + @@ -278,13 +326,41 @@ struct XSignalInfo string result = NULL; // - string conditionsStr = conditions - .GenerateSummary( - false, // Only Commons ... - true, // Only Conditions ... - false, // Include Score ... - false // Include False Conditions ... - ); + string cConditionsStr = cConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string sConditionsStr = sConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string mConditionsStr = mConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string lConditionsStr = lConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); + string hConditionsStr = hConditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ... + ); // int age = GetAge(); @@ -295,11 +371,18 @@ struct XSignalInfo ToString("Ticket", ticket) + ToString("Symbol", symbol) + ToString("Period", period) + - ToString("Pushers", pushers) + + ToString("Entry", entry) + ToString("Provider", provider) + + ToString("Type", ToString(type)) + ToString("Time", time) + + ToString("Pushers", pushers) + + "-------------" + "\n" + + ToString("VolumeOSC", volumeOSC) + + ToString("BullishSigns", bullishSigns) + + ToString("BearishSigns", bearishSigns) + ToString("BullishScore", bullishScore) + ToString("BearishScore", bearishScore) + + "-------------" + "\n" + ToString("Volume", volume) + ToString("Profit", profit) + ToString("Commission", commission) + @@ -308,9 +391,28 @@ struct XSignalInfo ToString("Age", age) + ToString("Message", message) + "-------------" + "\n" + - ToString("Signal", "\n" + signal.ToString()) + + "Conditions" + "\n" + "-------------" + "\n" + - ToString("Conditions", "\n" + conditionsStr) + + "-------------" + "\n" + + "CURRENT [" + ToString(cConditions.period) + "]" + "\n" + + "-------------" + "\n" + + cConditionsStr + "\n" + + "-------------" + "\n" + + "SHORT [" + ToString(sConditions.period) + "]" + "\n" + + "-------------" + "\n" + + sConditionsStr + "\n" + + "-------------" + "\n" + + "MEDIUM [" + ToString(mConditions.period) + "]" + "\n" + + "-------------" + "\n" + + mConditionsStr + "\n" + + "-------------" + "\n" + + "LONG [" + ToString(lConditions.period) + "]" + "\n" + + "-------------" + "\n" + + lConditionsStr + "\n" + + "-------------" + "\n" + + "HIND [" + ToString(hConditions.period) + "]" + "\n" + + "-------------" + "\n" + + hConditionsStr + "\n" + // "" // @@ -321,10 +423,168 @@ struct XSignalInfo } // + // These are Some Helpers for Trading Controls and do not relate to Main + // purpose of Trade Handler ... + + // + // Grid System Calculations ... + + // + double gEntry; // Represents Next Grid Signal's Entry + double gVolume; // Represent Next Grid Signal's Volume + + // + void ResetGrid() + { + gEntry = 0; + gVolume = 0; + } + + // + void SetGrid( + double nextEntry, + double nextVolume // + ) + { + // + gEntry = nextEntry; + gVolume = nextVolume; + } + + // + // Prepare Data For Next Grid ... + void PrepareNextGrid( + double distance, + double volumeMultiplier // + ) + { + // + bool isValid = + // + IsValid() && + entry > 0 && + volume > 0 && + distance > 0 && + volumeMultiplier > 0 + // + ; + bool isLong = IsLong(type); + + // + double distancePrice = PointToPrice( + distance, + symbol // + ); + + // + double selectedEntry = + gEntry <= 0 + ? entry + : gEntry; + double selectedVolume = + gVolume <= 0 + ? volume + : gVolume; + + // + double nextEntry = + isLong + ? selectedEntry - distancePrice + : selectedEntry + distancePrice; + double nextVolume = selectedVolume * volumeMultiplier; + + // + SetGrid( + nextEntry, + nextVolume // + ); + } + + // + // Check if a Grid Signal Exists Prepared and + // Provide it ... + bool HasGrid( + XSignal &signal, // Result Signal + double distance, + double volumeMultiplier // + ) + { + // + bool result = false; + + // + signal.Clean(); + + // + result = IsValid() && + distance > 0 && + volumeMultiplier > 0; + if (!result) + { + return result; + } + + // + bool isLong = IsLong(type); + + // + ENUM_POSITION_TYPE gType = + isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + + // + double cEntry = GetEntry( + symbol, + gType // + ); + + // + result = + isLong + ? cEntry <= gEntry + : cEntry >= gEntry; + if (!result) + { + return result; + } + + // + result = signal.Prepare( + symbol, + provider, + period, + gType, + X_ORDER_MODE_MARKET, + cEntry, + gVolume, + 0, // SL ... + 0 // TP ... + ); + + // + if (result) + { + // + // set Support Token ... + string comment = GenerateSupportTag(ticket); + signal.comment = comment; + + // + PrepareNextGrid( + distance, + volumeMultiplier // + ); + } + + // + return result; + } }; // -class XSignalInfoCollector +// a Class For Read and Write Trade Info Data in Files ... +class XTradeInfoCollector { // // Public ... @@ -334,7 +594,7 @@ public: // // Constructor(s) ... - void XSignalInfoCollector( + void XTradeInfoCollector( string _path = NULL // Base Path ) { @@ -348,16 +608,16 @@ public: } else { - mPath = "XSignalInfo" + "\\" + mAccount.GetCompany(); + mPath = "XTradeInfo" + "\\" + mAccount.GetCompany(); } } // // Deconstructor ... - void ~XSignalInfoCollector() {} + void ~XTradeInfoCollector() {} // - bool IsExists(XSignalInfo &item) + bool IsExists(XTradeInfo &item) { // bool result = false; @@ -372,7 +632,7 @@ public: } // - bool Save(XSignalInfo &item) + bool Save(XTradeInfo &item) { // bool result = false; @@ -426,7 +686,7 @@ private: XSCAccount *mAccount; // - string GetFilePath(XSignalInfo &item) + string GetFilePath(XTradeInfo &item) { // string fileName = item.GetFileName(); @@ -451,7 +711,7 @@ private: } // - int GetFileHandlerForRead(XSignalInfo &item) + int GetFileHandlerForRead(XTradeInfo &item) { // int result = INVALID_HANDLE; @@ -472,7 +732,7 @@ private: // return result; } - int GetFileHandlerForWrite(XSignalInfo &item) + int GetFileHandlerForWrite(XTradeInfo &item) { // int result = INVALID_HANDLE; @@ -495,6 +755,489 @@ private: } }; +// +// a Class for Holding all required data for Specified Trade +// such as: +// - Signal; +// - Position; +// - Conditions; +// - Scores; +// - etc ... +class XTradeInfoHandler +{ + // +public: + // + // Props ... + + // + // Constructor ... + void XTradeInfoHandler( + XSCTrade *trade // an Instance of Trader Class + ) + { + // + Clean(data); + SetSave(false); + mTrader = trade; + collector = new XTradeInfoCollector(); + } + + // + // Getter(s) / Setter(s) ... + + // + bool GetSave() + { + return mSave; + } + + // + void SetSave(bool value) + { + mSave = value; + } + + // + // Grid System ... + + // + bool AllowGrid() + { + return mAllowGrid; + } + + // + void AllowGrid(bool value) + { + mAllowGrid = value; + } + + // + double GridDistance() + { + return mGridDistance; + } + + // + void GridDistance(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mGridDistance = value; + } + + // + double GridVolumeMultiplier() + { + return mGridVolumeMultiplier; + } + + // + void GridVolumeMultiplier(double value) + { + // + if (value <= 1) + { + value = 0; + } + + // + mGridVolumeMultiplier = value; + } + + // + // Check Grid Properties to Validate it's Enable or not ... + bool EnableGrid() + { + // + bool result = false; + + // + result = + // + AllowGrid() && + GridDistance() > 0 && + GridVolumeMultiplier() > 0 + // + ; + + // + return result; + } + + // + // Tools ... + + // + int Count() + { + return ArraySize(data); + } + + // + int FindIndex(ulong ticket) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOwn = iInfo.IsOwn( + ticket // + ); + if (isOwn) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + int FindIndex(XSignal &signal) + { + // + int result = -1; + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XTradeInfo iInfo = data[i]; + + // + bool isOWN = + // + iInfo.time == signal.time && + iInfo.symbol == signal.symbol && + iInfo.volume == signal.volume && + iInfo.period == signal.period && + iInfo.provider == signal.provider && + iInfo.type == ToPositionType(signal.type) + // + ; + + // + if (isOWN) + { + // + result = i; + break; + } + } + + // + return result; + } + + // + void Add( + XSignal &signal, + int pushers, + double volumeOSC, + int bullishSigns, + int bearishSigns, + double bullishScore, + double bearishScore, + X121SetupConditions &cConditions, + X121SetupConditions &sConditions, + X121SetupConditions &mConditions, + X121SetupConditions &lConditions, + X121SetupConditions &hConditions // + ) + { + // + XTradeInfo signalInfo; + bool isFilled = signalInfo.Fill( + signal, + pushers, + volumeOSC, + bullishSigns, + bearishSigns, + bullishScore, + bearishScore, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); + if (!isFilled) + { + return; + } + + // + AddRef( + signalInfo, + data // + ); + } + + // + void Remove(XSignal &signal) + { + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + ArrayRemove( + data, + infoIDX, + 1 // + ); + } + + // + void Update(XSignal &signal) + { + // + if (!signal.IsValid() || !signal.IsExecuted()) + { + return; + } + + // + int infoIDX = FindIndex(signal); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].ticket = signal.positionId; + + // + // Find Orders for Accessing Commission ... + XDeal deals[]; + int dealsCount = mTrader.GetDeals( + deals, + signal.symbol, + signal.provider, + signal.period, + NULL, + DEAL_ENTRY_IN // Position Open Deal ... + ); + if (!IsValidSize(dealsCount)) + { + return; + } + + // + for (int i = 0; i < dealsCount; i++) + { + // + XDeal iDeal = deals[i]; + + // + if (iDeal.positionId == signal.positionId) + { + data[infoIDX].commission = iDeal.commission; + } + } + + // + // Check if Grid System Enable or Not ... + if (EnableGrid()) + { + // + // Here we Prepare Handler Structure for + // Next Grid Position ... + data[infoIDX].PrepareNextGrid( + GridDistance(), + GridVolumeMultiplier() // + ); + } + } + + // + void Update(XDeal &deal) + { + // + if (!deal.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(deal.positionId); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = deal.swap; + data[infoIDX].endTime = deal.time; + data[infoIDX].profit = deal.profit; + + // + string message = deal.reason == DEAL_REASON_TP + ? "TP" + : "SL"; + data[infoIDX].message = message; + + // + Finish(infoIDX); + } + + // + void Update(XPosition &position) + { + // + if (!position.IsValid()) + { + return; + } + + // + int infoIDX = FindIndex(position.ticket); + if (!IsValidIndex(infoIDX)) + { + return; + } + + // + data[infoIDX].swap = position.swap; + data[infoIDX].endTime = TimeCurrent(); + data[infoIDX].profit = position.profit; + data[infoIDX].message = position.comment; + + // + Finish(infoIDX); + } + + // + // Grid System Tools ... + int RequestForGrid(XSignal &signals[]) + { + // + int result = 0; + + // + Clean(signals); + + // + if (!EnableGrid()) + { + return result; + } + + // + int count = Count(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSignal iSignal; + bool hasGrid = data[i].HasGrid( + iSignal, + GridDistance(), + GridVolumeMultiplier() // + ); + + // + if (hasGrid) + { + // + AddRef( + iSignal, + signals // + ); + } + } + + // + result = ArraySize(signals); + + // + return result; + } + + // + // Protected ... +protected: + // + // Props ... + XSCTrade *mTrader; + XTradeInfo data[]; + XTradeInfoCollector *collector; + + // + bool mSave; // Save Results ... + + // + // Tools ... + + // + void Finish(int index) + { + // + XTradeInfo info = data[index]; + if (!info.IsValid()) + { + return; + } + + // + ArrayRemove( + data, + index, + 1 // + ); + + // + if (GetSave()) + { + collector.Save(info); + } + } + + // + // Grid ... + bool mAllowGrid; // Use Grid System to Recovery Positions + double mGridDistance; // Grid System Distance + double mGridVolumeMultiplier; // Grid System Volume Multiplier +}; + // // Class ... class XSCX121SetupEA : public XSCBaseEA @@ -539,12 +1282,8 @@ public: ) { // - Clean(mSignalInfos); - - // - // Disbale Using Signal Collector ... - UseSignalCollector(false); - mSignalCollector = new XSignalInfoCollector(); + mTradeInfoHandler = new XTradeInfoHandler(mTrader); + SaveResults(false); } // @@ -552,7 +1291,7 @@ public: ~XSCX121SetupEA() { // - delete mSignalCollector; + delete mTradeInfoHandler; // Clean(mSetups); @@ -790,65 +1529,51 @@ public: } // - bool UseGrid() + bool AllowGrid() { - return mUseGrid; + return mTradeInfoHandler.AllowGrid(); } // - void UseGrid(bool value) + void AllowGrid(bool value) { - mUseGrid = value; + mTradeInfoHandler.AllowGrid(value); } // double GridDistance() { - return mGridDistance; + return mTradeInfoHandler.GridDistance(); } // void GridDistance(double value) { - // - if (value < 0) - { - value = 0; - } - - // - mGridDistance = value; + mTradeInfoHandler.GridDistance(value); } // double GridVolumeMultiplier() { - return mGridVolumeMultiplier; + return mTradeInfoHandler.GridVolumeMultiplier(); } // void GridVolumeMultiplier(double value) { - // - if (value < 0) - { - value = 0; - } - - // - mGridVolumeMultiplier = value; + mTradeInfoHandler.GridVolumeMultiplier(value); } // - bool UseSignalCollector() + bool SaveResults() { - return mUseSignalCollector; + return mTradeInfoHandler.GetSave(); } // - void UseSignalCollector(bool value) + void SaveResults(bool value) { - mUseSignalCollector = value; + mTradeInfoHandler.SetSave(value); } // @@ -856,8 +1581,7 @@ public: // // Customize Token ... - string - GetToken() override + string GetToken() override { return GetSpecificToken(this); } @@ -1106,6 +1830,7 @@ public: sSignal, sPusher, sProvider, + mUseSupport, mAllowLong, mAllowShort, mVolume, @@ -1318,499 +2043,176 @@ public: // Parse Signals and Add them for Executing ... // - // Current Signals ... - if (cSignal.IsValid()) - { - // - bool isLong = IsLong(cSignal.type); - if (isLong) - { - mBullishSigns += cPusher; - } - else - { - mBearishSigns += cPusher; - } - - // - if (cPusher >= mReuiredSignalVerifications) - { - // - X121SetupConditions otherConditions[]; - AddRef( - sConditions, - otherConditions // - ); - AddRef( - mConditions, - otherConditions // - ); - AddRef( - lConditions, - otherConditions // - ); - AddRef( - hConditions, - otherConditions // - ); - - // - // Check Final Validations ... - bool isValid = - // - ( - // - sHasSignal - // - || - // - mHasSignal - // - || - // - lHasSignal - // - || - // - hHasSignal - // - ) - // - || - // - ( - // - !mGetVerificationFromOtherTimeFrames - ? true - : isLong - ? signalGenerator.HasLongVerifications(otherConditions) - : signalGenerator.HasShortVerifications(otherConditions) - // - ) - // - ; - - // - if (isValid) - { - // - AddRef( - cSignal, - signals // - ); - - // - if (UseSignalCollector()) - { - // - AddNewSignal( - cPusher, - cSignal, - mBullishScore, - mBearishScore, - cConditions // - ); - } - } - } - } - - // - // Short Signals ... - if (sSignal.IsValid()) - { - // - bool isLong = IsLong(sSignal.type); - if (isLong) - { - mBullishSigns += sPusher; - } - else - { - mBearishSigns += sPusher; - } - - // - if (sPusher >= mReuiredSignalVerifications) - { - // - X121SetupConditions otherConditions[]; - AddRef( - cConditions, - otherConditions // - ); - AddRef( - mConditions, - otherConditions // - ); - AddRef( - lConditions, - otherConditions // - ); - AddRef( - hConditions, - otherConditions // - ); - - // - // Check Final Validations ... - bool isValid = - // - ( - // - cHasSignal - // - || - // - mHasSignal - // - || - // - lHasSignal - // - || - // - hHasSignal - // - ) - // - || - // - ( - // - !mGetVerificationFromOtherTimeFrames - ? true - : isLong - ? signalGenerator.HasLongVerifications(otherConditions) - : signalGenerator.HasShortVerifications(otherConditions) - // - ) - // - ; - - // - if (isValid) - { - // - AddRef( - sSignal, - signals // - ); - - // - if (UseSignalCollector()) - { - // - AddNewSignal( - sPusher, - sSignal, - mBullishScore, - mBearishScore, - sConditions // - ); - } - } - } - } - - // - // Medium Signals ... - if (mSignal.IsValid()) - { - // - bool isLong = IsLong(mSignal.type); - if (isLong) - { - mBullishSigns += mPusher; - } - else - { - mBearishSigns += mPusher; - } - - // - if (mPusher >= mReuiredSignalVerifications) - { - // - X121SetupConditions otherConditions[]; - AddRef( - cConditions, - otherConditions // - ); - AddRef( - sConditions, - otherConditions // - ); - AddRef( - lConditions, - otherConditions // - ); - AddRef( - hConditions, - otherConditions // - ); - - // - // Check Final Validations ... - bool isValid = - // - ( - // - cHasSignal - // - || - // - sHasSignal - // - || - // - lHasSignal - // - || - // - hHasSignal - // - ) - // - || - // - ( - // - !mGetVerificationFromOtherTimeFrames - ? true - : isLong - ? signalGenerator.HasLongVerifications(otherConditions) - : signalGenerator.HasShortVerifications(otherConditions) - // - ) - // - ; - - // - if (isValid) - { - // - AddRef( - mSignal, - signals // - ); - - // - if (UseSignalCollector()) - { - // - AddNewSignal( - mPusher, - mSignal, - mBullishScore, - mBearishScore, - mConditions // - ); - } - } - } - } - - // - // Long Signals ... - if (lSignal.IsValid()) - { - // - bool isLong = IsLong(lSignal.type); - if (isLong) - { - mBullishSigns += lPusher; - } - else - { - mBearishSigns += lPusher; - } - - // - if (lPusher >= mReuiredSignalVerifications) - { - // - X121SetupConditions otherConditions[]; - AddRef( - cConditions, - otherConditions // - ); - AddRef( - sConditions, - otherConditions // - ); - AddRef( - mConditions, - otherConditions // - ); - AddRef( - hConditions, - otherConditions // - ); - - // - // Check Final Validations ... - bool isValid = - // - ( - // - cHasSignal - // - || - // - sHasSignal - // - || - // - mHasSignal - // - || - // - hHasSignal - // - ) - // - || - // - ( - // - !mGetVerificationFromOtherTimeFrames - ? true - : isLong - ? signalGenerator.HasLongVerifications(otherConditions) - : signalGenerator.HasShortVerifications(otherConditions) - // - ) - // - ; - - // - if (isValid) - { - // - AddRef( - lSignal, - signals // - ); - - // - if (UseSignalCollector()) - { - // - AddNewSignal( - lPusher, - lSignal, - mBullishScore, - mBearishScore, - lConditions // - ); - } - } - } - } - - // - // Hind Signals ... - if (hSignal.IsValid()) - { - // - bool isLong = IsLong(hSignal.type); - if (isLong) - { - mBullishSigns += hPusher; - } - else - { - mBearishSigns += hPusher; - } - - // - if (hPusher >= mReuiredSignalVerifications) - { - // - X121SetupConditions otherConditions[]; - AddRef( - cConditions, - otherConditions // - ); - AddRef( - sConditions, - otherConditions // - ); - AddRef( - mConditions, - otherConditions // - ); - AddRef( - lConditions, - otherConditions // - ); - - // - // Check Final Validations ... - bool isValid = - // - ( - // - cHasSignal - // - || - // - sHasSignal - // - || - // - mHasSignal - // - || - // - lHasSignal - // - ) // - || - // - ( - // - !mGetVerificationFromOtherTimeFrames - ? true - : isLong - ? signalGenerator.HasLongVerifications(otherConditions) - : signalGenerator.HasShortVerifications(otherConditions) - // - ) - // - ; - - // - if (isValid) - { - // - AddRef( - hSignal, - signals // - ); - - // - if (UseSignalCollector()) - { - // - AddNewSignal( - hPusher, - hSignal, - mBullishScore, - mBearishScore, - hConditions // - ); - } - } - } - } - - // + // Check if there is a Signal or Not ... bool hasSignal = cHasSignal || sHasSignal || mHasSignal || lHasSignal || hHasSignal; if (hasSignal) { - Print("Signal Recieved ..."); + // + // Handle Creating a new Signal Info ... + XSignal signal; + X121SetupConditions otherConditions[]; + if (hHasSignal) + { + // + signal = hSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + } + else if (lHasSignal) + { + // + signal = lSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + } + else if (mHasSignal) + { + // + signal = mSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + } + else if (sHasSignal) + { + // + signal = sSignal; + + // + AddRef( + cConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + else if (cHasSignal) + { + // + signal = cSignal; + + // + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + } + + // + int pushers = cPusher + sPusher + mPusher + lPusher + hPusher; + + // + bool isLong = IsLong(signal.type); + + // + // Collecting Bullish/Bearish Signs ... + if (isLong) + { + mBullishSigns += pushers; + } + else + { + mBearishSigns += pushers; + } + + // + // Validate Signal ... + bool isValid = + // + // Handle Pusher Validations ... + (mReuiredSignalVerifications <= 0 + ? true + : pushers >= mReuiredSignalVerifications) + // + && + // + // Handle Other Conditions Validations ... + (!mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions)) + // + ; + + // + if (!isValid) + { + continue; + } + + // + // Add Signal to Execution Result ... + AddRef( + signal, + signals // + ); + + // + // Add new Signal Info ... + mTradeInfoHandler.Add( + signal, + pushers, + mVolumeOSC, + mBullishSigns, + mBearishSigns, + mBullishScore, + mBearishScore, + cConditions, + sConditions, + mConditions, + lConditions, + hConditions // + ); } } @@ -1881,7 +2283,7 @@ public: { // // Select Signal Opposit Positions ... - ENUM_X_POSITION_TYPE iOpposit = GetOppositXPositionType(iSignal.type); + ENUM_X_POSITION_TYPE iOpposit = GetOppositPositionType(iSignal.type); // XPosition iPositions[]; @@ -1963,36 +2365,61 @@ public: } // - // Used for Signal Info States ... - void OnDealsChangedHandler(int count) override + // Signal Info ... + + // + void OnSignalExecuted(const XSignal &signal) override { // - if (UseSignalCollector()) - { - // - XDeal deal; - bool hasDeal = mTrader.GetLastDeal(deal); - if (hasDeal) - { - // - // Update Signal Info State ... - UpdateSignalState(deal); - } - } + // Signal Info Manager ... + XSignal tSignal = signal; + mTradeInfoHandler.Update(tSignal); + } + + // + void OnSignalExecutionFailed( + const XSignal &signal, + const ENUM_X_SIGNAL_EXECUTION_RESULT reason // + ) override + { + // + // Signal Info Manager ... + XSignal tSignal = signal; + mTradeInfoHandler.Remove(tSignal); } // void OnPositionClosed( - const ulong ticket, const XPosition &position, const string comment // ) override { // - if (UseSignalCollector()) - { - UpdateSignalState(ticket, position, comment); - } + // When a Position Closed Manually ... + // Signal Info Manager ... + XPosition tPosition = position; + tPosition.comment = comment; + mTradeInfoHandler.Update(tPosition); + } + + // + void OnStopLossTriggered(const XDeal &deal) override + { + // + // When a Position's Stop Loss Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeInfoHandler.Update(tDeal); + } + + // + void OnTakeProfitTriggered(const XDeal &deal) override + { + // + // When a Position's Take Profit Triggered ... + // Signal Info Manager ... + XDeal tDeal = deal; + mTradeInfoHandler.Update(tDeal); } // @@ -2056,279 +2483,11 @@ private: bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames // - bool mUseSupport; // Use Support Signals - bool mUseGrid; // Use Grid Signals - double mGridDistance; // Grid Distance - double mGridVolumeMultiplier; // Grid Volume Multiplier + bool mUseSupport; // Use Support Signals // - XSignalInfo mSignalInfos[]; - XSignalInfoCollector *mSignalCollector; - bool mUseSignalCollector; // Enable or Disable Signal Collector - - // - int CountSignalInfos() - { - return ArraySize(mSignalInfos); - } - - // - int FindSignalInfoIndex( - ulong positionTicket // - ) - { - // - int result = -1; - - // - int count = CountSignalInfos(); - if (!IsValidSize(count)) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XSignalInfo iInfo = mSignalInfos[i]; - - // - bool isOwn = iInfo.IsOwn( - positionTicket // - ); - if (isOwn) - { - // - result = i; - break; - } - } - - // - return result; - } - - // - int FindSignalInfoIndex( - string symbol, - string provider, - ENUM_TIMEFRAMES period // - ) - { - // - int result = -1; - - // - int count = CountSignalInfos(); - if (!IsValidSize(count)) - { - return result; - } - - // - for (int i = 0; i < count; i++) - { - // - XSignalInfo iInfo = mSignalInfos[i]; - - // - bool isOwn = iInfo.IsOwn( - symbol, - provider, - period // - ); - if (isOwn) - { - // - result = i; - break; - } - } - - // - return result; - } - - // - int FindSignalInfoIndex(XDeal &deal) - { - // - int result = -1; - - // - if (!deal.IsValid()) - { - return result; - } - - // - if (IsValid(deal.provider)) - { - // - ulong supTicket = ExtractSupportedTicket(deal.comment); - ulong supTicket1 = ExtractEQMSupportedTicket(deal.comment); - - // - if (supTicket <= 0 && supTicket1 <= 0) - { - // - result = FindSignalInfoIndex( - deal.symbol, - deal.provider, - deal.period // - ); - } - } - else - { - result = FindSignalInfoIndex(deal.positionId); - } - - // - return result; - } - - // - void AddNewSignal( - int pusher, - XSignal &signal, - double bullishScore, - double bearishScore, - X121SetupConditions &conditions // - ) - { - // - if (!UseSignalCollector()) - { - return; - } - - // - XSignalInfo info; - bool isFilled = info.Fill( - pusher, - signal, - bullishScore, - bearishScore, - conditions // - ); - - // - if (isFilled) - { - // - AddRef( - info, - mSignalInfos // - ); - } - } - - // - void UpdateSignalState(XDeal &deal) - { - // - if (!UseSignalCollector()) - { - return; - } - - // - if (!deal.IsValid()) - { - return; - } - - // - int infoIDX = FindSignalInfoIndex(deal); - if (!IsValidIndex(infoIDX)) - { - return; - } - - // - if (deal.entry == DEAL_ENTRY_IN) - { - // - mSignalInfos[infoIDX].time = deal.time; - mSignalInfos[infoIDX].ticket = deal.positionId; - mSignalInfos[infoIDX].commission = deal.commission; - mSignalInfos[infoIDX].signal.positionId = deal.positionId; - } - else if (deal.entry == DEAL_ENTRY_OUT) - { - // - mSignalInfos[infoIDX].swap = deal.swap; - mSignalInfos[infoIDX].endTime = deal.time; - mSignalInfos[infoIDX].profit = deal.profit; - - // - string message = - // - deal.reason == DEAL_REASON_TP - ? "TP" - : deal.reason == DEAL_REASON_SL - ? "SL" - : IsValid(deal.comment) - ? deal.comment - : "Force Close ..." - // - ; - mSignalInfos[infoIDX].message = message; - - // - // Now we can Save Signal Info and Remove it from mSignal Infos ... - bool isSaved = mSignalCollector.Save(mSignalInfos[infoIDX]); - if (isSaved) - { - // - ArrayRemove( - mSignalInfos, - infoIDX, - 1 // - ); - } - } - } - void UpdateSignalState( - const ulong ticket, - const XPosition &position, - const string message // - ) - { - // - if (!UseSignalCollector()) - { - return; - } - - // - int infoIDX = FindSignalInfoIndex(ticket); - if (!IsValidIndex(infoIDX)) - { - return; - } - - // - mSignalInfos[infoIDX].message = message; - mSignalInfos[infoIDX].swap = position.swap; - mSignalInfos[infoIDX].endTime = TimeCurrent(); - mSignalInfos[infoIDX].profit = position.profit; - - // - // Now we can Save Signal Info and Remove it from mSignal Infos ... - bool isSaved = mSignalCollector.Save(mSignalInfos[infoIDX]); - if (isSaved) - { - // - ArrayRemove( - mSignalInfos, - infoIDX, - 1 // - ); - } - } + bool mSaveResults; // Save Results in Specific Structure for Test Purposes ... + XTradeInfoHandler *mTradeInfoHandler; // Handle all Event which related to Signals and Positions // int mBullishSigns; @@ -2392,6 +2551,12 @@ private: // // EQM Functions ... + // + bool EnableGrid() + { + return mTradeInfoHandler.EnableGrid(); + } + // // Remove Untriggered EQM Orders ... void RemoveEQMOrders() @@ -2626,141 +2791,28 @@ private: void DoEQMGrid() { // - if (!UseGrid()) + if (!EnableGrid()) { return; } - // // - // int infosCount = CountSignalInfos(); - // if (!IsValidSize(infosCount)) - // { - // return; - // } + // + XSignal signals[]; + int signalsCount = mTradeInfoHandler + .RequestForGrid(signals); + if (!IsValidSize(signalsCount)) + { + return; + } - // // - // for (int i = 0; i < infosCount; i++) - // { - // // - // // Check Signal Executed or not ... - // if (mSignalInfos[i].ticket <= 0) - // { - // continue; - // } - - // // - // // Check Specific Position not a Support Position ... - // XPosition position; - // bool hasPosition = mTrader.GetPosition( - // mSignalInfos[i].ticket, - // position // - // ); - // if (!hasPosition) - // { - // continue; - // } - - // // - // // Check Position not a Support or EQM Support ... - // ulong supParent = 0; - // supParent = ExtractSupportedTicket(position.comment); - // if (supParent > 0) - // { - // continue; - // } - // supParent = ExtractEQMSupportedTicket(position.comment); - // if (supParent > 0) - // { - // continue; - // } - - // // - // // Check Grid Data ... - // if (mSignalInfos[i].gEntry <= 0 || mSignalInfos[i].gVolume <= 0) - // { - // continue; - // } - - // // - // // Retrieve Type of Position ... - // bool isLong = IsLong(mSignalInfos[i].signal.type); - - // // - // // Retrieve Cureent Entry Price based on Signal ... - // double cEntry = GetEntry( - // mSignalInfos[i].symbol, - // mSignalInfos[i].signal.type // - // ); - - // // - // // Check Price Distance passed or not ... - // bool isPriceDistancePassedForGrid = - // isLong - // ? cEntry <= mSignalInfos[i].gEntry - // : cEntry >= mSignalInfos[i].gEntry; - // if (!isPriceDistancePassedForGrid) - // { - // continue; - // } - - // // - // // Prepare Grid Signal ... - // XSignal gSignal; - // bool isPrepared = gSignal.Prepare( - // mSignalInfos[i].signal.symbol, - // mSignalInfos[i].signal.provider, - // mSignalInfos[i].signal.period, - // mSignalInfos[i].signal.type, - // X_ORDER_MODE_MARKET, - // mSignalInfos[i].gEntry, - // mSignalInfos[i].gVolume, - // 0, // SL ... - // 0 // TP ... - // ); - // if (!isPrepared) - // { - // continue; - // } - - // // - // // Add Support Tag ... - // string comment = GenerateSupportTag(mSignalInfos[i].ticket); - // gSignal.comment = comment; - - // // - // // Try to Execute Grid Signal ... - // ENUM_X_SIGNAL_EXECUTION_RESULT gState; - // int isExecuted = mTrader.ExecuteSignal( - // gSignal, - // gState, - // ORDER_TIME_GTC, - // NULL, - // false // Ignore Policies ... - // ); - // if (isExecuted) - // { - // // - // // Update Grid State of Signal Info ... - - // // - // double gDistancePrice = PointToPrice( - // mGridDistance, - // mSignalInfos[i].signal.symbol // - // ); - - // // - // mSignalInfos[i].gVolume *= mGridVolumeMultiplier; - // mSignalInfos[i].gEntry = isLong - // ? mSignalInfos[i].gEntry - gDistancePrice - // : mSignalInfos[i].gEntry + gDistancePrice; - - // // - // string message = XEQMSupportToken + " Execute Grid ..."; - - // // - // Alert(message); - // } - // } + // + // Execute Supports ... + ENUM_X_SIGNAL_EXECUTION_RESULT states[]; + int executed = ExecuteSignals( + signals, + states, + false // Ignore Policies ... + ); } // diff --git a/Classes/x-saherelm.xea.class.mq5 b/Classes/x-saherelm.xea.class.mq5 index 9d8e8614..e2d132eb 100644 --- a/Classes/x-saherelm.xea.class.mq5 +++ b/Classes/x-saherelm.xea.class.mq5 @@ -284,15 +284,7 @@ public: 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); + CalculateMaxDrawdown(); // // Draw ... @@ -341,11 +333,26 @@ public: HandleSignalsExecution(signals); } + // + // These are Some Event Handler ... + + // + // Calls whenever a signal Executed ... + virtual void OnSignalExecuted(const XSignal &signal) {} + + // + // Cals whenever a Signal Execution Failed ... + virtual void OnSignalExecutionFailed( + const XSignal &signal, + const ENUM_X_SIGNAL_EXECUTION_RESULT reason // + ) + { + } + // // Calls when a Position Modified ... virtual void OnPositionModified( - const ulong ticket, - const double profit, + const XPosition &position, const string comment // ) { @@ -354,7 +361,6 @@ public: // // Calls when a Position Closed ... virtual void OnPositionClosed( - const ulong ticket, const XPosition &position, const string comment // ) @@ -364,8 +370,7 @@ public: // // Calls when a Position Partially Closed ... virtual void OnPositionPartialyClosed( - const ulong ticket, - const double profit, + const XPosition &position, const string comment // ) { @@ -535,15 +540,6 @@ public: return 0; } - // - // When Some Errors happens in Executing Signals ... - virtual void ManageUnExecutedSignals( - ENUM_X_SIGNAL_EXECUTION_RESULT &states[], - XSignal &unExecutedSignals[] // - ) - { - } - // // Execute Provided Signals ... virtual void HandleSignalsExecution(XSignal &signals[]) @@ -566,66 +562,16 @@ public: // Notify Signal Event Handlers for Reciving New Signal ... for (int i = 0; i < managedSignalsCount; i++) { - // NotifyOnSignalEventHandlers(signals[i]); } // // Try to Execute Signals ... - XSignal notExecuteds[]; ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; - int executedSignalsCount = mTrader.ExecuteSpecifiedSignals( + int executedSignalsCount = ExecuteSignals( signals, - notExecuteds, // Not Executed Signals - reasons - // + reasons // ); - - // - string message = NULL; - if (executedSignalsCount == 0) - { - // - message = "(" + ToString(managedSignalsCount) + ") Signals Execution Failed ..."; - - // - for (int j = 0; j < ArraySize(reasons); j++) - { - // - string iReason = ToString(reasons[j]); - - // - message += "\n" + ToString(j) + ": " + iReason; - } - } - else if (executedSignalsCount < managedSignalsCount) - { - // - int diff = managedSignalsCount - executedSignalsCount; - - // - message = "Failed to Execute (" + ToString(diff) + ") Signals ..."; - } - else if (executedSignalsCount == managedSignalsCount) - { - message = "(" + ToString(executedSignalsCount) + ") Signals Executed Successfully ..."; - } - - // - if (ArraySize(notExecuteds) > 0) - { - // - ManageUnExecutedSignals( - reasons, - notExecuteds // - ); - } - - // - if (IsValid(message)) - { - mAlert.Alert(message); - } } // @@ -648,17 +594,139 @@ protected: double mDrawdownPercent; double mStaticBalanceForCalculateDrawdown; + // + // Calculate Max Drawdown and it's Percent ... + void CalculateMaxDrawdown() + { + // + int positionsCount = PositionsTotal(); + if (IsValidSize(positionsCount)) + { + double mEquity = mTrader.mAccount.GetEquity(); + if (mEquity > mMaxDrawdown) + { + mMaxDrawdown = mEquity; + } + + // + mDrawdownPercent = (mMaxDrawdown - mEquity) / (mStaticBalanceForCalculateDrawdown > 0 ? mStaticBalanceForCalculateDrawdown : mMaxDrawdown) * 100; + mDrawdownPercent = NormalizeDouble(mDrawdownPercent, 3); + } + else + { + // + mMaxDrawdown = 0.0; + mDrawdownPercent = 0.0; + } + } + + // + // // Tools ... // // Since we need to Calls Some Event Handlers on + // - Signal Execution; // - Modified; // - Closed; // - Partial Closed; // events ... // we have to implement thouse Methods here and use them ... + // + // Execute Stand alone Signal ... + bool ExecuteSignal( + XSignal &signal, // Signal + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result + bool checkPolicies = true, // Check Account Policies + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL // order expiration time + ) + { + // + bool result = false; + + // + result = mTrader.ExecuteSignal( + signal, + state, + lifetime, + expiration, + checkPolicies // + ); + if (result) + { + // + OnSignalExecuted(signal); + + // + string message = "Signal Executed (" + ToString(signal.positionId) + ") Successfully ..."; + + // + Alert(message); + } + else + { + // + OnSignalExecutionFailed(signal, state); + + // + string message = "Signal Execution Failed: " + ToString(state) + " ..."; + + // + Alert(message); + } + + // + return result; + } + + // + // Execute a Collection of Signals ... + int ExecuteSignals( + XSignal &signals[], // Collection of Signal for Execution + ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result + bool checkPolicies = true, // Check Account Policies + ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime + datetime expiration = NULL // order expiration time + ) + { + // + int result = 0; + + // + int signalsCount = ArraySize(signals); + if (!IsValidSize(signalsCount)) + { + return result; + } + + // + Clean(states); + ArrayResize(states, signalsCount, X_SIGNAL_EXECUTION_UNKNOWN); + + // + for (int i = 0; i < signalsCount; i++) + { + // + bool isExecuted = ExecuteSignal( + signals[i], + states[i], + checkPolicies, + lifetime, + expiration // + ); + if (isExecuted) + { + result++; + } + } + + // + return result; + } + // // Modify ... bool Modify( @@ -692,8 +760,7 @@ protected: { // OnPositionModified( - ticket, - position.profit, + position, comment // ); @@ -737,7 +804,6 @@ protected: { // OnPositionClosed( - ticket, position, comment // ); @@ -824,10 +890,15 @@ protected: { // OnPositionPartialyClosed( - ticket, - position.profit, + position, comment // ); + + // + string message = "Position " + ToString(ticket) + " Successfully Closed Parital ..."; + + // + Alert(message); } // @@ -1483,9 +1554,10 @@ protected: // ENUM_X_SIGNAL_EXECUTION_RESULT reason = NULL; - bool isExecuted = mTrader.ExecuteSignal( + bool isExecuted = ExecuteSignal( support, - reason); + reason // + ); // string comment = NULL; diff --git a/Documents/tmp.del b/Documents/tmp.del new file mode 100644 index 00000000..4f1786ca --- /dev/null +++ b/Documents/tmp.del @@ -0,0 +1,423 @@ + // + // Hind Signals ... + if (hSignal.IsValid()) + { + // + bool isLong = IsLong(hSignal.type); + if (isLong) + { + mBullishSigns += hPusher; + } + else + { + mBearishSigns += hPusher; + } + + // + if (hPusher >= mReuiredSignalVerifications) + { + // + X121SetupConditions otherConditions[]; + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + + // + // Check Final Validations ... + bool isValid = + // + ( + // + cHasSignal + // + || + // + sHasSignal + // + || + // + mHasSignal + // + || + // + lHasSignal + // + ) // + || + // + ( + // + !mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions) + // + ) + // + ; + + // + if (isValid) + { + // + AddRef( + hSignal, + signals // + ); + } + } + } + else + // + // Long Signals ... + if (lSignal.IsValid()) + { + // + bool isLong = IsLong(lSignal.type); + if (isLong) + { + mBullishSigns += lPusher; + } + else + { + mBearishSigns += lPusher; + } + + // + if (lPusher >= mReuiredSignalVerifications) + { + // + X121SetupConditions otherConditions[]; + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // Check Final Validations ... + bool isValid = + // + ( + // + cHasSignal + // + || + // + sHasSignal + // + || + // + mHasSignal + // + || + // + hHasSignal + // + ) + // + || + // + ( + // + !mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions) + // + ) + // + ; + + // + if (isValid) + { + // + AddRef( + lSignal, + signals // + ); + } + } + } + else + // + // Medium Signals ... + if (mSignal.IsValid()) + { + // + bool isLong = IsLong(mSignal.type); + if (isLong) + { + mBullishSigns += mPusher; + } + else + { + mBearishSigns += mPusher; + } + + // + if (mPusher >= mReuiredSignalVerifications) + { + // + X121SetupConditions otherConditions[]; + AddRef( + cConditions, + otherConditions // + ); + AddRef( + sConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // Check Final Validations ... + bool isValid = + // + ( + // + cHasSignal + // + || + // + sHasSignal + // + || + // + lHasSignal + // + || + // + hHasSignal + // + ) + // + || + // + ( + // + !mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions) + // + ) + // + ; + + // + if (isValid) + { + // + AddRef( + mSignal, + signals // + ); + } + } + } + else + // + // Short Signals ... + if (sSignal.IsValid()) + { + // + bool isLong = IsLong(sSignal.type); + if (isLong) + { + mBullishSigns += sPusher; + } + else + { + mBearishSigns += sPusher; + } + + // + if (sPusher >= mReuiredSignalVerifications) + { + // + X121SetupConditions otherConditions[]; + AddRef( + cConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // Check Final Validations ... + bool isValid = + // + ( + // + cHasSignal + // + || + // + mHasSignal + // + || + // + lHasSignal + // + || + // + hHasSignal + // + ) + // + || + // + ( + // + !mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions) + // + ) + // + ; + + // + if (isValid) + { + // + AddRef( + sSignal, + signals // + ); + } + } + } + else + // + // Current Signals ... + if (cSignal.IsValid()) + { + // + bool isLong = IsLong(cSignal.type); + if (isLong) + { + mBullishSigns += cPusher; + } + else + { + mBearishSigns += cPusher; + } + + // + if (cPusher >= mReuiredSignalVerifications) + { + // + X121SetupConditions otherConditions[]; + AddRef( + sConditions, + otherConditions // + ); + AddRef( + mConditions, + otherConditions // + ); + AddRef( + lConditions, + otherConditions // + ); + AddRef( + hConditions, + otherConditions // + ); + + // + // Check Final Validations ... + bool isValid = + // + ( + // + sHasSignal + // + || + // + mHasSignal + // + || + // + lHasSignal + // + || + // + hHasSignal + // + ) + // + || + // + ( + // + !mGetVerificationFromOtherTimeFrames + ? true + : isLong + ? signalGenerator.HasLongVerifications(otherConditions) + : signalGenerator.HasShortVerifications(otherConditions) + // + ) + // + ; + + // + if (isValid) + { + // + AddRef( + cSignal, + signals // + ); + } + } + } diff --git a/Experts/x-saherelm.x121.ea.mq5 b/Experts/x-saherelm.x121.ea.mq5 index a91f5177..811f83c2 100644 --- a/Experts/x-saherelm.x121.ea.mq5 +++ b/Experts/x-saherelm.x121.ea.mq5 @@ -42,27 +42,27 @@ input group "Signals"; input string x121EASymbols = "EURUSDb"; // Symbols input bool x121EAAllowLong = true; // Allow Long Trades input bool x121EAAllowShort = true; // Allow Short Trades -input int x121EAReuiredSignalVerifications = 3; // Required Verifications for Signals +input int x121EAReuiredSignalVerifications = 4; // Required Verifications for Signals input bool x121EAGetVerificationFromOtherTimeFrames = true; // Get Verifications from Other Time Frames // // Risk Management ... input group "Risk Management"; -input double x121EAVolume = 0.01; // Static Volume -input double x121EATPPoint = 60; // TP Point -input double x121EASLPoint = 300; // SL Point -input int x121EAMaxAllowedTrades = 1; // Max Allowed Positions -input bool x121EAIgnoreSL = true; // Ignore Calculated SL -input bool x121EAIgnoreTP = false; // Ignore Calculated TP -input bool x121EAUseSupport = false; // Use Support Signals -input bool x121EAUseGrid = true; // Use Grid Signals -input double x121EAGridDistance = 50; // Grid Distance -input double x121EAGridVolumeMultiplier = 2; // Grid Volume Multiplier -input double x121EAMinRequiredProfitPerTrade = 1; // Minimum Required Profit for Hedging -input double x121EAMinRequiredProfitPerVolumeFactor = 0.1; // Minimum Required Profit for Hedging Per Volume -input int x121EARestingAfterHedge = 0; // Resting Seconds After Hedge -input int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time -input bool x121EACloseOnOpposit = false; // Close all Positions on Opposit +input double x121EAVolume = 0.01; // Static Volume +input double x121EATPPoint = 60; // TP Point +input double x121EASLPoint = 300; // SL Point +input int x121EAMaxAllowedTrades = 1; // Max Allowed Positions +input bool x121EAIgnoreSL = true; // Ignore Calculated SL +input bool x121EAIgnoreTP = false; // Ignore Calculated TP +input bool x121EAUseSupport = false; // Use Support Signals +input bool x121EAAllowGrid = true; // Allow Grid Signals +input double x121EAGridDistance = 100; // Grid Distance +input double x121EAGridVolumeMultiplier = 2; // Grid Volume Multiplier +input double x121EAMinRequiredProfitPerTrade = 0.5; // Minimum Required Profit for Hedging +input double x121EAMinRequiredProfitPerVolumeFactor = 0.01; // Minimum Required Profit for Hedging Per Volume +input int x121EARestingAfterHedge = 300; // Resting Seconds After Hedge +input int x121EACloseOnSpecificTime = -1; // Close All Trades in Specific Time +input bool x121EACloseOnOpposit = false; // Close all Positions on Opposit // // Alert ... @@ -187,8 +187,11 @@ bool InitialEA() x121EA.GetVerificationFromOtherTimeFrames(x121EAGetVerificationFromOtherTimeFrames); // - x121EA.UseGrid(x121EAUseGrid); x121EA.UseSupport(x121EAUseSupport); + + // + // Grid System ... + x121EA.AllowGrid(x121EAAllowGrid); x121EA.GridDistance(x121EAGridDistance); x121EA.GridVolumeMultiplier(x121EAGridVolumeMultiplier); diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index e8a94f31..330fa7e7 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -154,6 +154,46 @@ enum ENUM_X_POSITION_TYPE X_POSITION_TYPE_SHORT = 3, }; +// +string ToString(ENUM_X_POSITION_TYPE value) +{ + // + string result = NULL; + + // + switch (value) + { + // + case X_POSITION_TYPE_ALL: + result = "All"; + break; + + // + case X_POSITION_TYPE_NONE: + result = "NONE"; + break; + + // + case X_POSITION_TYPE_SHORT: + result = "Short"; + break; + + // + case X_POSITION_TYPE_LONG: + result = "Long"; + break; + } + + // + return result; +} + +// +bool IsLong(ENUM_X_POSITION_TYPE value) +{ + return value == X_POSITION_TYPE_LONG; +} + // bool ToPositinType( ENUM_POSITION_TYPE &dest, @@ -182,7 +222,15 @@ bool ToPositinType( } // -ENUM_X_POSITION_TYPE GetOppositXPositionType(ENUM_POSITION_TYPE type) +ENUM_X_POSITION_TYPE ToPositionType(ENUM_POSITION_TYPE value) +{ + return IsLong(value) + ? X_POSITION_TYPE_LONG + : X_POSITION_TYPE_SHORT; +} + +// +ENUM_X_POSITION_TYPE GetOppositPositionType(ENUM_POSITION_TYPE type) { // ENUM_X_POSITION_TYPE result = X_POSITION_TYPE_NONE; @@ -4040,7 +4088,8 @@ ulong ExtractSupportedTicket(string value) int ExtractSupportPositions( XPosition &source[], XPosition &dest[] // Result ... -) { +) +{ // int result = 0; @@ -4049,18 +4098,21 @@ int ExtractSupportPositions( // int sourceCount = ArraySize(source); - if (!IsValidSize(sourceCount)) { + if (!IsValidSize(sourceCount)) + { return result; } // - for (int i = 0; i < sourceCount; i++) { + for (int i = 0; i < sourceCount; i++) + { // XPosition iSource = source[i]; // ulong iParentTicket = ExtractSupportedTicket(iSource.comment); - if (iParentTicket > 0) { + if (iParentTicket > 0) + { // AddRef( iSource,