diff --git a/Classes/x-saherelm.x121.setup.cycle.class.mq5 b/Classes/x-saherelm.x121.setup.cycle.class.mq5 index 0e74e8e7..3ddeb4e9 100644 --- a/Classes/x-saherelm.x121.setup.cycle.class.mq5 +++ b/Classes/x-saherelm.x121.setup.cycle.class.mq5 @@ -134,7 +134,19 @@ struct X121SetupCycleInputs } // - bool GetConsitions( + bool CanProcessBar() + { + return cycle.barTracker.CanProcessBar(); + } + + // + void WaitsUntilNextBar() + { + cycle.barTracker.Waits(); + } + + // + bool GetConditions( X121SetupConditions &conditions, // int barIndex = 0, // int loopback = 5 // @@ -229,6 +241,16 @@ public: return result; } + // + result = cBarTracker.Init( + _inputs.symbol, + _hostPeriod // + ); + if (!result) + { + return result; + } + // // Short ... result = sCycle.Init( @@ -321,6 +343,176 @@ public: return result; } + // + string GetSymbol() + { + return cCycle.GetSymbol(); + } + + // + ENUM_TIMEFRAMES GetPeriod() + { + return cCycle.GetPeriod(); + } + + // + bool CanProcessBar( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN // + ) + { + // + bool result = false; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + result = sBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + result = mBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_LONG: + // + result = lBarTracker.CanProcessBar(); + break; + + // + case X_MARKET_CYCLE_HIND: + // + result = hBarTracker.CanProcessBar(); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + result = cBarTracker.CanProcessBar(); + break; + } + + // + return result; + } + + // + void WaitsUntilNextBar( + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN // + ) + { + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + sBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + mBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_LONG: + // + lBarTracker.Waits(); + break; + + // + case X_MARKET_CYCLE_HIND: + // + hBarTracker.Waits(); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + cBarTracker.Waits(); + break; + } + } + + // + bool GetConditions( + X121SetupConditions &conditions, // + ENUM_X_MARKET_CYCLES cycle = X_MARKET_CYCLE_UNKNOWN, // + int barIndex = 0, // + int loopback = 5 // + ) + { + // + bool result = false; + + // + switch (cycle) + { + // + case X_MARKET_CYCLE_SHORT: + // + result = sCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_MEDIUM: + // + result = mCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_LONG: + // + result = lCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + case X_MARKET_CYCLE_HIND: + // + result = hCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + + // + default: + case X_MARKET_CYCLE_UNKNOWN: + // + result = cCycle.GetConditions( + conditions, + barIndex, + loopback // + ); + break; + } + + // + return result; + } + // // Protected ... protected: @@ -333,10 +525,20 @@ private: // X121SetupInputs inputs; // Cycles Configurations + // + // Bar Trackers ... + XBarTracker cBarTracker; + XBarTracker sBarTracker; + XBarTracker mBarTracker; + XBarTracker lBarTracker; + XBarTracker hBarTracker; + // X121SetupCycleInputs cCycle; // Current (Host) Cycle X121SetupCycleInputs sCycle; // Short Cycle X121SetupCycleInputs mCycle; // Medium Cycle X121SetupCycleInputs lCycle; // Long Cycle X121SetupCycleInputs hCycle; // Hind Cycle -} \ No newline at end of file +}; + +// \ No newline at end of file diff --git a/Classes/x-saherelm.x121.setup.xea.mq5 b/Classes/x-saherelm.x121.setup.xea.mq5 index cd262c51..557f5155 100644 --- a/Classes/x-saherelm.x121.setup.xea.mq5 +++ b/Classes/x-saherelm.x121.setup.xea.mq5 @@ -25,11 +25,402 @@ // #include "../Classes/x-saherelm.xea.class.mq5" -#include "../Classes/x-saherelm.x121.setup.class.mq5" +#include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" // // Definitions ... +// +struct XSignalInfo +{ + // + 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) + + // + double profit; // Profit on Close + datetime endTime; // End Time + string message; // Close Reason + + // + double bullishScore; // Bullish Score On Signal Time + double bearishScore; // Bearish Score On Signal Time + + // + XSignal signal; // Generated Signal + X121SetupConditions conditions; // Generated Conditions + + // + // Constructor ... + void XSignalInfo() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + ticket = 0; + symbol = NULL; + period = NULL; + time = NULL; + profit = 0; + endTime = NULL; + message = NULL; + bullishScore = 0; + bearishScore = 0; + signal.Clean(); + conditions.Clean(); + } + + // + bool Fill( + int _pushers, + XSignal &_signal, + X121SetupConditions &_conditions // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_signal.symbol) && + IsValid(_signal.period) && + IsValid(_signal.provider) + // + ; + + // + if (!result) + { + return result; + } + + // + pushers = _pushers; + symbol = _signal.symbol; + period = _signal.period; + provider = _signal.provider; + + // + signal = _signal; + conditions = _conditions; + + // + return result; + } + + // + bool IsOwn( + ulong _ticket // + ) + { + // + bool result = false; + + // + result = _ticket == ticket; + + // + return result; + } + + // + bool IsOwn( + string _symbol, + string _provider, + ENUM_TIMEFRAMES _period // + ) + { + // + bool result = false; + + // + result = + // + IsValid(_symbol) && + IsValid(_provider) && + IsValid(_period) && + // + symbol == _symbol && + provider == _provider && + period == _period + // + ; + + // + return result; + } + + // + // Data Collector ... + + // + bool IsValid() + { + // + bool result = false; + + // + result = + // + ticket > 0 && + IsValid(time) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } + + // + string GetFileName() + { + // + string result = NULL; + + // + if (!IsValid()) + { + return result; + } + + // + result = + // + symbol + "_" + + provider + "_" + + ToString(ticket) + "_" + + ToString(period) + "_" + + ToString(time) + // + ; + + // + return result; + } + + // + string ToModelString() + { + // + string result = NULL; + + // + string conditionsStr = conditions + .GenerateSummary( + false, // Only Commons ... + true, // Only Conditions ... + false, // Include Score ... + false // Include False Conditions ...ّ + ); + + // + result = + // + ToString("Ticket", ticket) + + ToString("Symbol", symbol) + + ToString("Period", period) + + ToString("Time", time) + + ToString("BullishScore", bullishScore) + + ToString("BearishScore", bearishScore) + + ToString("Profit", profit) + + ToString("End Time", endTime) + + ToString("Message", message) + + "-------------" + "\n" + + ToString("Signal", signal.ToModelString()) + + ToString("Conditions", conditionsStr) + + // + "" + // + ; + + // + return result; + } + + // +}; + +// +class XSignalInfoCollector +{ + // + // Public ... +public: + // + // Props ... + + // + // Constructor(s) ... + void XSignalInfoCollector( + string _path = NULL // Base Path + ) + { + // + if (IsValid(_path)) + { + mPath = _path; + } + else + { + mPath = "XSignalInfo"; + } + } + + // + // Deconstructor ... + void ~XSignalInfoCollector() {} + + // + bool IsExists(XSignalInfo &item) + { + // + bool result = false; + + // + int mHandler = GetFileHandlerForRead(item); + result = mHandler != INVALID_HANDLE; + FileClose(mHandler); + + // + return result; + } + + // + bool Save(XSignalInfo &item) + { + // + bool result = false; + + // + // Check info is Valid ... + result = item.IsValid(); + if (!result) + { + return result; + } + + // + string content = item.ToModelString(); + result = IsValid(content); + if (!result) + { + return result; + } + + // + int mHandler = GetFileHandlerForWrite(item); + result = mHandler != INVALID_HANDLE; + if (!result) + { + return result; + } + + // + FileWrite(mHandler, content); + FileFlush(mHandler); + FileClose(mHandler); + + // + return result; + } + + // + // Protected ... +protected: + // + // Private ... +private: + // + // Props ... + + // + string mPath; // Base Path ... + + // + string GetFilePath(XSignalInfo &item) + { + // + string fileName = item.GetFileName(); + + // + return GetFilePath(fileName); + } + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + fileName + // + ; + + // + return result; + } + + // + int GetFileHandlerForRead(XSignalInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_TXT // + ); + + // + return result; + } + int GetFileHandlerForWrite(XSignalInfo &item) + { + // + int result = INVALID_HANDLE; + + // + string filePath = GetFilePath(item); + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } +}; + // // Class ... class XSCX121SetupEA : public XSCBaseEA @@ -66,6 +457,8 @@ public: ) { // + Clean(mSignalInfos); + mSignalCollector = new XSignalInfoCollector(); } // @@ -74,6 +467,62 @@ public: { } + // + bool AddSetup(XSCX121SetupCycles *setup) + { + // + bool result = false; + + // + result = setup != NULL; + if (!result) + { + return result; + } + + // + Add( + setup, + mSetups // + ); + + // + return result; + } + + // + // Getter(s) / Setter(s) ... + + // + bool AllowLong() + { + return mAllowLong; + } + + // + void AllowLong(bool value) + { + mAllowLong = value; + } + + // + bool AllowShort() + { + return mAllowShort; + } + + // + void AllowShort(bool value) + { + mAllowShort = value; + } + + // + bool IsEnable() + { + return mAllowLong || mAllowShort; + } + // // Overrides ... @@ -116,8 +565,438 @@ public: // Clean(signals); + // + if (!IsEnable()) + { + return result; + } + // // IMPLEMENT ... + int count = CountSetups(); + result = IsValidSize(count); + if (!result) + { + return result; + } + + // + string separator = "\n"; + + // + X121SetupConditions cConditions; + X121SetupConditions sConditions; + X121SetupConditions mConditions; + X121SetupConditions lConditions; + X121SetupConditions hConditions; + + // + XSignal cSignal; + XSignal sSignal; + XSignal mSignal; + XSignal lSignal; + XSignal hSignal; + + // + int cPusher = 0; + int sPusher = 0; + int mPusher = 0; + int lPusher = 0; + int hPusher = 0; + + // + X121SignalGenerator signalGenerator; + + // + for (int i = 0; i < count; i++) + { + // + // Cleanup Signals ... + cSignal.Clean(); + sSignal.Clean(); + mSignal.Clean(); + lSignal.Clean(); + hSignal.Clean(); + + // + // Current ... + bool canProcess = mSetups[i] + .CanProcessBar( + X_MARKET_CYCLE_UNKNOWN // + ); + if (canProcess) + { + // + bool iHasConditions = mSetups[i].GetConditions( + cConditions, + X_MARKET_CYCLE_UNKNOWN, // Current Market ... + 0, // Bar Index ... + 5 // Loop Back ... + ); + + // + if (!iHasConditions) + { + continue; + } + + // + mBullishScore = 0; + mBearishScore = 0; + + // + // Retrieve Scores ... + double bullishScore = 0; + double bearishScore = 0; + cConditions.GenerateScore( + bullishScore, + bearishScore // + ); + mBullishScore += bullishScore; + mBearishScore += bearishScore; + + // + // Parse Conditions for Signal ... + bool hasSignal = signalGenerator.HasSignal( + cConditions, + cSignal, + cPusher, + mAllowLong, + mAllowShort // + ); + + // + if (hasSignal) + { + // + mSetups[i].WaitsUntilNextBar( + X_MARKET_CYCLE_UNKNOWN // + ); + } + } + + // + // Short ... + canProcess = mSetups[i] + .CanProcessBar( + X_MARKET_CYCLE_SHORT // + ); + if (canProcess) + { + // + bool iHasConditions = mSetups[i].GetConditions( + sConditions, + X_MARKET_CYCLE_SHORT, // Current Market ... + 0, // Bar Index ... + 5 // Loop Back ... + ); + + // + if (!iHasConditions) + { + continue; + } + + // + // Retrieve Scores ... + double bullishScore = 0; + double bearishScore = 0; + sConditions.GenerateScore( + bullishScore, + bearishScore // + ); + mBullishScore += bullishScore; + mBearishScore += bearishScore; + + // + // Parse Conditions for Signal ... + bool hasSignal = signalGenerator.HasSignal( + sConditions, + sSignal, + sPusher, + mAllowLong, + mAllowShort // + ); + + // + if (hasSignal) + { + // + mSetups[i].WaitsUntilNextBar( + X_MARKET_CYCLE_SHORT // + ); + } + } + + // + // Medium ... + canProcess = mSetups[i] + .CanProcessBar( + X_MARKET_CYCLE_MEDIUM // + ); + if (canProcess) + { + // + bool iHasConditions = mSetups[i].GetConditions( + mConditions, + X_MARKET_CYCLE_MEDIUM, // Current Market ... + 0, // Bar Index ... + 5 // Loop Back ... + ); + + // + if (!iHasConditions) + { + continue; + } + + // + // Retrieve Scores ... + double bullishScore = 0; + double bearishScore = 0; + mConditions.GenerateScore( + bullishScore, + bearishScore // + ); + mBullishScore += bullishScore; + mBearishScore += bearishScore; + + // + // Parse Conditions for Signal ... + bool hasSignal = signalGenerator.HasSignal( + mConditions, + mSignal, + mPusher, + mAllowLong, + mAllowShort // + ); + + // + if (hasSignal) + { + // + mSetups[i].WaitsUntilNextBar( + X_MARKET_CYCLE_MEDIUM // + ); + } + } + + // + // Long ... + canProcess = mSetups[i] + .CanProcessBar( + X_MARKET_CYCLE_LONG // + ); + if (canProcess) + { + // + bool iHasConditions = mSetups[i].GetConditions( + lConditions, + X_MARKET_CYCLE_LONG, // Current Market ... + 0, // Bar Index ... + 5 // Loop Back ... + ); + + // + if (!iHasConditions) + { + continue; + } + + // + // Retrieve Scores ... + double bullishScore = 0; + double bearishScore = 0; + lConditions.GenerateScore( + bullishScore, + bearishScore // + ); + mBullishScore += bullishScore; + mBearishScore += bearishScore; + + // + // Parse Conditions for Signal ... + bool hasSignal = signalGenerator.HasSignal( + lConditions, + lSignal, + lPusher, + mAllowLong, + mAllowShort // + ); + + // + if (hasSignal) + { + // + mSetups[i].WaitsUntilNextBar( + X_MARKET_CYCLE_LONG // + ); + } + } + + // + // Hind ... + canProcess = mSetups[i] + .CanProcessBar( + X_MARKET_CYCLE_HIND // + ); + if (canProcess) + { + // + bool iHasConditions = mSetups[i].GetConditions( + hConditions, + X_MARKET_CYCLE_HIND, // Current Market ... + 0, // Bar Index ... + 5 // Loop Back ... + ); + + // + if (!iHasConditions) + { + continue; + } + + // + // Retrieve Scores ... + double bullishScore = 0; + double bearishScore = 0; + hConditions.GenerateScore( + bullishScore, + bearishScore // + ); + mBullishScore += bullishScore; + mBearishScore += bearishScore; + + // + // Parse Conditions for Signal ... + bool hasSignal = signalGenerator.HasSignal( + hConditions, + hSignal, + hPusher, + mAllowLong, + mAllowShort // + ); + + // + if (hasSignal) + { + // + mSetups[i].WaitsUntilNextBar( + X_MARKET_CYCLE_HIND // + ); + } + } + } + + // + // Parse Signals and Add them for Executing ... + // Here we can Save Signal and it's Conditions to + // Specified Collector then Update them on SL and TP ... + + // + // Current Signals ... + if (cPusher > 0 && cSignal.IsValid()) + { + // + AddRef( + cSignal, + signals // + ); + + // + AddNewSignal( + cPusher, + cSignal, + cConditions // + ); + } + + // + // Short Signals ... + if (sPusher > 0 && sSignal.IsValid()) + { + // + AddRef( + sSignal, + signals // + ); + + // + AddNewSignal( + sPusher, + sSignal, + sConditions // + ); + } + + // + // Medium Signals ... + if (mPusher > 0 && mSignal.IsValid()) + { + // + AddRef( + mSignal, + signals // + ); + + // + AddNewSignal( + mPusher, + mSignal, + mConditions // + ); + } + + // + // Long Signals ... + if (lPusher > 0 && lSignal.IsValid()) + { + // + AddRef( + lSignal, + signals // + ); + + // + AddNewSignal( + lPusher, + lSignal, + lConditions // + ); + } + + // + // Hind Signals ... + if (hPusher > 0 && hSignal.IsValid()) + { + // + AddRef( + hSignal, + signals // + ); + + // + AddNewSignal( + hPusher, + hSignal, + hConditions // + ); + } + + // + // Create Score Summary for Commenting on Chart ... + string scoreSummary = + // + "Scores:" + separator + + "----------" + separator + + "Bullish: " + ToString(mBullishScore) + separator + + "Bearish: " + ToString(mBearishScore) + separator + + "" + // + ; + + // + Comment(scoreSummary); // result = ArraySize(signals); @@ -200,6 +1079,21 @@ public: return result; } + // + // Tools For Signal Info Collect ... + + // + void OnDealsChangedHandler(int count) + { + // + XDeal deal; + bool hasDeal = mTrader.GetLastDeal(deal); + if (hasDeal) + { + UpdateSignalState(deal); + } + } + // // Protected ... protected: @@ -215,6 +1109,242 @@ protected: // // Private ... private: + // + // Props ... + + // + bool mAllowLong; // Allow Long + bool mAllowShort; // Allow Short + + // + // TODO: + // Add Volume and TP SL Points as Properties here ... + + // + XSignalInfo mSignalInfos[]; + XSignalInfoCollector *mSignalCollector; + + // + 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)) + { + result = FindSignalInfoIndex( + deal.symbol, + deal.provider, + deal.period // + ); + } + else + { + result = FindSignalInfoIndex(deal.positionId); + } + + // + return result; + } + + // + void AddNewSignal( + int pusher, + XSignal &signal, + X121SetupConditions &conditions // + ) + { + // + XSignalInfo info; + bool isFilled = info.Fill( + pusher, + signal, + conditions // + ); + + // + if (isFilled) + { + // + AddRef( + info, + mSignalInfos // + ); + } + } + + // + void UpdateSignalState(XDeal &deal) + { + // + 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; + Print("Open Position: " + ToString(deal.positionId)); + } + else if (deal.entry == DEAL_ENTRY_OUT) + { + Print("Close Position: " + ToString(deal.positionId)); + } + } + + // + double mBullishScore; + double mBearishScore; + + // + XSCX121SetupCycles *mSetups[]; // Number of Setups + + // + // Tools ... + int CountSetups() + { + return ArraySize(mSetups); + } + + // + int FindSetupIndex( + string symbol, + ENUM_TIMEFRAMES period // + ) + { + // + int result = -1; + + // + int count = CountSetups(); + if (!IsValidSize(count)) + { + return result; + } + + // + for (int i = 0; i < count; i++) + { + // + XSCX121SetupCycles *iSetup = mSetups[i]; + + // + X121SetupInputs iInputs = iSetup.GetInputs(); + + // + if (iInputs.symbol == symbol && iInputs.period == period) + { + // + result = i; + break; + } + } + + // + return result; + } }; // diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index b17b40b0..372532bc 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -2719,6 +2719,34 @@ public: .ByIndex(index); } + // + bool GetLastDeal( + XDeal &result // Hold's Result + ) + { + // + bool mResult = false; + + // + mResult = HistorySelect(0, TimeCurrent()); + if (!mResult) + { + return mResult; + } + + // + int lastDealIndex = HistoryDealsTotal() - 1; + + // + mResult = GetDeal( + lastDealIndex, + result // + ); + + // + return mResult; + } + // // Retrieve Specified Deal's History ... int GetDealsHistory( diff --git a/Experts/x-test-xxx.mq5 b/Experts/x-test-xxx.mq5 index 15251065..19f0df26 100644 --- a/Experts/x-test-xxx.mq5 +++ b/Experts/x-test-xxx.mq5 @@ -90,109 +90,14 @@ void OnDeinit(const int reason) // // De Initialize XSampleEA Providers ... - - // - delete mSetup; - - // - delete mAlert; - delete mTrader; + delete mEA; } // // On Tick Handler ... void OnTick() { - // - if (!xBarTracker.CanProcessBar()) - { - return; - } - - // - // Get Consitions and Validate it ... - X121SetupConditions conditions; - bool hasConditions = mSetup.GetConditions( - conditions // - ); - if (!hasConditions) - { - return; - } - - // - string separator = "\n"; - - // - // Retrieve Scores ... - double bullishScore = 0; - double bearishScore = 0; - conditions.GenerateScore( - bullishScore, - bearishScore // - ); - - // - // Create Score Summary for Commenting on Chart ... - string scoreSummary = - // - "Scores:" + separator + - "----------" + separator + - "Bullish: " + ToString(bullishScore) + separator + - "Bearish: " + ToString(bearishScore) + separator + - "" - // - ; - - // - Comment(scoreSummary); - - // - // Check Conditions has Signal or not ... - int pusher = 0; - XSignal signal; - bool hasSignal = mSignalGenerator - .HasSignal( - conditions, - signal, - pusher, - eaAllowLong, - eaAllowShort, - eaVolume, - 0, // SL Point ... - 30 // TP Point ... - ); - if (!hasSignal) - { - return; - } - - // - // Since we have a Signal in current Bar, ignore other ticks and - // waits for Next Bar ... - xBarTracker.Waits(); - - // - // Generate Condition Summary for Logging ... - string summary = conditions.GenerateSummary(false, true, false); - - // - Print(summary); - - // - ENUM_X_SIGNAL_EXECUTION_RESULT state; - int isExecuted = mTrader.ExecuteSignal( - signal, - state // - ); - if (isExecuted) - { - // - string message = "Signal Executed Successfully ..."; - - // - mAlert.Alert(message); - } + mEA.OnTick(); } // @@ -207,49 +112,71 @@ bool InitialEA() // TesterHideIndicators(true); - // - SetLogAlerts(true); - SetPrefix(ShortName); - SetEnableAlerts(true); - SetPushAlerts(false); - SetMailAlerts(false); - SetTerminalAlerts(false); + // + result = IsValid(eaSymbols); + if (!result) + { + return result; + } // - mTrader = new XSCTrade( + string symbols[]; + int symbolsCount = SplitContent( + symbols, + eaSymbols // + ); + result = symbolsCount > 0; + if (!result) + { + return result; + } + + // + mEA = new XSCX121SetupEA( eaSlippage, - eaMagicNumber, - 0, - 0, - 0 // + eaMagicNumber // ); // - result = xBarTracker.Init( - _Symbol, - _Period // - ); - if (!result) - { - return result; - } + // Allow Signals ... + mEA.AllowLong(true); + mEA.AllowShort(true); // - X121SetupInputs x121Inputs; - x121Inputs.symbol = _Symbol; - x121Inputs.period = _Period; - result = x121Inputs.Init(); - if (!result) + mEA.SetAlertPrefix(ShortName); + + // + X121SetupInputs setupInputsDefault; + setupInputsDefault.Default(); + + // + // Prepare Providers and Add them into mX121EA class ... + for (int i = 0; i < symbolsCount; i++) { - return result; - } - mSetup = new XSCX121Setup(); - result = mSetup.Init( - x121Inputs // - ); - if (!result) - { - return result; + // + // Requirements ... + string iSymbol = symbols[i]; + ENUM_TIMEFRAMES iHostPeriod = _Period; + + // + XSCX121SetupCycles *iSetupCycle; + iSetupCycle = new XSCX121SetupCycles(); + result = iSetupCycle.Init( + setupInputsDefault, + iSymbol, + iHostPeriod // + ); + if (!result) + { + break; + } + + // + result = mEA.AddSetup(iSetupCycle); + if (!result) + { + break; + } } // diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 index a1fb2f16..871e95c1 100644 --- a/Libraries/x-saherelm.common.lib.mq5 +++ b/Libraries/x-saherelm.common.lib.mq5 @@ -6973,6 +6973,28 @@ string ToString( return result; } +// +template +string ToString( + string prefix, // Title + T value, // Value + string lineSeparator = "\n", // Line Separator + string prefixSeparator = ":" // Title Separator +) +{ + // + string result = NULL; + + // + result = prefix + + prefixSeparator + " " + + ToString(value) + + lineSeparator; + + // + return result; +} + // string SetLabel( string mLabel, // Provided Label ...