diff --git a/Experts/x-saherelm.xcaea.ea.mq5 b/Experts/x-saherelm.xcaea.ea.mq5 index 63c7bd3b..43c6331d 100644 --- a/Experts/x-saherelm.xcaea.ea.mq5 +++ b/Experts/x-saherelm.xcaea.ea.mq5 @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////// // -// SaherElm IT Center XTest MQL5 Expert Advisor +// SaherElm IT Center XCAEA MQL5 Expert Advisor // ------------------------------------------------- // Name: XCAEA // Description: an Exper Advisor which used Panels @@ -173,7 +173,7 @@ void OnTick() eaConditions.Clean(); // - double r2r = 2; + double r2r = 4; string provider = "XCAEA"; ENUM_POSITION_TYPE type = POSITION_TYPE_BUY; ENUM_X_ORDER_MODES mode = X_ORDER_MODE_MARKET; @@ -366,6 +366,7 @@ void OnTick() // Handle On Trade Event ... void OnTrade() { + eaTrade.HandleOnTrade(); } // @@ -604,6 +605,7 @@ void InitRequirements() eaTradeManager = new XCXCAEATradeManager( eaTrade // ); + eaTradeManager.SaveTrades(true); eaTradeManager.SetAlertEnableAlerts(eaEnableAlerts); eaTradeManager.SetAlertPrefix(eaTag); eaTradeManager.SetAlertLogAlerts(eaLogAlerts); diff --git a/Libraries/x-saherelm.x-trade.lib.mq5 b/Libraries/x-saherelm.x-trade.lib.mq5 index 2a708c25..f33e7c88 100644 --- a/Libraries/x-saherelm.x-trade.lib.mq5 +++ b/Libraries/x-saherelm.x-trade.lib.mq5 @@ -1119,6 +1119,7 @@ struct XSignal // // Traget ... double targets[]; // Force Risk Free On Targets ... + int appliedTargetIDX; // Last Applied Target Index ... bool ignoreEAVolume; // Ignore EA Volume ... // @@ -1680,6 +1681,7 @@ struct XSignal // Clean(targets); + appliedTargetIDX = -1; ignoreEAVolume = false; // diff --git a/XCAEA/Classes/xcaea.x-data.collector.class.mq5 b/XCAEA/Classes/xcaea.x-data.collector.class.mq5 new file mode 100644 index 00000000..bbd1d2f7 --- /dev/null +++ b/XCAEA/Classes/xcaea.x-data.collector.class.mq5 @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------------- +// Name: XCXCAEADataCollector ... +// Description: Class for XCAEA Data Collector ... +// +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property library +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm Class for XCAEA Data Collector" +#property strict + +// +// Imports ... +#include "../../Classes/x-saherelm.base.class.mq5" + +// +// Definitions ... + +// +// Implementation ... +class XCXCAEADataCollector : public XCBase +{ + // + // Public ... + public: + // + // Constructors ... + XCXCAEADataCollector() + { + } + + // + // Deconstructor ... + ~XCXCAEADataCollector() + { + } + + // + // Properties ... + + // + string Path() + { + return mPath; + } + + // + void Path(string value) + { + // + // Normalizing Collector Path ... + if (IsValid(value)) + { + mPath = value; + } + else + { + mPath = "XCXCAEADataCollector"; + } + } + + // + // Tools ... + + // + string GetFilePath(string fileName) + { + // + string result = ""; + + // + result = + // + mPath + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + int GetFileHandlerForWrite(string filePath) + { + // + int result = INVALID_HANDLE; + + // + if (!IsValid(filePath)) + { + return result; + } + + // + result = FileOpen( + filePath, + FILE_READ | FILE_WRITE | FILE_TXT // + ); + + // + return result; + } + + /** + * Save Specified Content into Specified File Name ... + * + * @param fileName: string, file name ... + * @param content: string, content ... + * + * @return ( bool ) + */ + bool Save( + string fileName, + string content // + ) + { + // + bool result = false; + + // + result = IsValid(content); + if (!result) + { + return result; + } + + // + // + int mHandler = GetFileHandlerForWrite(fileName); + 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 Collector Path ... +}; diff --git a/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 b/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 index e8628b90..cda38977 100644 --- a/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 +++ b/XCAEA/Classes/xcaea.x-trade.manager.class.mq5 @@ -24,6 +24,7 @@ #include "../../Classes/x-saherelm.x-alert.class.mq5" #include "../../Classes/x-saherelm.x-poi.drawer.class.mq5" #include "../../Classes/x-saherelm.x-trade.class.mq5" +#include "../Classes/xcaea.x-data.collector.class.mq5" #include "../Libraries/xcaea.signaller.lib.mq5" // @@ -32,13 +33,25 @@ // enum ENUM_XCAEA_TRADE_FINALIZATION { - XCAEA_TRADE_FINAL_NONE, - XCAEA_TRADE_FINAL_TP, - XCAEA_TRADE_FINAL_SL, - XCAEA_TRADE_FINAL_CLOSE_IN_PROFIT, - XCAEA_TRADE_FINAL_CLOSE_IN_LOSE, + XCAEA_TRADE_FINAL_NONE, // None + XCAEA_TRADE_FINAL_TP, // TP + XCAEA_TRADE_FINAL_SL, // SL + XCAEA_TRADE_FINAL_CLOSE_IN_PROFIT, // Profit + XCAEA_TRADE_FINAL_CLOSE_IN_LOSE, // Lost }; +string ToString(ENUM_XCAEA_TRADE_FINALIZATION value) +{ + // + string result = NULL; + + // + result = EnumToString(value); + + // + return result; +} + // struct XCAEATrade { @@ -52,6 +65,11 @@ struct XCAEATrade XCAEAStrategyConditions conditions; ENUM_XCAEA_TRADE_FINALIZATION finalize; + // + datetime signaledAt; + datetime executedAt; + datetime finalizedAt; + // // Constructor ... XCAEATrade() @@ -76,6 +94,11 @@ struct XCAEATrade conditions.Clean(); finalize = XCAEA_TRADE_FINAL_NONE; + // + signaledAt = NULL; + executedAt = NULL; + finalizedAt = NULL; + // ZeroMemory(this); } @@ -132,6 +155,142 @@ struct XCAEATrade // return result; } + + /** + * Generate Summary Info ... + * + * @return ( string ) + */ + string Summary() + { + // + string result = NULL; + + // + result = + // + ToString("Swap: ", swap) + + ToString("Profit: ", profit) + + ToString("Commission: ", commission) + + ToString("Finalize: ", ToString(finalize)) + + ToString("PositionID: ", positionID) + + ToString("----------------") + "\n" + + ToString("Signaled At: ", ToFormatString(signaledAt)) + + ToString("Executed At: ", ToFormatString(executedAt)) + + ToString("Finalized At: ", ToFormatString(finalizedAt)) + // + ; + + // + return result; + } + + /** + * Get Data Collection File Name ... + * + * @return ( string ) + */ + string GetFileName() + { + // + string result = NULL; + + // + bool hasSignal = HasSignal(); + bool isExecuted = IsExecuted(); + bool isFinalized = IsFinalized(); + if (!hasSignal && !isExecuted && !isFinalized) + { + return result; + } + + // + result = + // + signal.symbol + "\\" + + ToString(signal.type) + "\\" + + (profit >= 0 ? "Profit" : "Loss") + "\\" + + ToString(positionID) + "_" + + ToString(signal.period) + "_" + + ToFormatString(signaledAt) + // + ; + + // + return result; + } + + /** + * Converts Model to String Representation ... + * + * @param onlySignals: Boolean, Specified Represent Only Signal or not ... + * + * @return ( string ) + */ + string ToString( + bool includeSummary = true, + bool includeSignal = true, + bool includeConditions = true // + ) + { + // + string result = NULL; + + // + // Generating Model Summary ... + string summary = Summary(); + + // + // Generating Signal Summary ... + string signalSummary = signal.ToString(); + + // + // Generating Conditions Summary ... + string conditionsSummary = conditions + .conditions + .GenerateSummary( + true, + true, + true, + false // Ignore False Conditions ... + ); + + // + if (includeSummary) + { + // + result += + ToString("----------------") + "\n" + + ToString("Summary: ") + "\n" + + ToString("----------------") + "\n" + + summary + "\n"; + } + + // + if (includeSignal) + { + // + result += + ToString("----------------") + "\n" + + ToString("Signal: ") + "\n" + + ToString("----------------") + "\n" + + signalSummary + "\n"; + } + + // + if (includeConditions) + { + // + result += + ToString("----------------") + "\n" + + ToString("Conditions: ") + "\n" + + ToString("----------------") + "\n" + + conditionsSummary + "\n"; + } + + // + return result; + } }; // @@ -146,24 +305,61 @@ class XCXCAEATradeManager : public XCBaseAlert XCTrade *trader; bool drawSignal; XCPOIDrawer *drawer; + XCXCAEADataCollector *collector; // // Constructors ... - XCXCAEATradeManager(XCTrade *&_trader) + XCXCAEATradeManager( + XCTrade *&_trader, + string _path = NULL // Base Path + ) { // trader = _trader; drawSignal = true; drawer = new XCPOIDrawer(); + + // + SaveTrades(false); + + // + // Normalizing Collector Path ... + if (!IsValid(_path)) + { + _path = "X121XCAEATradeManager" + "\\" + trader.mAccount.GetCompany(); + } + + // + collector = new XCXCAEADataCollector(); + collector.Path(_path); } // // De Constructors ... ~XCXCAEATradeManager() { + // + Clean(trades); + // ZeroMemory(trader); ZeroMemory(drawer); + ZeroMemory(collector); + } + + // + // Properties ... + + // + bool SaveTrades() + { + return mSaveTrades; + } + + // + void SaveTrades(bool value) + { + mSaveTrades = value; } // @@ -362,6 +558,17 @@ class XCXCAEATradeManager : public XCBaseAlert // double jTarget = targets[j]; + // + // Check Target is Applied Before or Not ... + has = + !IsValidIndex(trades[idx].signal.appliedTargetIDX) + ? true + : trades[idx].signal.appliedTargetIDX < j; + if (!has) + { + continue; + } + // // Check Traget Validation ... has = @@ -403,6 +610,9 @@ class XCXCAEATradeManager : public XCBaseAlert ); if (isModified) { + // + trades[idx].signal.appliedTargetIDX = j; + // string message = prefix + ToString(iPosition.type) + @@ -500,6 +710,8 @@ class XCXCAEATradeManager : public XCBaseAlert iTrade.conditions = conditions; iTrade.positionID = positionID; iTrade.commission = commission; + iTrade.signaledAt = signal.time; + iTrade.executedAt = TimeCurrent(); // AddRef( @@ -535,7 +747,7 @@ class XCXCAEATradeManager : public XCBaseAlert // Apply Required Data ... trades[idx].swap = deal.swap; trades[idx].profit = deal.profit; - trades[idx].commission = deal.commission; + trades[idx].finalizedAt = TimeCurrent(); trades[idx].finalize = XCAEA_TRADE_FINAL_TP; // @@ -543,6 +755,11 @@ class XCXCAEATradeManager : public XCBaseAlert managedTPCount++; // + // Save Trade ... + Save(trades[idx]); + + // + RemoveTrade(idx); } /** @@ -568,7 +785,7 @@ class XCXCAEATradeManager : public XCBaseAlert // Apply Required Data ... trades[idx].swap = deal.swap; trades[idx].profit = deal.profit; - trades[idx].commission = deal.commission; + trades[idx].finalizedAt = TimeCurrent(); trades[idx].finalize = XCAEA_TRADE_FINAL_SL; // @@ -576,6 +793,11 @@ class XCXCAEATradeManager : public XCBaseAlert managedSLCount++; // + // Save Trade ... + Save(trades[idx]); + + // + RemoveTrade(idx); } /** @@ -604,6 +826,7 @@ class XCXCAEATradeManager : public XCBaseAlert // Apply Required Data ... trades[idx].swap = position.swap; trades[idx].profit = position.profit; + trades[idx].finalizedAt = TimeCurrent(); trades[idx].commission = position.commission; trades[idx].finalize = isInProfit ? XCAEA_TRADE_FINAL_CLOSE_IN_PROFIT @@ -624,6 +847,11 @@ class XCXCAEATradeManager : public XCBaseAlert } // + // Save Trade ... + Save(trades[idx]); + + // + RemoveTrade(idx); } // @@ -752,18 +980,118 @@ class XCXCAEATradeManager : public XCBaseAlert return result; } + /** + * Remove a Trade From List ... + * + * @param index: int ... + */ + void RemoveTrade(int index) + { + // + bool has = + HasChild(trades) && + IsValidIndex(index) && + index < ArraySize(trades); + if (!has) + { + return; + } + + // + ArrayRemove( + trades, + index, + 1 // + ); + } + // // Protected ... protected: // // Tools ... + // + string GetFilePath(XCAEATrade &trade) + { + // + string fileName = trade.GetFileName(); + + // + return GetFilePath(fileName); + } + + // + string GetFilePath(string fileName) + { + // + string result = NULL; + + // + string mPath = collector.Path(); + + // + result = + // + mPath + "\\" + "Trades" + "\\" + fileName + ".x121.log" + // + ; + + // + return result; + } + + // + bool Save( + XCAEATrade &trade, + bool includeSummary = true, + bool includeSignal = true, + bool includeConditions = true // + ) + { + // + bool result = false; + + // + if (!mSaveTrades) + { + return result; + } + + // + string filePath = GetFilePath(trade); + result = IsValid(filePath); + if (!result) + { + return result; + } + + // + string content = trade.ToString( + includeSummary, + includeSignal, + includeConditions // + ); + + // + result = collector.Save( + filePath, + content // + ); + + // + return result; + } + // // Private ... private: // // Props ... + // + bool mSaveTrades; + // int slCount; int tpCount; diff --git a/XCAEA/Helpers/xcaea.helper.mq5 b/XCAEA/Helpers/xcaea.helper.mq5 index b5d2bf11..4aade460 100644 --- a/XCAEA/Helpers/xcaea.helper.mq5 +++ b/XCAEA/Helpers/xcaea.helper.mq5 @@ -2705,22 +2705,19 @@ struct XCAEAConditions ; // - result = + if (onlyCommons && !onlyConditions) { + result += commonStr = separator; + } else if (onlyConditions && !onlyCommons) { + result += conditionsStr + separator; + } else { // - "[" + GetTag() + "]" + separator + - (onlyConditions - ? "" - : commonStr) + - (!includeScores - ? "" - : scoresStr) + - " " + separator + - (onlyCommons - ? "" - : conditionsStr) + - "" - // - ; + result += + // + commonStr + separator + + conditionsStr + separator + // + ; + } // return result; diff --git a/XCAEA/Libraries/xcaea.signaller.lib.mq5 b/XCAEA/Libraries/xcaea.signaller.lib.mq5 index b340b7fa..60e93fe3 100644 --- a/XCAEA/Libraries/xcaea.signaller.lib.mq5 +++ b/XCAEA/Libraries/xcaea.signaller.lib.mq5 @@ -776,6 +776,13 @@ bool DetectXCAEAConditions( double pRSI = conditions.rsiBuffer[pIDX]; double p2RSI = conditions.rsiBuffer[p2IDX]; + // + // CCI ... + double zCCI = conditions.cciBuffer[zIDX]; + double cCCI = conditions.cciBuffer[cIDX]; + double pCCI = conditions.cciBuffer[pIDX]; + double p2CCI = conditions.cciBuffer[p2IDX]; + // // X3MA ... @@ -871,6 +878,14 @@ bool DetectXCAEAConditions( // // Create Conditions ... + // + bool isPRSIOB = + pRSI > conditions.rsiOBLevel; + + // + bool isPRSIOS = + pRSI < conditions.rsiOSLevel; + // bool isRSIBullish = cRSI > pRSI && @@ -881,6 +896,24 @@ bool DetectXCAEAConditions( cRSI < pRSI && !conditions.isRSIOS; + // + bool isPCCIOB = + pCCI > conditions.cciOBLevel; + + // + bool isPCCIOS = + pCCI < conditions.cciOSLevel; + + // + bool isCCIBullish = + cCCI > pCCI && + !conditions.isCCIOB; + + // + bool isCCIBearish = + cCCI < pCCI && + !conditions.isCCIOS; + // bool isLowOverMax = cBar.low > maxCTrendValue; bool isHighUnderMin = cBar.high < minCTrendValue; @@ -945,12 +978,15 @@ bool DetectXCAEAConditions( // // Parsing Pivots ... + XBoxZone rciPivot; double providedSL = 0; XBoxZone rejectedPivot; XBoxZone insidePivots[]; + XBoxZone rciContainers[]; int insidePivotsCount = 0; bool isRejectedOnMid = false; bool hasInsidePivots = false; + bool hasRCIContainers = false; bool hasPivots = HasChild(pivots); if (hasPivots) { @@ -1014,6 +1050,123 @@ bool DetectXCAEAConditions( true, true // ); + + // + // Select CCI/RSI Cross Object ... + count = ArraySize(pivots); + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = pivots[i]; + + // + ENUM_XCA_PIVOTS iType = GetPivotType(iPivot); + + // + // Checking Type is Passed ... + has = + // + iType == XCA_RSI_COOS || + iType == XCA_CCI_COOS || + iType == XCA_RSI_CUOB || + iType == XCA_CCI_CUOB + // + ; + + // + // Checking cBar is Pivots' Last Bar ... + has = + has && + cBar.time <= iPivot.to && + cBar.time > iPivot.from; + if (has) + { + // + rciPivot = iPivot; + + // + iPivot.Clean(); + + // + break; + } + + // + iPivot.Clean(); + } + + // + // Detect RCI Pivot Containers Pivots ... + count = ArraySize(pivots); + has = rciPivot.IsValid(); + if (has) + { + // + for (int i = 0; i < count; i++) + { + // + XBoxZone iPivot = pivots[i]; + + // + ENUM_XCA_PIVOTS iType = GetPivotType(iPivot); + + // + // Checking Type is Passed ... + has = + // + IsValid(iType) && + (iType == XCA_PEAKSWHRES || + iType == XCA_VALESWLSUP) + // + ; + + // + // Check Dir is Passed ... + has = + has && + rciPivot.dir == iPivot.dir; + + // + // Check RCI Pivot is Inside Pivot ... + has = + has && + // + ( + // + (rciPivot.lower >= iPivot.lower && + rciPivot.lower < iPivot.upper) + // + || + // + (rciPivot.upper <= iPivot.upper && + rciPivot.upper > iPivot.lower) + // + || + // + (rciPivot.upper > iPivot.upper && + rciPivot.lower < iPivot.lower) + // + ) + // + ; + + // + if (has) + { + // + AddRef( + iPivot, + rciContainers // + ); + } + + // + iPivot.Clean(); + } + + // + hasRCIContainers = HasChild(rciContainers); + } } // @@ -1025,7 +1178,7 @@ bool DetectXCAEAConditions( // bool isCond1Bullish = // - // false && // TODO: Remove this ... + false && // TODO: Remove this ... isRSIBullish && isVolumeOverAvg && isVolumeOverLast && @@ -1039,7 +1192,7 @@ bool DetectXCAEAConditions( // bool isCond1Bearish = // - // false && // TODO: Remove this ... + false && // TODO: Remove this ... isRSIBearish && isVolumeOverAvg && isVolumeOverLast && @@ -1074,44 +1227,40 @@ bool DetectXCAEAConditions( // bool isCond2Bullish = // - false && + // false && // + isPRSIOS && + isPCCIOS && + isRSIBullish && + isCCIBullish && + hasRCIContainers && + rciPivot.IsValid() && + rciPivot.IsBullish() && conditions.isUnderMal && conditions.isValeIsPivot && - // conditions.swingLowBuffer[cIDX] > conditions.valeBuffer[cIDX] && + (conditions.isRSICrossedOverOS || + conditions.isCCICrossedOverOS) && conditions.swingLowBuffer[cIDX] < conditions.fiboLevel3Buffer[cIDX] // - // conditions.isRSIOS - // - // isVolumeOverAvg && - // isVolumeBullish && - // isVolumeOverLast && - // c3MASlowState > 0 && - // c3MAMediumState > 0 && - // cBar.GetUp() > pSar && - // conditions.isFastOverSlow && - // conditions.isVidyaBullish && - // conditions.isFastOverMedium && - // isTrendRangeFinishedFromValid && - // conditions.isSwingHighOverLast && - // conditions.isSarSwitchedToBullish - // - // - // isX3MaBearishState && - // isCBarBullishRejected // && - // cBar.GetDown() > pVale && - // conditions.isValeUnderLast - // ; // bool isCond2Bearish = // - false // && - // isX3MaBullishState && - // isCBarBearishRejected // && - // cBar.GetUp() < pPeak && - // conditions.isPeakOverLast + // false && + // + isPRSIOB && + isPCCIOB && + isRSIBearish && + isCCIBearish && + hasRCIContainers && + rciPivot.IsValid() && + rciPivot.IsBearish() && + conditions.isOverMal && + conditions.isPeakIsPivot && + (conditions.isRSICrossedUnderOB || + conditions.isCCICrossedUnderOB) && + conditions.swingHighBuffer[cIDX] > conditions.fiboLevel1Buffer[cIDX] // ; @@ -1121,9 +1270,10 @@ bool DetectXCAEAConditions( if (isCond2) { // - Print("Cond2"); - isCond2Bullish = false; - isCond2Bearish = false; + pivotBox = rciPivot; + + // + // Selectiing Pivot Box based on RCI Containers ... } // @@ -1193,7 +1343,12 @@ bool DetectXCAEAConditions( // // Preparing SLs ... - if (isCond1) + + // + // For Cond 1 ... + // For Cond 2 ... + if (isCond1 || + isCond2) { // if (isCond1Bullish) @@ -1349,10 +1504,12 @@ bool DetectXCAEAConditions( p2Bar.Clean(); p3Bar.Clean(); p4Bar.Clean(); + rciPivot.Clean(); Clean(cTrendValues); Clean(pTrendValues); Clean(insidePivots); pConditions.Clean(); + Clean(rciContainers); rejectedPivot.Clean(); // diff --git a/XCAEA/Signals/xcaea.signaller.class.mq5 b/XCAEA/Signals/xcaea.signaller.class.mq5 index 77354854..42e63d66 100644 --- a/XCAEA/Signals/xcaea.signaller.class.mq5 +++ b/XCAEA/Signals/xcaea.signaller.class.mq5 @@ -852,8 +852,8 @@ class XCXCAEASignaller : XCBase // // Oscillators Views ... - inputs.showRSI = false; - inputs.showCCI = false; + inputs.showRSI = true; + inputs.showCCI = true; inputs.showMFI = false; inputs.showRVI = false; inputs.showADX = false; diff --git a/XCAEA/Tests/xcaea.cond2.script.mq5 b/XCAEA/Tests/xcaea.cond2.script.mq5 new file mode 100644 index 00000000..d2a626f0 --- /dev/null +++ b/XCAEA/Tests/xcaea.cond2.script.mq5 @@ -0,0 +1,647 @@ +/////////////////////////////////////////////////////// +// +// SaherElm IT Center XCond2 MQL5 Script +// ------------------------------------------------- +// Name: XCAEA +// Description: an Exper Advisor which used Panels +// +// Maintainer: +// ------------ +// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) +// +////////////////////////////////////////////////////// +// +// Global Properties ... +#property copyright "Copyright 2023, SaherElm IT Center" +#property link "https://saherelm.ir" +#property version "1.00" +#property description "SaherElm XCAEA Cond2 Script" +#property strict + +// +// Imports ... + +// +// Classes ... +#include "../../Classes/x-saherelm.x-poi.class.mq5" + +// +// Libraries ... +#include "../../Libraries/x-saherelm.common.lib.mq5" +#include "../../Libraries/x-saherelm.x-poi.lib.mq5" + +// +// Helpers ... +#include "../Helpers/xcaea.helper.mq5"; + +// +// Definitions ... + +// +// Holds Drawn Objects ... +CArrayObj mObjects; + +// +// Required Objects ... +int mLoopback = 10; +XCAEAInputs mInputs; +XBarTracker mBarTracker; +XCAEAConditions mConditions; +XCXCAEAHelper *helper = NULL; + +// +// Event Handlers ... + +/** + * Initialize Script ... + * + * @return ( int ) + */ +int OnInit() +{ + // + // Initialize Helper ... + bool isInited = InitHelper(); + if (!isInited) + { + return INIT_FAILED; + } + + // + return INIT_SUCCEEDED; +} + +/** + * De Initialize Script ... + * + * @param reason: Argument 1 + */ +void OnDeinit(const int reason) +{ + // + mInputs.Clean(); + mConditions.Clean(); + + // + ZeroMemory(helper); +} + +/** + * Handle Tick Event ... + */ +void OnTick() +{ + // + bool has = false; + + // + // Run on New Bar ... + bool isNewBar = mBarTracker.IsNewBar(); + if (!isNewBar) + { + return; + } + + // + // Setting Bar Index ... + int barIndex = 0; + + // + // Retrieve Conditions ... + has = helper.GetConditions( + mConditions, + barIndex, + mLoopback // + ); + if (!has) + { + return; + } + + // + // Handling Logic ... + HandleLogic(); +} + +// +// Custom Functions ... + +/** + * Initialize Helper ... + * + * @return ( bool ) + */ +bool InitHelper() +{ + // + bool result = false; + + // + mInputs.Default(); + + // + // Configure Inputs ... + + // + // Oscilators ... + mInputs.showAC = false; + mInputs.showAD = false; + mInputs.showADX = false; + mInputs.showATR = false; + mInputs.showCCI = false; + mInputs.showRSI = false; + mInputs.showMFI = false; + mInputs.showRVI = false; + mInputs.showMACD = false; + mInputs.showMomentum = false; + mInputs.showStochastic = false; + + // + // XCT ... + mInputs.ctInputs.showCandleTime = true; + + // + // XCC ... + mInputs.ccInputs.showCandles = true; + + // + // X3MA ... + mInputs.x3maInputs.showFast = false; + mInputs.x3maInputs.showSlow = false; + mInputs.x3maInputs.showMedium = false; + + // + // XOSC ... + // mInputs.oscsInputs; + + // + // XCA ... + mInputs.caInputs.showKI = false; + mInputs.caInputs.showSar = false; + mInputs.caInputs.showTKI = false; + mInputs.caInputs.showMAH = true; + mInputs.caInputs.showMAL = true; + mInputs.caInputs.showMAC = true; + mInputs.caInputs.showVidya = false; + mInputs.caInputs.showTrend = false; + mInputs.caInputs.showSwings = false; + mInputs.caInputs.showLongCycle = false; + mInputs.caInputs.showHindCycle = false; + mInputs.caInputs.showShortCycle = false; + mInputs.caInputs.showFiboLevel1 = true; + mInputs.caInputs.showFiboLevel2 = false; + mInputs.caInputs.showFiboLevel3 = true; + mInputs.caInputs.showMediumCycle = false; + mInputs.caInputs.showPeaksAndVales = false; + mInputs.caInputs.showPeakAndValeGolden = false; + mInputs.caInputs.showSupportAndResistance = true; + + // + // Initialize Helper ... + helper = new XCXCAEAHelper(); + result = helper.Init( + _Symbol, + _Period, + mInputs // + ); + if (!result) + { + return result; + } + + // + // Initialize Bar Tracker ... + result = mBarTracker.Init( + _Symbol, + _Period // + ); + if (!result) + { + return result; + } + + // + return result; +} + +/** + * Handle Logic of Script ... + */ +void HandleLogic() +{ + // + // Defining Requirements ... + + // + int zIDX = 0; + int cIDX = zIDX + 1; + int pIDX = cIDX + 1; + int p2IDX = pIDX + 1; + + // + bool has = false; + + // + // Reading Required Values ... + + // + // PEAK ... + double zPeak = mConditions.peakBuffer[zIDX]; + double cPeak = mConditions.peakBuffer[cIDX]; + double pPeak = mConditions.peakBuffer[pIDX]; + double p2Peak = mConditions.peakBuffer[p2IDX]; + + // + // VALE ... + double zVale = mConditions.valeBuffer[zIDX]; + double cVale = mConditions.valeBuffer[cIDX]; + double pVale = mConditions.valeBuffer[pIDX]; + double p2Vale = mConditions.valeBuffer[p2IDX]; + + // + // SAR ... + double zSar = mConditions.sarBuffer[zIDX]; + double cSar = mConditions.sarBuffer[cIDX]; + double pSar = mConditions.sarBuffer[pIDX]; + double p2Sar = mConditions.sarBuffer[p2IDX]; + + // + // KI ... + double zKI = mConditions.kiBuffer[zIDX]; + double cKI = mConditions.kiBuffer[cIDX]; + double pKI = mConditions.kiBuffer[pIDX]; + double p2KI = mConditions.kiBuffer[p2IDX]; + + // + // KI State ... + double zKIState = mConditions.kiStateBuffer[zIDX]; + double cKIState = mConditions.kiStateBuffer[cIDX]; + double pKIState = mConditions.kiStateBuffer[pIDX]; + double p2KIState = mConditions.kiStateBuffer[p2IDX]; + + // + // TKI ... + double zTKI = mConditions.tkiBuffer[zIDX]; + double cTKI = mConditions.tkiBuffer[cIDX]; + double pTKI = mConditions.tkiBuffer[pIDX]; + double p2TKI = mConditions.tkiBuffer[p2IDX]; + + // + // TKI State ... + double zTKIState = mConditions.tkiStateBuffer[zIDX]; + double cTKIState = mConditions.tkiStateBuffer[cIDX]; + double pTKIState = mConditions.tkiStateBuffer[pIDX]; + double p2TKIState = mConditions.tkiStateBuffer[p2IDX]; + + // + // MAH ... + double zMAH = mConditions.mahBuffer[zIDX]; + double cMAH = mConditions.mahBuffer[cIDX]; + double pMAH = mConditions.mahBuffer[pIDX]; + double p2MAH = mConditions.mahBuffer[p2IDX]; + + // + // MAL ... + double zMAL = mConditions.malBuffer[zIDX]; + double cMAL = mConditions.malBuffer[cIDX]; + double pMAL = mConditions.malBuffer[pIDX]; + double p2MAL = mConditions.malBuffer[p2IDX]; + + // + // MAC ... + double zMAC = mConditions.macBuffer[zIDX]; + double cMAC = mConditions.macBuffer[cIDX]; + double pMAC = mConditions.macBuffer[pIDX]; + double p2MAC = mConditions.macBuffer[p2IDX]; + + // + // TREND ... + double zTrend = mConditions.trendBuffer[zIDX]; + double cTrend = mConditions.trendBuffer[cIDX]; + double pTrend = mConditions.trendBuffer[pIDX]; + double p2Trend = mConditions.trendBuffer[p2IDX]; + + // + // TREND State ... + double zTrendState = mConditions.trendStateBuffer[zIDX]; + double cTrendState = mConditions.trendStateBuffer[cIDX]; + double pTrendState = mConditions.trendStateBuffer[pIDX]; + double p2TrendState = mConditions.trendStateBuffer[p2IDX]; + + // + // RESISTANCE ... + double zResistance = mConditions.resistanceBuffer[zIDX]; + double cResistance = mConditions.resistanceBuffer[cIDX]; + double pResistance = mConditions.resistanceBuffer[pIDX]; + double p2Resistance = mConditions.resistanceBuffer[p2IDX]; + + // + // SUPPORT ... + double zSupport = mConditions.supportBuffer[zIDX]; + double cSupport = mConditions.supportBuffer[cIDX]; + double pSupport = mConditions.supportBuffer[pIDX]; + double p2Support = mConditions.supportBuffer[p2IDX]; + + // + // VIDYA ... + double zVIDYA = mConditions.vidyaBuffer[zIDX]; + double cVIDYA = mConditions.vidyaBuffer[cIDX]; + double pVIDYA = mConditions.vidyaBuffer[pIDX]; + double p2VIDYA = mConditions.vidyaBuffer[p2IDX]; + + // + // VIDYA State ... + double zVIDYAState = mConditions.vidyaStateBuffer[zIDX]; + double cVIDYAState = mConditions.vidyaStateBuffer[cIDX]; + double pVIDYAState = mConditions.vidyaStateBuffer[pIDX]; + double p2VIDYAState = mConditions.vidyaStateBuffer[p2IDX]; + + // + // SWING Low ... + double zSwingLow = mConditions.swingLowBuffer[zIDX]; + double cSwingLow = mConditions.swingLowBuffer[cIDX]; + double pSwingLow = mConditions.swingLowBuffer[pIDX]; + double p2SwingLow = mConditions.swingLowBuffer[p2IDX]; + + // + // SWING High ... + double zSwingHigh = mConditions.swingHighBuffer[zIDX]; + double cSwingHigh = mConditions.swingHighBuffer[cIDX]; + double pSwingHigh = mConditions.swingHighBuffer[pIDX]; + double p2SwingHigh = mConditions.swingHighBuffer[p2IDX]; + + // + // FIBO Level 1 ... + double zFiboLevel1 = mConditions.fiboLevel1Buffer[zIDX]; + double cFiboLevel1 = mConditions.fiboLevel1Buffer[cIDX]; + double pFiboLevel1 = mConditions.fiboLevel1Buffer[pIDX]; + double p2FiboLevel1 = mConditions.fiboLevel1Buffer[p2IDX]; + + // + // FIBO Level 2 ... + double zFiboLevel2 = mConditions.fiboLevel2Buffer[zIDX]; + double cFiboLevel2 = mConditions.fiboLevel2Buffer[cIDX]; + double pFiboLevel2 = mConditions.fiboLevel2Buffer[pIDX]; + double p2FiboLevel2 = mConditions.fiboLevel2Buffer[p2IDX]; + + // + // FIBO Level 3 ... + double zFiboLevel3 = mConditions.fiboLevel3Buffer[zIDX]; + double cFiboLevel3 = mConditions.fiboLevel3Buffer[cIDX]; + double pFiboLevel3 = mConditions.fiboLevel3Buffer[pIDX]; + double p2FiboLevel3 = mConditions.fiboLevel3Buffer[p2IDX]; + + // + // X3MA ... + + // + // FAST ... + + // + double z3MAFast = mConditions.fastBuffer[zIDX]; + double c3MAFast = mConditions.fastBuffer[cIDX]; + double p3MAFast = mConditions.fastBuffer[pIDX]; + double p23MAFast = mConditions.fastBuffer[p2IDX]; + + // + double z3MAFastState = mConditions.fastStateBuffer[zIDX]; + double c3MAFastState = mConditions.fastStateBuffer[cIDX]; + double p3MAFastState = mConditions.fastStateBuffer[pIDX]; + double p23MAFastState = mConditions.fastStateBuffer[p2IDX]; + + // + // MEDIUM ... + + // + double z3MAMedium = mConditions.mediumBuffer[zIDX]; + double c3MAMedium = mConditions.mediumBuffer[cIDX]; + double p3MAMedium = mConditions.mediumBuffer[pIDX]; + double p23MAMedium = mConditions.mediumBuffer[p2IDX]; + + // + double z3MAMediumState = mConditions.mediumStateBuffer[zIDX]; + double c3MAMediumState = mConditions.mediumStateBuffer[cIDX]; + double p3MAMediumState = mConditions.mediumStateBuffer[pIDX]; + double p23MAMediumState = mConditions.mediumStateBuffer[p2IDX]; + + // + // SLOW ... + + // + double z3MASlow = mConditions.slowBuffer[zIDX]; + double c3MASlow = mConditions.slowBuffer[cIDX]; + double p3MASlow = mConditions.slowBuffer[pIDX]; + double p23MASlow = mConditions.slowBuffer[p2IDX]; + + // + double z3MASlowState = mConditions.slowStateBuffer[zIDX]; + double c3MASlowState = mConditions.slowStateBuffer[cIDX]; + double p3MASlowState = mConditions.slowStateBuffer[pIDX]; + double p23MASlowState = mConditions.slowStateBuffer[p2IDX]; + + // + // RSI ... + double zRSI = mConditions.rsiBuffer[zIDX]; + double cRSI = mConditions.rsiBuffer[cIDX]; + double pRSI = mConditions.rsiBuffer[pIDX]; + double p2RSI = mConditions.rsiBuffer[p2IDX]; + + // + // Reading Bars ... + + // + XOHCL zBar; + XOHCL cBar; + XOHCL pBar; + XOHCL p2Bar; + XOHCL p3Bar; + XOHCL p4Bar; + has = zBar.Init( + _Symbol, + _Period, + zIDX // + ); + has = + has && + zBar.GetPreviousBar(cBar); + has = + has && + cBar.GetPreviousBar(pBar); + has = + has && + pBar.GetPreviousBar(p2Bar); + has = + has && + p2Bar.GetPreviousBar(p3Bar); + has = + has && + p3Bar.GetPreviousBar(p4Bar); + if (!has) + { + // + zBar.Clean(); + cBar.Clean(); + pBar.Clean(); + p2Bar.Clean(); + p3Bar.Clean(); + p4Bar.Clean(); + + // + return; + } + + // + // Reading Bars Related Data ... + + // + // Score ... + + // + double bullishScore = 0; + double bearishScore = 0; + mConditions.GenerateScore( + bullishScore, + bearishScore // + ); + + // + bool isScoreBullish = + bullishScore > bearishScore; + + // + bool isScoreBearish = + bearishScore > bullishScore; + + // + // Generating Conditions Summary ... + string summary = + mConditions + .GenerateSummary(); + + // + // Calculating Range Volumes ... + + // + double bullishVolume = 0; + double bearishVolume = 0; + int volumeRangeLoopback = 5; + helper.barAnalyser.CalculateRangeVolume( + cBar, + bullishVolume, + bearishVolume, + volumeRangeLoopback // + ); + + // + double rangeVolume = bullishVolume = bearishVolume; + double rangeVolumeAvg = rangeVolume / volumeRangeLoopback; + + // + // Preparing Complex Conditions ... + + // + bool isRSIBullish = + cRSI > pRSI && + !mConditions.isRSIOB; + + // + bool isRSIBearish = + cRSI < pRSI && + !mConditions.isRSIOS; + + // + bool isVolumeBullish = bullishVolume > bearishVolume; + bool isVolumeBearish = bullishVolume < bearishVolume; + bool isVolumeOverLast = cBar.volume > pBar.volume; + bool isVolumeOverAvg = cBar.volume > rangeVolumeAvg; + + // + // Cond2 ... + + // + bool isCond2Bullish = + // + mConditions.isUnderMal && + mConditions.isValeIsPivot && + // mConditions.swingLowBuffer[cIDX] > mConditions.valeBuffer[cIDX] && + mConditions.swingLowBuffer[cIDX] < mConditions.fiboLevel3Buffer[cIDX] + // + ; + + // + bool isCond2Bearish = + // + false // && + // + ; + + // + bool isCond2 = isCond2Bullish || + isCond2Bearish; + if (isCond2) + { + // + // Print("Cond2"); + // isCond2Bullish = false; + // isCond2Bearish = false; + } + + // + // Check Results ... + + // + bool isBullish = isCond2Bullish; + bool isBearish = isCond2Bearish; + + // + bool result = isBullish || + isBearish; + if (result) + { + // + datetime time = zBar.time; + + // + ENUM_X_DIRECTION iDir = + isBullish + ? X_DIRECTION_BULLISH + : X_DIRECTION_BEARISH; + + // + // Handle Works ... + if (isCond2) + { + // + string name = "Cond2_" + ToString(iDir); + + // + color clr = isBullish + ? clrAqua + : clrMagenta; + + // + CChartObjectHLine *iObj; + iObj = new CChartObjectHLine(); + has = iObj.Create( + 0, + name, + 0, + time // + ); + if (has) + { + // + // Style Object ... + iObj.Width(1); + iObj.Color(clr); + iObj.Style(STYLE_DOT); + + // + // Store Object ... + mObjects.Add(iObj); + } + } + } +} + +// \ No newline at end of file