diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 6b9eb651..19cdef7d 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -1,102 +1,21 @@ { - "todo": [ - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-17T19:53:39.860Z", - "description": { - "content": "- use it for supportings", - "mime": "text/markdown" - }, - "id": "82", - "references": [], - "title": "add trend line class and test it" - } - ], + "todo": [], "in-progress": [ { "assignedTo": { "name": "Hadi Khazaee Asl" }, - "creation_time": "2024-06-26T18:27:39.722Z", - "description": { - "content": "- [] Linear Regression Line 9 and 18;\n- [] Linear Regression Value;\n\nadd all those into 1 Indicator for Recieveing Verification for Signals;", + "creation_time": "2024-07-28T22:48:10.644Z", + "details": { + "content": "[] Add Recovery Options when try to Synchronize Positions Using Trade Handler ...\n[] Add Do not Trail Support or Recovery Positions in Trade Handler ...\n[] Add a TP and SL to Recovery Position ...\n[] Made Multi Asset ...\n[] Add Pressure Based Trailling ...\n[] Add Support for Pressures in Recovery ...\n[] Add OB / FVG and Other things Like XPV Signalling ...\n[] Create XCHCHE Insicator and it's Helper class ...\n", "mime": "text/markdown" }, - "id": "85", + "id": "86", "references": [], - "title": "Converts Linear Regression Line and Value indicator" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-17T19:53:56.463Z", - "id": "83", - "references": [], - "title": "run a multi currency test" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-17T19:54:13.659Z", - "id": "84", - "references": [], - "title": "try to implement machine learning and neural network" - } - ], - "testing": [ - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-16T23:57:54.021Z", - "id": "78", - "references": [], - "title": "add Max Allowe Signals per Symbol" - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-16T23:59:52.125Z", - "description": { - "content": "- Start Time;\n- End Time;\n- Close On Specific;\n- Close On Opposite;", - "mime": "text/markdown" - }, - "id": "80", - "references": [], - "title": "Complete Signalling COntrols ..." - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-17T00:01:04.987Z", - "description": { - "content": "- Max Number;\n- Voluem Multiplier;\n- Max Volume;\n- Support on Distance;", - "mime": "text/markdown" - }, - "id": "81", - "references": [], - "title": "Fix Allow Supports ..." - }, - { - "assignedTo": { - "name": "Hadi Khazaee Asl" - }, - "creation_time": "2024-06-16T23:58:59.163Z", - "description": { - "content": "Fix Open Signals When Support Signals only Open\nMax Allowed Trades Handler ...", - "mime": "text/markdown" - }, - "id": "79", - "references": [], - "title": "Fix Max Allowed Trade on Only SUpport Signals" + "title": "TODOs" } ], + "testing": [], "done": [ { "assignedTo": { @@ -136,6 +55,15 @@ "references": [], "title": "add handlers for TakeProfit or LoseProfit Events" }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-16T23:57:54.021Z", + "id": "78", + "references": [], + "title": "add Max Allowe Signals per Symbol" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -323,6 +251,19 @@ "references": [], "title": "add supports to plot trend arrow in tdma indicator" }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-17T19:53:39.860Z", + "description": { + "content": "- use it for supportings", + "mime": "text/markdown" + }, + "id": "82", + "references": [], + "title": "add trend line class and test it" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -442,6 +383,32 @@ "references": [], "title": "Complete Remained Short Signals" }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-16T23:59:52.125Z", + "description": { + "content": "- Start Time;\n- End Time;\n- Close On Specific;\n- Close On Opposite;", + "mime": "text/markdown" + }, + "id": "80", + "references": [], + "title": "Complete Signalling COntrols ..." + }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-26T18:27:39.722Z", + "description": { + "content": "- [] Linear Regression Line 9 and 18;\n- [] Linear Regression Value;\n\nadd all those into 1 Indicator for Recieveing Verification for Signals;", + "mime": "text/markdown" + }, + "id": "85", + "references": [], + "title": "Converts Linear Regression Line and Value indicator" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -702,6 +669,19 @@ "references": [], "title": "extends new section based indicators" }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-17T00:01:04.987Z", + "description": { + "content": "- Max Number;\n- Voluem Multiplier;\n- Max Volume;\n- Support on Distance;", + "mime": "text/markdown" + }, + "id": "81", + "references": [], + "title": "Fix Allow Supports ..." + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -712,6 +692,19 @@ "references": [], "title": "fix cc and ct indicator issues ..." }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-16T23:58:59.163Z", + "description": { + "content": "Fix Open Signals When Support Signals only Open\nMax Allowed Trades Handler ...", + "mime": "text/markdown" + }, + "id": "79", + "references": [], + "title": "Fix Max Allowed Trade on Only SUpport Signals" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -994,6 +987,15 @@ "references": [], "title": "resolve InvalidStop on Partial Closing" }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-17T19:53:56.463Z", + "id": "83", + "references": [], + "title": "run a multi currency test" + }, { "assignedTo": { "name": "Hadi Khazaee Asl" @@ -1052,6 +1054,15 @@ "content": "do a refactor on all brokers, higgh priority criterias ...", "mime": "text/markdown" } + }, + { + "assignedTo": { + "name": "Hadi Khazaee Asl" + }, + "creation_time": "2024-06-17T19:54:13.659Z", + "id": "84", + "references": [], + "title": "try to implement machine learning and neural network" } ] } \ No newline at end of file diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index e60fc584..5feb6696 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -4305,6 +4305,25 @@ public: mMaxAllowedRecover = value; } + // + double MaxAllowedRecoveryVolume() + { + return mMaxAllowedRecoveryVolume; + } + + // + void MaxAllowedRecoveryVolume(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedRecoveryVolume = value; + } + // double RecoveryVolumeMultiplier() { @@ -4324,6 +4343,18 @@ public: mRecoveryVolumeMultiplier = value; } + // + bool ForcePressuresInRecovery() + { + return mForcePressuresInRecovery; + } + + // + void ForcePressuresInRecovery(bool value) + { + mForcePressuresInRecovery = value; + } + // // Hedging ... @@ -4409,6 +4440,11 @@ public: return; } + // + // Check Signal Support or Recovery ... + bool isSupport = IsSupport(signal.comment); + bool isRecovery = ExtractRecoveredTicket(signal.comment) > 0; + // XTradeData item; bool isFilled = item.Fill(signal); @@ -4429,7 +4465,10 @@ public: if (mAllowTrailStops || forceTrail) { // - item.allowTrailStop = true; + if (!isSupport && !isRecovery) + { + item.allowTrailStop = true; + } // item.ignoreTPOnTrail = mIgnoreTPOnTrail; @@ -4447,7 +4486,10 @@ public: if (mAllowRecover || forceRecover) { // - item.allowRecover = true; + if (!isSupport && !isRecovery) + { + item.allowRecover = true; + } // item.recoveryTPPoint = mRecoveryTPPoint; @@ -4800,31 +4842,50 @@ public: ); // - double requiredProfitPoints = (mData[i].recoveryLevel + 1) * recoveryTPPoint; - - // - double rSwap = mData[i].swap; + // Summary Calculations ... double rVolume = volume; double rProfit = profit; + bool hasMaxVolume = false; + double rSwap = mData[i].swap; double rCommission = mData[i].commission; - for (int i = 0; i < recoveriesCount; i++) + for (int j = 0; j < recoveriesCount; j++) { // - rSwap += recoveries[i].swap; - rProfit += recoveries[i].profit; - rVolume += recoveries[i].volume; - rCommission += mTrader.GetPositionCommission(recoveries[i].ticket); + rSwap += recoveries[j].swap; + rProfit += recoveries[j].profit; + rVolume += recoveries[j].volume; + rCommission += mTrader.GetPositionCommission(recoveries[j].ticket); + + // + if (!hasMaxVolume && + mMaxAllowedRecoveryVolume > 0 && + recoveries[j].volume >= mMaxAllowedRecoveryVolume) + { + hasMaxVolume = true; + } // AddRef( - recoveries[i], + recoveries[j], mustClose // ); } - - // double profitSummary = rProfit + (-1 * rSwap) - MathAbs(rCommission); + + // + double requiredProfitPoints = recoveriesCount * recoveryTPPoint; + // if (mData[i].recoveryLevel >= 2) + // { + // // + // requiredProfitPoints /= mData[i].recoveryLevel; + // if (requiredProfitPoints < recoveryTPPoint) + // { + // requiredProfitPoints = recoveryTPPoint; + // } + // } + + // if (profitSummary > 0) { // @@ -4856,12 +4917,12 @@ public: break; } } - - // - Clean(mustClose); - Clean(positions); - Clean(recoveries); } + + // + Clean(mustClose); + Clean(positions); + Clean(recoveries); } } } @@ -4897,12 +4958,13 @@ public: tmpLSW, true // ); - bool isBullishSigns = + bool hasBullishSigns = // - isBullishTrend && - hasBullishPower && + // isBullishTrend && + cBar.IsBullish() && hasBullishPattern && - hasBullishPressure + (hasBullishPower && + hasBullishPressure) // ; @@ -4916,12 +4978,13 @@ public: tmpLSW, true // ); - bool isBearishSigns = + bool hasBearishSigns = // - isBearishTrend && - hasBearishPower && - hasBearishPattern && - hasBearishPressure + // isBearishTrend && + cBar.IsBearish() && + hasBearishPressure && + (hasBearishPower && + hasBearishPattern) // ; @@ -5103,7 +5166,35 @@ public: // Do Recovery ... // - // Profit Must be Negative ... + // Check Looking for Direction ... + ENUM_X_POSITION_TYPES recoveryLookingType = mData[i].recoveryLookingType; + if (recoveryLookingType == X_POSITION_TYPE_ALL || + recoveryLookingType == X_POSITION_TYPE_NONE) + { + continue; + } + + // + bool isDirectional = recoveryLookingType == mData[i].type; + + // + bool hasPressure = + !mForcePressuresInRecovery + ? true + : isDirectional + // + // Looking For Directional Pressure ... + ? isLong + ? hasBullishSigns + : hasBearishSigns + // + // Looking For InDirectional Pressure ... + : isLong + ? hasBearishSigns + : hasBullishSigns; + + // + // Check Required Properties Validation ... if ( recoveryTPPoint > 0 && recoverySLPoint > 0 && @@ -5112,78 +5203,45 @@ public: : mData[i].recoveryLevel < maxAllowedRecover)) { // - // Current Profit ... + // Calculate requirements ... double distanceInPoints = (MathAbs(profit) / volume); - double _volumeMultiplier = ((mData[i].recoveryLevel + 1) * recoveryVolumeMultiplier); - double _volume = volume * (_volumeMultiplier <= 0 ? 1 : _volumeMultiplier); + // double _volumeMultiplier = ((mData[i].recoveryLevel + 1) * recoveryVolumeMultiplier); + // double _volume = + // volume * (_volumeMultiplier <= 0 ? 1 : _volumeMultiplier); + double _volume = + mData[i].recoveryVolume <= 0 + ? volume * recoveryVolumeMultiplier + : mData[i].recoveryVolume; + if (mMaxAllowedRecoveryVolume > 0 && _volume > mMaxAllowedRecoveryVolume) + { + _volume = mMaxAllowedRecoveryVolume; + } + + // string _comment = GenerateRecoveryTag(ticket); // - if (profit < 0) + XSignal rSignal; + bool isPrepared = false; + + // + if (profit < 0 && + hasPressure && + !isDirectional && + distanceInPoints >= recoverySLPoint) { // - bool canRecover = - distanceInPoints >= recoverySLPoint && - (mData[i].recoveryLevel == 0 || - (mData[i].recoveryLevel >= 2 && - mData[i].recoveryLevel / 2 == 0)); - if (canRecover) - { - // - RemovePositionTPSL(iPosition); - - // - ENUM_POSITION_TYPE _type = - isLong - ? POSITION_TYPE_SELL - : POSITION_TYPE_BUY; - double _entry = GetEntry(symbol, _type); - - // - XSignal rSignal; - bool isPrepared = rSignal.Prepare( - symbol, - provider, - period, - _type, - X_ORDER_MODE_MARKET, - _entry, - _volume, - 0, - 0 // - ); - if (isPrepared) - { - // - rSignal.comment = _comment; - - // - bool isExecuted = ExecuteRecoverySignal(rSignal); - if (isExecuted) - { - mData[i].recoveryLevel++; - } - } - } - } - else if (profit >= 0 && - (mData[i].recoveryLevel == 1 || - (mData[i].recoveryLevel >= 2 && - mData[i].recoveryLevel / 2 == 1))) - { - // - RemovePositionTPSL(iPosition); + FixRecoveredPositionTPSL(iPosition); // ENUM_POSITION_TYPE _type = isLong - ? POSITION_TYPE_BUY - : POSITION_TYPE_SELL; + ? POSITION_TYPE_SELL + : POSITION_TYPE_BUY; double _entry = GetEntry(symbol, _type); // - XSignal rSignal; - bool isPrepared = rSignal.Prepare( + isPrepared = rSignal.Prepare( symbol, provider, period, @@ -5194,16 +5252,63 @@ public: 0, 0 // ); - if (isPrepared) + } + else if (profit >= 0 && + hasPressure && + isDirectional) + { + // + FixRecoveredPositionTPSL(iPosition); + + // + ENUM_POSITION_TYPE _type = + isLong + ? POSITION_TYPE_BUY + : POSITION_TYPE_SELL; + double _entry = GetEntry(symbol, _type); + + // + isPrepared = rSignal.Prepare( + symbol, + provider, + period, + _type, + X_ORDER_MODE_MARKET, + _entry, + _volume, + 0, + 0 // + ); + } + + // + if (isPrepared && rSignal.IsValid()) + { + // + // Attach Recovery Tag ... + rSignal.comment = _comment; + + // + // Execute Recovery Signal ... + bool isExecuted = ExecuteRecoverySignal(rSignal); + if (isExecuted) { // - rSignal.comment = _comment; + // Increase Recovery Level ... + mData[i].recoveryLevel++; + mData[i].recoveryVolume = _volume * recoveryVolumeMultiplier; // - bool isExecuted = ExecuteRecoverySignal(rSignal); - if (isExecuted) + // Try to Reverse Looking for Next Recovery + // Position Type ... + ENUM_POSITION_TYPE _type; + bool isConverted = ToPositionType( + _type, + recoveryLookingType // + ); + if (isConverted) { - mData[i].recoveryLevel++; + mData[i].recoveryLookingType = GetOppositPositionType(_type); } } } @@ -5265,7 +5370,9 @@ protected: int mMaxAllowedRecover; // Max Allowed Recovery double mRecoveryTPPoint; // Recovery TP in Points double mRecoverySLPoint; // Recovery SL in Points + bool mForcePressuresInRecovery; // Use Direction Pressures In Recovery double mRecoveryVolumeMultiplier; // Recovery Volume Multiplier + double mMaxAllowedRecoveryVolume; // Max Allowed Recovery Volume // // Hedging ... @@ -5533,7 +5640,7 @@ private: } // - bool RemovePositionTPSL(XPosition &osition) + bool FixRecoveredPositionTPSL(XPosition &osition) { // bool result = false; diff --git a/Documents/BKP/usefull.mq5 b/Documents/BKP/usefull.mq5 index 0d185993..69d60f3c 100644 --- a/Documents/BKP/usefull.mq5 +++ b/Documents/BKP/usefull.mq5 @@ -8018,3 +8018,125 @@ void HandleStrategiesOnTick() // sl = pvConditions.fib4s[cIndex]; // } // } + +/////////////////////////////////////////////////////////////////////////// + + + // + XSymbolParser symbolParser; + + // + bool useEURUSD = false; + bool useUSDCHF = false; + bool useUSDJPY = false; + bool useGBPUSD = false; + bool useXAUUSD = false; + + // + bool useXTest = false; + bool useXDTD = false; + bool useXCHKM = false; + + // + // EURUSD ... + string eurusdSymbol = "EURUSDb"; // symbolParser.GetEURUSDSymbol(); + if (useEURUSD && IsValid(eurusdSymbol)) + { + // + // MAGIC NUMBER ... + long magicNumber = eaMagicNumber + 1; + + // + // XDTD ... + if (useXDTD) + { + // + XSCXDTDStrategy *eurusdXTDTStrategy; + eurusdXTDTStrategy = new XSCXDTDStrategy( + eurusdSymbol, + PERIOD_M15, + eaVolume, + eaR2R, // R2R ... + eaSlippage, + magicNumber, + true, // Ignore Signal Execution + true, // Use TP SL Point + false, // Use Max + eaTPPoint, // TP + eaSLPoint, // SL + eaIgnoreTP, + false, // eaIgnoreSL, + eaAllowLong, + eaAllowShort, + eaMaxAllowedLongs, // Max Longs + eaMaxAllowedShorts // Max Shorts + ); + eurusdXTDTStrategy.SetAlertLogAlerts(true); + eurusdXTDTStrategy.SetAlertEnableAlerts(true); + eurusdXTDTStrategy.AddSignalEventHandler(OnSignalRecieved); + RegisterStrategy(eurusdXTDTStrategy); + } + + // + // XTest ... + if (useXTest) + { + // + XSCXTestStrategy *eurusdTestStrategy; + eurusdTestStrategy = new XSCXTestStrategy( + eurusdSymbol, + PERIOD_M15, + eaVolume, + eaR2R, // R2R ... + eaSlippage, + magicNumber, + true, // Ignore Signal Execution + true, // Use TP SL Point + false, // Use Max + eaTPPoint, // TP + eaSLPoint, // SL + eaIgnoreTP, + eaIgnoreSL, + eaAllowLong, + eaAllowShort, + eaMaxAllowedLongs, // Max Longs + eaMaxAllowedShorts // Max Shorts + ); + eurusdTestStrategy.SetAlertLogAlerts(true); + eurusdTestStrategy.SetAlertEnableAlerts(true); + eurusdTestStrategy.AddSignalEventHandler(OnSignalRecieved); + RegisterStrategy(eurusdTestStrategy); + } + + // + // XCHKM ... + if (useXCHKM) + { + // + XSCXCHKMStrategy *eurusdXCHKMStrategy; + eurusdXCHKMStrategy = new XSCXCHKMStrategy( + eurusdSymbol, + PERIOD_M5, + PERIOD_H1, // Analyzing Period + eaVolume, + eaR2R, // R2R ... + eaSlippage, + magicNumber, + true, // Ignore Signal Execution + false, // Use TP SL Point + false, // Use Max + eaTPPoint, // TP + eaSLPoint, // SL + eaIgnoreTP, + false, // eaIgnoreSL, + eaAllowLong, + eaAllowShort, + eaMaxAllowedLongs, // Max Longs + eaMaxAllowedShorts // Max Shorts + ); + eurusdXCHKMStrategy.SetAlertLogAlerts(true); + eurusdXCHKMStrategy.SetAlertEnableAlerts(true); + eurusdXCHKMStrategy.AddSignalEventHandler(OnSignalRecieved); + RegisterStrategy(eurusdXCHKMStrategy); + } + } diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index eb1975d9..5113220e 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -60,6 +60,10 @@ bool eaIgnoreSL = false; // Ignore SL // double eaR2R = 1.5; // Risk to Reward Ratio +// +bool eaMultiSymbol = true; // Use Multi Symbol +string eaSymbols = "EURUSDb,USDJPYb,USDCHFb,GBPUSDb,XAUUSDb,XAGUSDb"; + // // Variables ... @@ -281,161 +285,99 @@ bool InitialEA() // // Configure Recovery ... - eaTradeHandler.AllowRecover(true); - eaTradeHandler.MaxAllowedRecover(0); + eaTradeHandler.AllowRecover(false); eaTradeHandler.RecoveryTPPoint(50); - eaTradeHandler.RecoverySLPoint(eaSLPoint); + eaTradeHandler.MaxAllowedRecover(3); + eaTradeHandler.MaxAllowedRecoveryVolume(0.1); + eaTradeHandler.RecoverySLPoint(200); eaTradeHandler.RecoveryVolumeMultiplier(2); + eaTradeHandler.ForcePressuresInRecovery(false); // - XSymbolParser symbolParser; - - // - bool drawAreas = false; - - // - bool useEURUSD = false; - bool useUSDCHF = false; - bool useUSDJPY = false; - bool useGBPUSD = false; - bool useXAUUSD = false; - - // - bool useXTest = false; - bool useXDTD = false; - bool useXCHKM = false; - - // - // EURUSD ... - string eurusdSymbol = "EURUSDb"; // symbolParser.GetEURUSDSymbol(); - if (useEURUSD && IsValid(eurusdSymbol)) + // Single Symbol ... + if (!eaMultiSymbol) { // - // MAGIC NUMBER ... - long magicNumber = eaMagicNumber + 1; - + XSCXCHKMStrategy *xchmStrategy; + xchmStrategy = new XSCXCHKMStrategy( + _Symbol, + _Period, + PERIOD_H1, // Analyzing Period + eaVolume, + eaR2R, // R2R ... + eaSlippage, + eaMagicNumber, + true, // Ignore Signal Execution + true, // Use TP SL Point + false, // Use Max + eaTPPoint, // TP + eaSLPoint, // SL + eaIgnoreTP, + true, // eaIgnoreSL, + eaAllowLong, + eaAllowShort, + eaMaxAllowedLongs, // Max Longs + eaMaxAllowedShorts // Max Shorts + ); + xchmStrategy.SetAlertLogAlerts(true); + xchmStrategy.SetAlertEnableAlerts(true); + xchmStrategy.AddSignalEventHandler(OnSignalRecieved); + RegisterStrategy(xchmStrategy); + } + // + // Multi Symbol ... + else + { // - // XDTD ... - if (useXDTD) + // Parse Symbols ... + string symbols[]; + int symbolsCount = SplitContent( + symbols, + eaSymbols // + ); + result = IsValidSize(symbolsCount); + if (!result) { - // - XSCXDTDStrategy *eurusdXTDTStrategy; - eurusdXTDTStrategy = new XSCXDTDStrategy( - eurusdSymbol, - PERIOD_M15, - eaVolume, - eaR2R, // R2R ... - eaSlippage, - magicNumber, - true, // Ignore Signal Execution - true, // Use TP SL Point - false, // Use Max - eaTPPoint, // TP - eaSLPoint, // SL - eaIgnoreTP, - false, // eaIgnoreSL, - eaAllowLong, - eaAllowShort, - eaMaxAllowedLongs, // Max Longs - eaMaxAllowedShorts // Max Shorts - ); - eurusdXTDTStrategy.SetAlertLogAlerts(true); - eurusdXTDTStrategy.SetAlertEnableAlerts(true); - eurusdXTDTStrategy.AddSignalEventHandler(OnSignalRecieved); - RegisterStrategy(eurusdXTDTStrategy); + return result; } // - // XTest ... - if (useXTest) + for (int i = 0; i < symbolsCount; i++) { // - XSCXTestStrategy *eurusdTestStrategy; - eurusdTestStrategy = new XSCXTestStrategy( - eurusdSymbol, - PERIOD_M15, - eaVolume, - eaR2R, // R2R ... - eaSlippage, - magicNumber, - true, // Ignore Signal Execution - true, // Use TP SL Point - false, // Use Max - eaTPPoint, // TP - eaSLPoint, // SL - eaIgnoreTP, - eaIgnoreSL, - eaAllowLong, - eaAllowShort, - eaMaxAllowedLongs, // Max Longs - eaMaxAllowedShorts // Max Shorts - ); - eurusdTestStrategy.SetAlertLogAlerts(true); - eurusdTestStrategy.SetAlertEnableAlerts(true); - eurusdTestStrategy.AddSignalEventHandler(OnSignalRecieved); - RegisterStrategy(eurusdTestStrategy); - } + string iSymbol = symbols[i]; - // - // XCHKM ... - if (useXCHKM) - { // - XSCXCHKMStrategy *eurusdXCHKMStrategy; - eurusdXCHKMStrategy = new XSCXCHKMStrategy( - eurusdSymbol, - PERIOD_M5, + XSCXCHKMStrategy *iStrategy; + iStrategy = new XSCXCHKMStrategy( + iSymbol, + _Period, PERIOD_H1, // Analyzing Period eaVolume, eaR2R, // R2R ... eaSlippage, - magicNumber, + eaMagicNumber, true, // Ignore Signal Execution - false, // Use TP SL Point + true, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL eaIgnoreTP, - false, // eaIgnoreSL, + true, // eaIgnoreSL, eaAllowLong, eaAllowShort, eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); - eurusdXCHKMStrategy.SetAlertLogAlerts(true); - eurusdXCHKMStrategy.SetAlertEnableAlerts(true); - eurusdXCHKMStrategy.AddSignalEventHandler(OnSignalRecieved); - RegisterStrategy(eurusdXCHKMStrategy); + iStrategy.SetAlertLogAlerts(true); + iStrategy.SetAlertEnableAlerts(true); + iStrategy.AddSignalEventHandler(OnSignalRecieved); + + // + RegisterStrategy(iStrategy); } } - // - XSCXCHKMStrategy *xchmStrategy; - xchmStrategy = new XSCXCHKMStrategy( - _Symbol, - _Period, - PERIOD_H1, // Analyzing Period - eaVolume, - eaR2R, // R2R ... - eaSlippage, - eaMagicNumber, - true, // Ignore Signal Execution - true, // Use TP SL Point - false, // Use Max - eaTPPoint, // TP - eaSLPoint, // SL - eaIgnoreTP, - true, // eaIgnoreSL, - eaAllowLong, - eaAllowShort, - eaMaxAllowedLongs, // Max Longs - eaMaxAllowedShorts // Max Shorts - ); - xchmStrategy.SetAlertLogAlerts(true); - xchmStrategy.SetAlertEnableAlerts(true); - xchmStrategy.AddSignalEventHandler(OnSignalRecieved); - RegisterStrategy(xchmStrategy); - // return result; } diff --git a/Indicators/x-saherelm.xchche.mq5 b/Indicators/x-saherelm.xchche.mq5 new file mode 100644 index 00000000..3d928351 --- /dev/null +++ b/Indicators/x-saherelm.xchche.mq5 @@ -0,0 +1,956 @@ +/////////////////////////////////////////////////////// +// SaherElm IT Center MQL5 Indicator +// ------------------------------------------- +// Name: XCHCHE +// Description: XCHE Cycles ... +// +// 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 XCHCHE Indicator" +#property strict + +// +#define ShortName "XCHCHE" + +// +// Includes Common Library ... +#include +#include "../Libraries/x-saherelm.common.lib.mq5" + +// +// Inputs ... + +// +input group "Market"; +input int length = 35; // Length +input int loopback = 26; // Loopback +input double multiplier1 = 3.0; // 1st Multiplier +input double multiplier2 = 3.5; // 2nd Multiplier + +// +input group "Calculation"; +input ENUM_APPLIED_PRICE upAppliedTo = PRICE_HIGH; // Up Zone Applied to +input ENUM_APPLIED_PRICE downAppliedTo = PRICE_LOW; // Down Zone Applied to + +// +input group "Cycles"; + +// +input group "Short"; +input ENUM_X_PERIOD_METHOD scMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES scPeriod = NULL; // Time Period + +// +input group "Medium"; +input ENUM_X_PERIOD_METHOD mcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES mcPeriod = NULL; // Time Period + +// +input group "Long"; +input ENUM_X_PERIOD_METHOD lcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES lcPeriod = NULL; // Time Period + +// +input group "Hind"; +input ENUM_X_PERIOD_METHOD hcMethod = X_PERIOD_AUTO; // How to Find Period +input ENUM_TIMEFRAMES hcPeriod = NULL; // Time Period + +// +// Presentation ... +input group "Presentation"; + +// +// Current ... +input bool showCurrentLE1 = true; // Show Current Cycle Long Exit 1 +input bool showCurrentLE2 = true; // Show Current Cycle Long Exit 2 +input bool showCurrentSE1 = true; // Show Current Cycle Short Exit 1 +input bool showCurrentSE2 = true; // Show Current Cycle Short Exit 2 + +// +// Short ... +input bool showShortLE1 = true; // Show Short Cycle Long Exit 1 +input bool showShortLE2 = true; // Show Short Cycle Long Exit 2 +input bool showShortSE1 = true; // Show Short Cycle Short Exit 1 +input bool showShortSE2 = true; // Show Short Cycle Short Exit 2 + +// +// Medium ... +input bool showMediumLE1 = true; // Show Medium Cycle Long Exit 1 +input bool showMediumLE2 = true; // Show Medium Cycle Long Exit 2 +input bool showMediumSE1 = true; // Show Medium Cycle Short Exit 1 +input bool showMediumSE2 = true; // Show Medium Cycle Short Exit 2 + +// +// Long ... +input bool showLongLE1 = true; // Show Long Cycle Long Exit 1 +input bool showLongLE2 = true; // Show Long Cycle Long Exit 2 +input bool showLongSE1 = true; // Show Long Cycle Short Exit 1 +input bool showLongSE2 = true; // Show Long Cycle Short Exit 2 + +// +// Hind ... +input bool showHindLE1 = true; // Show Hind Cycle Long Exit 1 +input bool showHindLE2 = true; // Show Hind Cycle Long Exit 2 +input bool showHindSE1 = true; // Show Hind Cycle Short Exit 1 +input bool showHindSE2 = true; // Show Hind Cycle Short Exit 2 + +// +// Buffers ... + +// +#define hideColorIDX 0 +#define bullishColorIDX 1 +#define bearishColorIDX 2 + +// +#property indicator_chart_window + +// +#property indicator_buffers 40 +#property indicator_plots 40 + +// +// Current ... + + +// +// Short ... + + +// +// Medium ... + + +// +// Long ... + + +// +// Hind ... + +// +// Variables, Properties and etc ... + +// +int maxLength; + +// +// Current ... +int mCSMLength = cSmoothingLength; + +// +// Short ... +int mSCLength = 0; +int mSSMLength = 0; +ENUM_TIMEFRAMES mSCPeriod = NULL; + +// +// Medium ... +int mMCLength = 0; +int mMSMLength = 0; +ENUM_TIMEFRAMES mMCPeriod = NULL; + +// +// Long ... +int mLCLength = 0; +int mLSMLength = 0; +ENUM_TIMEFRAMES mLCPeriod = NULL; + +// +// Hind ... +int mHCLength = 0; +int mHSMLength = 0; +ENUM_TIMEFRAMES mHCPeriod = NULL; + +// +// Event Handlers ... + +// +// Initialization ... +int OnInit() +{ + // + // Validate Inputs ... + if (!ValidateInputs()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + if (!InitMarketCycles()) + { + return INIT_PARAMETERS_INCORRECT; + } + + // + // because in some cases we may have more than one input for + // calculation and we must prevent any calculation + // untill we pass the biggest input length, here we get max Input length + // and then wait until pass it ... + maxLength = ExtractMaxLengthOfInputs(); + + // + // Define Index Buffers ... + DefineBuffers(); + + // + // Set Indicator ShortName ... + SetIndicatorName(); + + // + // Init Succeed ... + return INIT_SUCCEEDED; +} + +// +// DeInitialization ... +void OnDeinit(const int reason) +{ + // + // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function + // REASON_REMOVE 1 Program removed from a chart + // REASON_RECOMPILE 2 Program recompiled + // REASON_CHARTCHANGE 3 A symbol or a chart period is changed + // REASON_CHARTCLOSE 4 Chart closed + // REASON_PARAMETERS 5 Inputs changed by a user + // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings + // REASON_TEMPLATE 7 Another chart template applied + // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value + // REASON_CLOSE 9 Terminal closed +} + +// +// Calculating what we want ... +int OnCalculate( + const int rates_total, // Total Bars on Chart ... + const int prev_calculated, // Total Calculated Bars on Charts ... + const datetime &time[], // History of Open Time ... + const double &open[], // History of Open Price ... + const double &high[], // History of High Price ... + const double &low[], // History of Low Price ... + const double &close[], // History of Close Price ... + const long &tick_volume[], // History of Tick Volumes on Bar ... + const long &volume[], // History of Trade Volumes ... + const int &spread[] // History of Spread Price ... +) +{ + // + // Prepare Buffers ... + ArraySetAsSeries(time, true); + ArraySetAsSeries(open, true); + ArraySetAsSeries(high, true); + ArraySetAsSeries(low, true); + ArraySetAsSeries(close, true); + ArraySetAsSeries(tick_volume, true); + ArraySetAsSeries(volume, true); + ArraySetAsSeries(spread, true); + + // + // this counts Available Bars ... + int limit; + + // + limit = (prev_calculated > rates_total || prev_calculated <= 0) ? rates_total : (rates_total - prev_calculated) + 1; + + // + // Main Loop ... + for (int i = limit - 1; i >= 0 && !IsStopped(); i--) + { + CalculateHK(i, prev_calculated, rates_total, open, high, close, low); + } + + // + CalculateCycles(rates_total, prev_calculated); + + // + return rates_total; +} + +// +// Functions ... + +// +// Validate Input Args for Initialization ... +bool ValidateInputs() +{ + // + bool result = false; + + // + result = + // + cSmoothingLength > 2 && + // + (IsValid(scMethod, scPeriod) && + IsValid(mcMethod, mcPeriod) && + IsValid(lcMethod, lcPeriod) && + IsValid(hcMethod, hcPeriod)) + // + ; + + // + return result; +} + +// +// Initialize Market Cycles ... +bool InitMarketCycles() +{ + // + bool result = false; + + // + // Current Cycle Initialization ... + + // + int cPeriodSeconds = PeriodSeconds(_Period); + + // + // Short Cycle Initialization ... + + // + // Find Cycle Period ... + if (scMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mSCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_SHORT, + _Period // + ); + } + else + { + mSCPeriod = scPeriod; + } + + // + result = IsValid(mSCPeriod); + if (!result) + { + return result; + } + + // + mSCLength = PeriodSeconds(mSCPeriod) / cPeriodSeconds; + mSSMLength = mSCLength * mCSMLength; + result = mSCLength > 0; + if (!result) + { + return result; + } + + // + // Medium Cycle Initialization ... + + // + // Find Cycle Period ... + if (mcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mMCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_MEDIUM, + _Period // + ); + } + else + { + mMCPeriod = mcPeriod; + } + + // + result = IsValid(mMCPeriod); + if (!result) + { + return result; + } + + // + mMCLength = PeriodSeconds(mMCPeriod) / cPeriodSeconds; + mMSMLength = mMCLength * mCSMLength; + result = mMCLength > 0; + if (!result) + { + return result; + } + + // + // Long Cycle Initialization ... + + // + // Find Cycle Period ... + if (lcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mLCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_LONG, + _Period // + ); + } + else + { + mLCPeriod = lcPeriod; + } + + // + result = IsValid(mLCPeriod); + if (!result) + { + return result; + } + + // + mLCLength = PeriodSeconds(mLCPeriod) / cPeriodSeconds; + mLSMLength = mLCLength * mCSMLength; + result = mLCLength > 0; + if (!result) + { + return result; + } + + // + // Hind Cycle Initialization ... + + // + // Find Cycle Period ... + if (hcMethod == X_PERIOD_AUTO) + { + // + // Select Period ... + mHCPeriod = GetCyclePeriod( + X_MARKET_CYCLE_HIND, + _Period // + ); + } + else + { + mHCPeriod = hcPeriod; + } + + // + result = IsValid(mHCPeriod); + if (!result) + { + return result; + } + + // + mHCLength = PeriodSeconds(mHCPeriod) / cPeriodSeconds; + mHSMLength = mHCLength * mCSMLength; + result = mHCLength > 0; + if (!result) + { + return result; + } + + // + return result; +} + +// +// Retrieve all Exists Input Max Length ... +// use for Start Of Drawing ... +int ExtractMaxLengthOfInputs() +{ + // + int result = 0; + + // + result = MathMax(mCSMLength, mSSMLength); + result = MathMax(result, mMSMLength); + result = MathMax(result, mLSMLength); + result = MathMax(result, mHSMLength); + + // + return result; +} + +// +// Define Indexes and Styles ... +void DefineBuffers() +{ + // + // Data Buffers ... + + // + // Open ... + ArraySetAsSeries(openBuffer, true); + SetIndexBuffer(openBufferIndex, openBuffer, INDICATOR_CALCULATIONS); + + // + // High ... + ArraySetAsSeries(highBuffer, true); + SetIndexBuffer(highBufferIndex, highBuffer, INDICATOR_CALCULATIONS); + + // + // Low ... + ArraySetAsSeries(lowBuffer, true); + SetIndexBuffer(lowBufferIndex, lowBuffer, INDICATOR_CALCULATIONS); + + // + // Close ... + ArraySetAsSeries(closeBuffer, true); + SetIndexBuffer(closeBufferIndex, closeBuffer, INDICATOR_CALCULATIONS); + + // + // Current ... + + // + // Color ... + ArraySetAsSeries(cColorBuffer, true); + SetIndexBuffer(cColorBufferIndex, cColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(cBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(cBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(cColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(cOpenBuffer, true); + PlotIndexSetInteger(cOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(cOpenBufferIndex, cOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(cHighBuffer, true); + PlotIndexSetInteger(cHighBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(cHighBufferIndex, cHighBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(cCloseBuffer, true); + PlotIndexSetInteger(cCloseBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(cCloseBufferIndex, cCloseBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(cLowBuffer, true); + PlotIndexSetInteger(cLowBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(cLowBufferIndex, cLowBuffer, INDICATOR_DATA); + + // + // Short ... + + // + // Color ... + ArraySetAsSeries(sColorBuffer, true); + SetIndexBuffer(sColorBufferIndex, sColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(sBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(sBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(sColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(sOpenBuffer, true); + PlotIndexSetInteger(sOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(sOpenBufferIndex, sOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(sHighBuffer, true); + PlotIndexSetInteger(sHighBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(sHighBufferIndex, sHighBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(sCloseBuffer, true); + PlotIndexSetInteger(sCloseBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(sCloseBufferIndex, sCloseBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(sLowBuffer, true); + PlotIndexSetInteger(sLowBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(sLowBufferIndex, sLowBuffer, INDICATOR_DATA); + + // + // Medium ... + + // + // Color ... + ArraySetAsSeries(mColorBuffer, true); + SetIndexBuffer(mColorBufferIndex, mColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(mBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(mBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(mColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(mOpenBuffer, true); + PlotIndexSetInteger(mOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(mOpenBufferIndex, mOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(mHighBuffer, true); + PlotIndexSetInteger(mHighBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(mHighBufferIndex, mHighBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(mCloseBuffer, true); + PlotIndexSetInteger(mCloseBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(mCloseBufferIndex, mCloseBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(mLowBuffer, true); + PlotIndexSetInteger(mLowBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(mLowBufferIndex, mLowBuffer, INDICATOR_DATA); + + // + // Long ... + + // + // Color ... + ArraySetAsSeries(lColorBuffer, true); + SetIndexBuffer(lColorBufferIndex, lColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(lBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(lBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(lColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(lOpenBuffer, true); + PlotIndexSetInteger(lOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(lOpenBufferIndex, lOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(lHighBuffer, true); + PlotIndexSetInteger(lHighBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(lHighBufferIndex, lHighBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(lCloseBuffer, true); + PlotIndexSetInteger(lCloseBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(lCloseBufferIndex, lCloseBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(lLowBuffer, true); + PlotIndexSetInteger(lLowBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(lLowBufferIndex, lLowBuffer, INDICATOR_DATA); + + // + // Hind ... + + // + // Color ... + ArraySetAsSeries(hColorBuffer, true); + SetIndexBuffer(hColorBufferIndex, hColorBuffer, INDICATOR_COLOR_INDEX); + + // + // Set EMPTY_VALUE on Bar Buffer ... + PlotIndexSetDouble(hBufferIndex, PLOT_EMPTY_VALUE, 0.0); + + // + PlotIndexSetInteger(hBufferIndex, PLOT_SHOW_DATA, false); + PlotIndexSetInteger(hColorBufferIndex, PLOT_SHOW_DATA, false); + + // + // Open ... + ArraySetAsSeries(hOpenBuffer, true); + PlotIndexSetInteger(hOpenBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hOpenBufferIndex, hOpenBuffer, INDICATOR_DATA); + + // + // High ... + ArraySetAsSeries(hHighBuffer, true); + PlotIndexSetInteger(hHighBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hHighBufferIndex, hHighBuffer, INDICATOR_DATA); + + // + // Close ... + ArraySetAsSeries(hCloseBuffer, true); + PlotIndexSetInteger(hCloseBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hCloseBufferIndex, hCloseBuffer, INDICATOR_DATA); + + // + // Low ... + ArraySetAsSeries(hLowBuffer, true); + PlotIndexSetInteger(hLowBufferIndex, PLOT_SHOW_DATA, false); + SetIndexBuffer(hLowBufferIndex, hLowBuffer, INDICATOR_DATA); +} + +// +// Set Indicator Short Name and also we can define Buffers Labels ... +void SetIndicatorName() +{ + IndicatorSetString(INDICATOR_SHORTNAME, ShortName); +} + +// +// Calculations ... + +// +// Calculate Hiken Ashi ... +void CalculateHK( + int bar_index, // Selected Bar Index + const int prevCalculated, + const int ratesTotal, + const double &open[], + const double &high[], + const double &close[], + const double &low[] // +) +{ + // + double mPrevHKOpenValue; + double mPrevHKCloseValue; + + // + if (ArraySize(open) <= bar_index + 1) + { + // + mPrevHKOpenValue = 0; + mPrevHKCloseValue = 0; + } + else + { + // + mPrevHKOpenValue = openBuffer[bar_index + 1]; + mPrevHKCloseValue = closeBuffer[bar_index + 1]; + } + + // + double mHKOpenValue = (mPrevHKOpenValue + mPrevHKCloseValue) / 2; + double mHKCloseValue = (open[bar_index] + high[bar_index] + close[bar_index] + low[bar_index]) / 4; + double mHKHighValue = MathMax(high[bar_index], MathMax(mHKOpenValue, mHKCloseValue)); + double mHKLowValue = MathMin(low[bar_index], MathMin(mHKOpenValue, mHKCloseValue)); + + // + openBuffer[bar_index] = mHKOpenValue; + highBuffer[bar_index] = mHKHighValue; + lowBuffer[bar_index] = mHKLowValue; + closeBuffer[bar_index] = mHKCloseValue; +} + +// +void CalculateCycles( + int ratesTotal, // Total Bars + int prevCalculated // Calculated Bars +) +{ + // + // Current ... + CalculateCycle( + cOpenBuffer, + cHighBuffer, + cLowBuffer, + cCloseBuffer, + cColorBuffer, + mCSMLength, + showCurrent, + ratesTotal, + prevCalculated // + ); + + // + // Short ... + CalculateCycle( + sOpenBuffer, + sHighBuffer, + sLowBuffer, + sCloseBuffer, + sColorBuffer, + mSSMLength, + showShort, + ratesTotal, + prevCalculated // + ); + + // + // Medium ... + CalculateCycle( + mOpenBuffer, + mHighBuffer, + mLowBuffer, + mCloseBuffer, + mColorBuffer, + mMSMLength, + showMedium, + ratesTotal, + prevCalculated // + ); + + // + // Long ... + CalculateCycle( + lOpenBuffer, + lHighBuffer, + lLowBuffer, + lCloseBuffer, + lColorBuffer, + mLSMLength, + showLong, + ratesTotal, + prevCalculated // + ); + + // + // Hind ... + CalculateCycle( + hOpenBuffer, + hHighBuffer, + hLowBuffer, + hCloseBuffer, + hColorBuffer, + mHSMLength, + showHind, + ratesTotal, + prevCalculated // + ); +} + +// +void CalculateCycle( + double &open[], + double &high[], + double &low[], + double &close[], + double &clr[], // Color Index Buffer + int length, // Calculation Length + bool show, // Show or not + int ratesTotal, // Total Bars + int prevCalculated // Calculated Bars +) +{ + // + // Open ... + int calculatedSMOpens = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + openBuffer, + open // + ); + + // + // Close ... + int calculatedSMCloses = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + closeBuffer, + close // + ); + + // + int calculatedSMLows = 0; + int calculatedSMHighs = 0; + if (!ignoreShadows) + { + // + // High ... + calculatedSMHighs = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + highBuffer, + high // + ); + + // + // Low ... + calculatedSMLows = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + lowBuffer, + low // + ); + } + else + { + // + // High ... + calculatedSMHighs = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + openBuffer, + high // + ); + + // + // Low ... + calculatedSMLows = ExponentialMAOnBuffer( + ratesTotal, + prevCalculated, + 0, + length, + closeBuffer, + low // + ); + } + + // + // Find Calculated Items for Colors Calculations ... + int mNumberOfItems = MathMin(calculatedSMOpens, calculatedSMHighs); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMLows); + mNumberOfItems = MathMin(mNumberOfItems, calculatedSMCloses); + + // + // Create a Loop for Color of Candles ... + for (int i = 0; i < mNumberOfItems; i++) + { + // + bool isBearish = + // + open[i] > close[i] + // + ; + + // + if (show) + { + // + clr[i] = isBearish + ? bearishColorIDX + : bullishColorIDX; + } + else + { + // + clr[i] = hideColorIDX; + } + } +} + +// \ No newline at end of file diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index 70ec314e..edf4061f 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -3791,6 +3791,7 @@ struct XTradeData int maxAllowedRecover; // Max Allowed Recovery int recoveryLevel; // Number of Recovery Signals double recoveryVolumeMultiplier; // Recovery Volume Multiplier + double recoveryVolume; // Next Recovery Positioin Volume ENUM_X_POSITION_TYPES recoveryLookingType; // Looking for Next Recovery Type // @@ -3799,6 +3800,7 @@ struct XTradeData // allowRecover = false; recoveryLevel = 0; + recoveryVolume = 0; recoveryTPPoint = 0; recoverySLPoint = 0; recoveryVolumeMultiplier = 0; diff --git a/Strategies/x-saherelm.xchkm.strategy.mq5 b/Strategies/x-saherelm.xchkm.strategy.mq5 index ebf176fb..45e1261b 100644 --- a/Strategies/x-saherelm.xchkm.strategy.mq5 +++ b/Strategies/x-saherelm.xchkm.strategy.mq5 @@ -186,6 +186,229 @@ public: mEnableXCHSTR = value; } + // + // Important Areas Getters ... + + // + bool GetSupport( + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + result = support.IsValid(); + if (result) + { + bar = support; + } + + // + return result; + } + + // + bool GetResistance( + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + result = resistance.IsValid(); + if (result) + { + bar = resistance; + } + + // + return result; + } + + // + bool GetBullishOB( + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + result = bullishOB.IsValid(); + if (result) + { + bar = bullishOB; + } + + // + return result; + } + + // + bool GetBearishOB( + XOHCL &bar // + ) + { + // + bool result = false; + + // + bar.Clean(); + + // + result = bearishOB.IsValid(); + if (result) + { + bar = bearishOB; + } + + // + return result; + } + + // + bool GetBullishFVG( + XOHCL &bar, + double upper, + double lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + bar.Clean(); + + // + result = bullishFVG.IsValid(); + if (result) + { + // + bar = bullishFVG; + upper = bullishFVGUpper; + lower = bullishFVGLower; + } + + // + return result; + } + + // + bool GetBearishFVG( + XOHCL &bar, + double upper, + double lower // + ) + { + // + bool result = false; + + // + upper = 0; + lower = 0; + bar.Clean(); + + // + result = bearishFVG.IsValid(); + if (result) + { + // + bar = bearishFVG; + upper = bearishFVGUpper; + lower = bearishFVGLower; + } + + // + return result; + } + + // + bool GetBullishTrend( + XOHCL &bar, + XOHCL &swingHighs[], + XOHCL &swingLows[] // + ) + { + // + bool result = false; + + // + bar.Clean(); + Clean(swingHighs); + Clean(swingLows); + + // + result = bullishTrend.IsValid(); + if (result) + { + // + bar = bullishTrend; + + // + Copy( + bullishTrendSwingHighs, + swingHighs // + ); + Copy( + bullishTrendSwingLows, + swingLows // + ); + } + + // + return result; + } + + // + bool GetBearishTrend( + XOHCL &bar, + XOHCL &swingHighs[], + XOHCL &swingLows[] // + ) + { + // + bool result = false; + + // + bar.Clean(); + Clean(swingHighs); + Clean(swingLows); + + // + result = bearishTrend.IsValid(); + if (result) + { + // + bar = bearishTrend; + + // + Copy( + bearishTrendSwingHighs, + swingHighs // + ); + Copy( + bearishTrendSwingLows, + swingLows // + ); + } + + // + return result; + } + // // Overrides ... @@ -566,6 +789,71 @@ public: } } + // + // TREND ... + + // + bool hasBullishTrend = bullishTrend.IsValid(); + if (!hasBullishTrend) + { + // + hasBullishTrend = aBar.HasBullishTrend( + bullishTrendSwingHighs, + bullishTrendSwingLows, + false // + ); + + // + if (hasBullishTrend) + { + // + bullishTrend = aBar; + + // + if (mDrawImportantAreas) + { + // + DrawBullishTrend( + bullishTrend, + bullishTrendSwingHighs, + bullishTrendSwingLows, + ChartID() // + ); + } + } + } + + // + bool hasBearishTrend = bearishTrend.IsValid(); + if (!hasBearishTrend) + { + // + hasBearishTrend = aBar.HasBearishTrend( + bearishTrendSwingHighs, + bearishTrendSwingLows, + false // + ); + + // + if (hasBearishTrend) + { + // + bearishTrend = aBar; + + // + if (mDrawImportantAreas) + { + // + DrawBearishTrend( + bearishTrend, + bearishTrendSwingHighs, + bearishTrendSwingLows, + ChartID() // + ); + } + } + } + // // For Trend ... XOHCL tmpHSW[]; @@ -1007,6 +1295,10 @@ public: CheckBullishFVGValidation(); CheckBearishFVgValidation(); + // + CheckBullishTrendValidation(); + CheckBearishTrendValidation(); + // return result; } @@ -1071,6 +1363,22 @@ public: bearishFVG.Clean(); } + // + if (hasBullishTrend) + { + // + RemoveBullishTrend(bullishTrend); + bullishTrend.Clean(); + } + + // + if (hasBearishTrend) + { + // + RemoveBearishTrend(bearishTrend); + bearishTrend.Clean(); + } + // // Retrieve Entry Price based on Position Type ... entry = GetEntry(mSymbol, type); @@ -1159,6 +1467,16 @@ protected: double bearishFVGLower; XOHCL bearishFVG; + // + XOHCL bullishTrendSwingHighs[]; + XOHCL bullishTrendSwingLows[]; + XOHCL bullishTrend; + + // + XOHCL bearishTrendSwingHighs[]; + XOHCL bearishTrendSwingLows[]; + XOHCL bearishTrend; + // // XPV ... XPVInputs pvInputs; @@ -1594,6 +1912,20 @@ private: } } + // + void CheckBullishTrendValidation() + { + // + // TODO: Complete this ... + } + + // + void CheckBearishTrendValidation() + { + // + // TODO: Complete this ... + } + // // XCHE Custom Data ...