diff --git a/.vscode/vscode-kanban.json b/.vscode/vscode-kanban.json index 0080b68e..4c4b6b36 100644 --- a/.vscode/vscode-kanban.json +++ b/.vscode/vscode-kanban.json @@ -7,7 +7,7 @@ }, "creation_time": "2024-07-28T22:48:10.644Z", "details": { - "content": "[] Add Recovery Options when try to Synchronize Positions Using Trade Handler ...\n[x] Add Do not Trail Support or Recovery Positions in Trade Handler ...\n[x] Add a TP and SL to Recovery Position ...\n[x] Made Multi Asset ...\n[] Add Pressure Based Trailling ...\n[x] Add Support for Pressures in Recovery ...\n[] Add OB / FVG and Other things Like XPV Signalling ...\n[x] Create XCHCHE Insicator and it's Helper class ...\n[] Create XCHVLM. XCHTD ...\n", + "content": "[] Add Recovery Options when try to Synchronize Positions Using Trade Handler ...\n[x] Add Do not Trail Support or Recovery Positions in Trade Handler ...\n[x] Add a TP and SL to Recovery Position ...\n[x] Made Multi Asset ...\n[] Add Pressure Based Trailling ...\n[x] Add Support for Pressures in Recovery ...\n[] Add OB / FVG and Other things Like XPV Signalling ...\n[x] Create XCHCHE Insicator and it's Helper class ...\n[x] Create XCHVLM. XCHTD ...\n[] Add Support for Free Margin Check ...\n", "mime": "text/markdown" }, "id": "86", diff --git a/Classes/x-saherelm.xtrade.class.mq5 b/Classes/x-saherelm.xtrade.class.mq5 index 06c690b7..118c09f1 100644 --- a/Classes/x-saherelm.xtrade.class.mq5 +++ b/Classes/x-saherelm.xtrade.class.mq5 @@ -4156,6 +4156,99 @@ public: return maxSameTimeTrades; } + // + bool AllowLong() + { + return mAllowLong; + } + + // + void AllowLong(bool value) + { + mAllowLong = value; + } + + // + bool AllowShort() + { + return mAllowShort; + } + + // + void AllowShort(bool value) + { + mAllowShort = value; + } + + // + int MaxAllowedLongs() + { + return mMaxAllowedLongs; + } + + // + void MaxAllowedLongs(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedLongs = value; + } + + // + int MaxAllowedShorts() + { + return mMaxAllowedShorts; + } + + // + void MaxAllowedShorts(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxAllowedShorts = value; + } + + // + bool UseMaxAllowedTradesPerSymbol() + { + return mUseMaxAllowedTradesPerSymbol; + } + + // + void UseMaxAllowedTradesPerSymbol(bool value) + { + mUseMaxAllowedTradesPerSymbol = value; + } + + // + double MaxDrawdownPercentForOpenTrades() + { + return mMaxDrawdownPercentForOpenTrades; + } + + // + void MaxDrawdownPercentForOpenTrades(double value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMaxDrawdownPercentForOpenTrades = value; + } + // // Trailling ... @@ -4370,18 +4463,6 @@ public: mAllowHedging = value; } - // - bool OnlyHedgeSupportedPositions() - { - return mOnlyHedgeSupportedPositions; - } - - // - void OnlyHedgeSupportedPositions(bool value) - { - mOnlyHedgeSupportedPositions = value; - } - // double HedgeVolumeFactor() { @@ -4401,6 +4482,25 @@ public: mHedgeVolumeFactor = value; } + // + int MinTradesForHedge() + { + return mMinTradesForHedge; + } + + // + void MinTradesForHedge(int value) + { + // + if (value < 0) + { + value = 0; + } + + // + mMinTradesForHedge = value; + } + // double HedgeMinProfitPerVolumeFactor() { @@ -4423,6 +4523,36 @@ public: // // Tools ... + // + // Calculate Max Drawdown and it's Percent ... + double GetMaxDrawdown() + { + // + XPosition positions[]; + int positionsCount = mTrader.GetPositions(positions); + if (IsValidSize(positionsCount)) + { + double mEquity = mTrader.mAccount.GetEquity(); + if (mEquity > maxDrawdown) + { + maxDrawdown = mEquity; + } + + // + drawdownPercent = (maxDrawdown - mEquity) / (staticBalanceForCalculateDrawdown > 0 ? staticBalanceForCalculateDrawdown : maxDrawdown) * 100; + drawdownPercent = NormalizeDouble(drawdownPercent, 3); + } + else + { + // + maxDrawdown = 0.0; + drawdownPercent = 0.0; + } + + // + return drawdownPercent; + } + // // First Step of Trade Handling ... // Since Must Call when a Signal Executed ... @@ -4662,6 +4792,9 @@ public: { maxSameTimeTrades = count; } + + // + GetMaxDrawdown(); } // @@ -4681,9 +4814,9 @@ public: { // // Check Values Validation ... - if ((count > 1 || - (count == 1 && - mOnlyHedgeSupportedPositions)) && + if ((mMinTradesForHedge <= 0 + ? count > 1 + : count >= mMinTradesForHedge) && mHedgeVolumeFactor > 0 && mHedgeMinProfitPerVolumeFactor > 0) { @@ -5342,6 +5475,162 @@ public: return result; } + // + bool ExecuteSignal( + XSignal &signal, // Signal for Execution + ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Execution State + bool ignorePolicies = false // Ignore Execution Policies + ) + { + // + bool result = false; + + // + // Check Signal Validation ... + result = signal.IsValid(); + if (!result) + { + return result; + } + + // + // Filter Signals if Necessary ... + result = CanExecute(signal); + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_INVALID_PARAMS; + return result; + } + + // + // Check Policies ... + if (!ignorePolicies) + { + // + bool isLong = IsLong(signal.type); + + // + // Check Allow Trade Type ... + result = + isLong + ? mAllowLong + : mAllowShort; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED; + return result; + } + + // + // Check Trades Count ... + if (mMaxAllowedLongs > 0 || mMaxAllowedShorts > 0) + { + // + XPosition longs[]; + XPosition shorts[]; + + // + // Counting Positions ... + if (mUseMaxAllowedTradesPerSymbol) + { + // + mTrader.GetPositions( + longs, + shorts, + signal.symbol // + ); + } + else + { + // + mTrader.GetPositions( + longs, + shorts, + NULL // All Symbols ... + ); + } + + // + int longsCount = ArraySize(longs); + int shortsCount = ArraySize(shorts); + + // + result = + // + // Long ... + isLong + ? mMaxAllowedLongs <= 0 + ? true + : longsCount < mMaxAllowedLongs + // + // Short ... + : mMaxAllowedShorts <= 0 + ? true + : shortsCount < mMaxAllowedShorts + // + ; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_MAX_REACHED; + return result; + } + } + + // + // Check Drawdown ... + if (mMaxDrawdownPercentForOpenTrades > 0) + { + // + drawdownPercent = GetMaxDrawdown(); + + // + result = + drawdownPercent <= 0 + ? true + : drawdownPercent < mMaxDrawdownPercentForOpenTrades; + if (!result) + { + // + state = X_SIGNAL_EXECUTION_FAILED_NO_EQUITY; + return result; + } + } + } + + // + // Execute Signal ... + result = mTrader.ExecuteSignal( + signal, + state // + ); + if (result) + { + // + double commission = mTrader.GetPositionCommission(signal.positionId); + + // + // Add Signal to Trade Handler ... + AddData( + signal, + commission // + ); + + // + string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") + + " Signal Provided by: " + signal.provider + + " on: " + signal.symbol + + " in: " + ToString(signal.period) + + " Executed Successfully ..."; + Alert(msg); + } + + // + return result; + } + // // Protected ... protected: @@ -5352,6 +5641,14 @@ protected: bool mSaveSignals; // Save Signals bool mSaveTrades; // Save Trades + // + bool mAllowLong; // Allow Long/Buy Trade Type + bool mAllowShort; // Allow Short/Sell Trade Type + int mMaxAllowedLongs; // Max Allowe Long/Buy Trades + int mMaxAllowedShorts; // Max Allowe Short/Sell Trades + bool mUseMaxAllowedTradesPerSymbol; // Use Max Allowed Trades Per Symbol + double mMaxDrawdownPercentForOpenTrades; // Max Drawdown Percent for Open Trades + // XSCTrade *mTrader; // Instance of Trader Class XTradeCollector *mCollector; // Instance of Trade Collector Class @@ -5377,7 +5674,7 @@ protected: // // Hedging ... bool mAllowHedging; // Hedge Trades - bool mOnlyHedgeSupportedPositions; // Only Hedge Supported Positions + int mMinTradesForHedge; // Minimum Open Trades for Do Hedge double mHedgeVolumeFactor; // Hedging Volume Factor double mHedgeMinProfitPerVolumeFactor; // Hedging Min Required Profit Per Volume Factor @@ -5389,7 +5686,10 @@ protected: private: // // Props ... - int maxSameTimeTrades; // Max Same Time Trades + int maxSameTimeTrades; // Max Same Time Trades + double maxDrawdown; // Max Drawdown + double drawdownPercent; // Drawdown Percent + double staticBalanceForCalculateDrawdown; // Static Balance for Max Drawdown Calculation // // Count Data ... diff --git a/Experts/x-test-strategies.ea.mq5 b/Experts/x-test-strategies.ea.mq5 index 7f267f0f..5614e3e9 100644 --- a/Experts/x-test-strategies.ea.mq5 +++ b/Experts/x-test-strategies.ea.mq5 @@ -28,7 +28,7 @@ #include "../Helpers/x-saherelm.xcc.helper.mq5" // -#include "../Strategies/x-saherelm.xchkm.strategy.mq5" +#include "../Strategies/x-saherelm.xch.strategy.mq5" // // Inputs ... @@ -36,32 +36,24 @@ long eaMagicNumber = 78692110; // Magic Number int eaSlippage = 10; // Slippgae // -double eaVolume = 0.01; // Static Volume -double eaAllowLong = true; // Allow Long Positions -double eaAllowShort = true; // Allow Short Positions - -// -int eaMaxAllowedLongs = 1; // Max Allowed Long Positions -int eaMaxAllowedShorts = 1; // Max Allowed Short Positions - -// -double eaTPPoint = 150; // Static TP Point -double eaSLPoint = 500; // Static SL Point - -// +double eaVolume = 0.01; // Static Volume bool eaIgnoreTP = false; // Ignore TP bool eaIgnoreSL = false; // Ignore SL +double eaTPPoint = 150; // Static TP Point +double eaSLPoint = 500; // Static SL Point // -// int eaMaxAllowedSLsInDay = 0; +double eaR2R = 1.5; // Risk to Reward Ratio +double eaAllowLong = true; // Allow Long Positions +double eaAllowShort = true; // Allow Short Positions +int eaMaxAllowedLongs = 1; // Max Allowed Long Positions +int eaMaxAllowedShorts = 1; // Max Allowed Short Positions +double eaMaxDrawdownPercentForOpenTrades = 3; // Max Drawdown Percent for Open Trades // -double eaR2R = 1.5; // Risk to Reward Ratio - -// -bool eaMultiSymbol = false; // Use Multi Symbol -bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol -string eaSymbols = "EURUSDb,USDJPYb"; // Trading Symbols +bool eaMultiSymbol = false; // Use Multi Symbol +bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol +string eaSymbols = "EURUSDb,USDJPYb"; // Trading Symbols // string eaSymbols = "EURUSDb,USDJPYb,USDCHFb,GBPUSDb,XAUUSDb,XAGUSDb"; // Trading Symbols // @@ -272,11 +264,19 @@ bool InitialEA() eaTradeHandler.SaveTrades(true); eaTradeHandler.SaveSignals(true); + // + eaTradeHandler.AllowLong(eaAllowLong); + eaTradeHandler.AllowShort(eaAllowShort); + eaTradeHandler.MaxAllowedLongs(eaMaxAllowedLongs); + eaTradeHandler.MaxAllowedShorts(eaMaxAllowedShorts); + eaTradeHandler.UseMaxAllowedTradesPerSymbol(eaUseMaxAllowedTradesPerSymbol); + eaTradeHandler.MaxDrawdownPercentForOpenTrades(eaMaxDrawdownPercentForOpenTrades); + // // Configure Hedging ... eaTradeHandler.AllowHedging(true); + eaTradeHandler.MinTradesForHedge(2); eaTradeHandler.HedgeVolumeFactor(eaVolume); - eaTradeHandler.OnlyHedgeSupportedPositions(false); eaTradeHandler.HedgeMinProfitPerVolumeFactor(0.3); // @@ -302,8 +302,8 @@ bool InitialEA() if (!eaMultiSymbol) { // - XSCXCHKMStrategy *xchmStrategy; - xchmStrategy = new XSCXCHKMStrategy( + XSCXCHStrategy *xchStrategy; + xchStrategy = new XSCXCHStrategy( _Symbol, _Period, PERIOD_H1, // Analyzing Period @@ -323,15 +323,15 @@ bool InitialEA() eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); - xchmStrategy.EnableXCHM(true); - xchmStrategy.EnableXCHHK(true); - xchmStrategy.EnableXCHSTR(true); - xchmStrategy.EnableXCHCHE(false); - xchmStrategy.SetAlertLogAlerts(true); - xchmStrategy.DrawImportantAreas(false); - xchmStrategy.SetAlertEnableAlerts(true); - xchmStrategy.AddSignalEventHandler(OnSignalRecieved); - RegisterStrategy(xchmStrategy); + xchStrategy.EnableXCHM(true); + xchStrategy.EnableXCHHK(true); + xchStrategy.EnableXCHSTR(true); + xchStrategy.EnableXCHCHE(true); + xchStrategy.SetAlertLogAlerts(true); + xchStrategy.DrawImportantAreas(false); + xchStrategy.SetAlertEnableAlerts(true); + xchStrategy.AddXCHSignalEventHandler(OnSignalRecieved); + RegisterStrategy(xchStrategy); } // // Multi Symbol ... @@ -357,8 +357,8 @@ bool InitialEA() string iSymbol = symbols[i]; // - XSCXCHKMStrategy *iStrategy; - iStrategy = new XSCXCHKMStrategy( + XSCXCHStrategy *iStrategy; + iStrategy = new XSCXCHStrategy( iSymbol, _Period, PERIOD_H1, // Analyzing Period @@ -381,11 +381,11 @@ bool InitialEA() iStrategy.EnableXCHM(true); iStrategy.EnableXCHHK(true); iStrategy.EnableXCHSTR(true); - iStrategy.EnableXCHCHE(false); + iStrategy.EnableXCHCHE(true); iStrategy.SetAlertLogAlerts(true); iStrategy.DrawImportantAreas(false); iStrategy.SetAlertEnableAlerts(true); - iStrategy.AddSignalEventHandler(OnSignalRecieved); + iStrategy.AddXCHSignalEventHandler(OnSignalRecieved); // RegisterStrategy(iStrategy); @@ -467,8 +467,14 @@ void HandleTimeReport() // // All Signals from Strategies Comming Here for Execution or // Analyzing ... -void OnSignalRecieved(XSignal &signal) +void OnSignalRecieved( + XSignal &signal, + XCHStrategyConditions &conditions // +) { + // + // Check Signal and Conditions Validations ... + // if (!signal.IsValid()) { @@ -476,134 +482,39 @@ void OnSignalRecieved(XSignal &signal) } // - bool isLong = IsLong(signal.type); - - // - // Check Allow Trade Type ... - if ((isLong && !eaAllowLong) || - (!isLong && !eaAllowShort)) + if (!conditions.IsValid()) { return; } // - // Check Max Allowed ... - if (eaMaxAllowedLongs > 0 || eaMaxAllowedShorts > 0) - { - // - XPosition longs[]; - XPosition shorts[]; - - // - if (eaUseMaxAllowedTradesPerSymbol) - { - // - eaTrader.GetPositions( - longs, - shorts, - signal.symbol // - ); - } - else - { - // - eaTrader.GetPositions( - longs, - shorts, - NULL // All Symbols ... - ); - } - - // - int longsCount = ArraySize(longs); - int shortsCount = ArraySize(shorts); - - // - if ((isLong && - eaMaxAllowedLongs > 0 && - longsCount >= eaMaxAllowedLongs) || - (!isLong && - eaMaxAllowedShorts > 0 && - shortsCount >= eaMaxAllowedShorts)) - { - return; - } - } - - // - // Check Signal Can Execute or not ... - bool canExecute = eaTradeHandler.CanExecute(signal); - if (!canExecute) + XCHStartegyConditionsParser parser; + bool isFiltered = parser.IsFiltered( + signal, + conditions // + ); + if (isFiltered) { return; } - // // - // if (eaMaxAllowedSLsInDay > 0 && - // mNumberOfSLs >= eaMaxAllowedSLsInDay) - // { - // return; - // } - - // // - // if (signal.pushers < 2) - // { - // return; - // } + // + // Attach Conditions Summary to Signal ... + string conditionsSummary = conditions.GenerateSummary( + false, + false, + true, + false // + ); + signal.conditions = conditionsSummary; // + // Execute Signal Using Trade Handler ... ENUM_X_SIGNAL_EXECUTION_RESULT state; - bool isExecuted = eaTrader.ExecuteSignal( + bool isExecuted = eaTradeHandler.ExecuteSignal( signal, state // ); - - // - if (isExecuted) - { - // - // Find Executed Signal Deal History ... - XDeal deals[]; - double commission = 0; - int dealsCount = eaTrader.GetDeals( - deals, - signal.symbol, - signal.provider, - signal.period, - NULL, - DEAL_ENTRY_IN // - ); - if (IsValidSize(dealsCount)) - { - // - for (int i = 0; i < dealsCount; i++) - { - // - XDeal iDeal = deals[i]; - if (iDeal.positionId == signal.positionId) - { - // - commission = iDeal.commission; - break; - } - } - } - - // - // Add Signal to Trade Handler ... - eaTradeHandler.AddData( - signal, - commission // - ); - - // - string msg = (signal.type == POSITION_TYPE_BUY ? "Long" : "Short") + - " Signal Provided by: " + signal.provider + - " on: " + signal.symbol + - " in: " + ToString(signal.period) + - " Executed Successfully ..."; - eaAlert.Alert(msg); - } } // diff --git a/Helpers/x-saherelm.xchche.helper.mq5 b/Helpers/x-saherelm.xchche.helper.mq5 index a7cbe794..51cda9cd 100644 --- a/Helpers/x-saherelm.xchche.helper.mq5 +++ b/Helpers/x-saherelm.xchche.helper.mq5 @@ -2299,6 +2299,68 @@ public: return result; } + // + bool IsCycleStrongBearish( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // + ) + { + // + bool result = false; + + // + double se1 = 0; + double se2 = 0; + + // + switch (cycle) + { + // + // CURRENT ... + case X_MARKET_CYCLE_UNKNOWN: + se1 = GetCSE1(barIndex); + se2 = GetCSE2(barIndex); + break; + + // + // SHORT ... + case X_MARKET_CYCLE_SHORT: + se1 = GetSSE1(barIndex); + se2 = GetSSE2(barIndex); + break; + + // + // MEDIUM ... + case X_MARKET_CYCLE_MEDIUM: + se1 = GetMSE1(barIndex); + se2 = GetMSE2(barIndex); + break; + + // + // LONG ... + case X_MARKET_CYCLE_LONG: + se1 = GetLSE1(barIndex); + se2 = GetLSE2(barIndex); + break; + + // + // HIND ... + case X_MARKET_CYCLE_HIND: + se1 = GetHSE1(barIndex); + se2 = GetHSE2(barIndex); + break; + } + + // + result = se1 != EMPTY_VALUE && + se1 > 0 && + se2 != EMPTY_VALUE && + se2 > 0; + + // + return result; + } + // int GetCycleValues( int barIndex, // Bar Index @@ -2419,6 +2481,182 @@ public: return result; } + // + int GetCycleBullishValues( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle, + double &values[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + double le1 = 0; + double le2 = 0; + + // + switch (cycle) + { + // + // CURRENT ... + case X_MARKET_CYCLE_UNKNOWN: + // + le1 = GetCLE1(barIndex); + le2 = GetCLE2(barIndex); + break; + + // + // SHORT ... + case X_MARKET_CYCLE_SHORT: + // + le1 = GetSLE1(barIndex); + le2 = GetSLE2(barIndex); + break; + + // + // MEDIUM ... + case X_MARKET_CYCLE_MEDIUM: + // + le1 = GetMLE1(barIndex); + le2 = GetMLE2(barIndex); + break; + + // + // LONG ... + case X_MARKET_CYCLE_LONG: + // + le1 = GetLLE1(barIndex); + le2 = GetLLE2(barIndex); + break; + + // + // HIND ... + case X_MARKET_CYCLE_HIND: + // + le1 = GetHLE1(barIndex); + le2 = GetHLE2(barIndex); + break; + } + + // + if (le1 > 0 && le1 != EMPTY_VALUE) + { + // + Add( + le1, + values // + ); + } + + // + if (le2 > 0 && le2 != EMPTY_VALUE) + { + // + Add( + le2, + values // + ); + } + + // + result = ArraySize(values); + + // + return result; + } + + // + int GetCycleBearishValues( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle, + double &values[] // + ) + { + // + int result = 0; + + // + Clean(values); + + // + double se1 = 0; + double se2 = 0; + + // + switch (cycle) + { + // + // CURRENT ... + case X_MARKET_CYCLE_UNKNOWN: + // + se1 = GetCSE1(barIndex); + se2 = GetCSE2(barIndex); + break; + + // + // SHORT ... + case X_MARKET_CYCLE_SHORT: + // + se1 = GetSSE1(barIndex); + se2 = GetSSE2(barIndex); + break; + + // + // MEDIUM ... + case X_MARKET_CYCLE_MEDIUM: + // + se1 = GetMSE1(barIndex); + se2 = GetMSE2(barIndex); + break; + + // + // LONG ... + case X_MARKET_CYCLE_LONG: + // + se1 = GetLSE1(barIndex); + se2 = GetLSE2(barIndex); + break; + + // + // HIND ... + case X_MARKET_CYCLE_HIND: + // + se1 = GetHSE1(barIndex); + se2 = GetHSE2(barIndex); + break; + } + + // + if (se1 > 0 && se1 != EMPTY_VALUE) + { + // + Add( + se1, + values // + ); + } + + // + if (se2 > 0 && se2 != EMPTY_VALUE) + { + // + Add( + se2, + values // + ); + } + + // + result = ArraySize(values); + + // + return result; + } + // double GetCycleMax( int barIndex, // Bar Index @@ -2503,68 +2741,6 @@ public: return result; } - // - bool IsCycleStrongBearish( - int barIndex, // Bar Index - ENUM_X_MARKET_CYCLES cycle // - ) - { - // - bool result = false; - - // - double se1 = 0; - double se2 = 0; - - // - switch (cycle) - { - // - // CURRENT ... - case X_MARKET_CYCLE_UNKNOWN: - se1 = GetCSE1(barIndex); - se2 = GetCSE2(barIndex); - break; - - // - // SHORT ... - case X_MARKET_CYCLE_SHORT: - se1 = GetSSE1(barIndex); - se2 = GetSSE2(barIndex); - break; - - // - // MEDIUM ... - case X_MARKET_CYCLE_MEDIUM: - se1 = GetMSE1(barIndex); - se2 = GetMSE2(barIndex); - break; - - // - // LONG ... - case X_MARKET_CYCLE_LONG: - se1 = GetLSE1(barIndex); - se2 = GetLSE2(barIndex); - break; - - // - // HIND ... - case X_MARKET_CYCLE_HIND: - se1 = GetHSE1(barIndex); - se2 = GetHSE2(barIndex); - break; - } - - // - result = se1 != EMPTY_VALUE && - se1 > 0 && - se2 != EMPTY_VALUE && - se2 > 0; - - // - return result; - } - // int GetBullishCycles( int barIndex, // Bar Index @@ -3039,6 +3215,142 @@ public: return result; } + // + double GetCycleBullishMax( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // Cycle + ) + { + // + double result = 0; + + // + bool isBullish = IsCycleBullish( + barIndex, + cycle // + ); + if (!isBullish) + { + return result; + } + + // + double values[]; + int count = GetCycleBullishValues( + barIndex, + cycle, + values // + ); + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetCycleBullishMin( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // Cycle + ) + { + // + double result = 0; + + // + bool isBullish = IsCycleBullish( + barIndex, + cycle // + ); + if (!isBullish) + { + return result; + } + + // + double values[]; + int count = GetCycleBullishValues( + barIndex, + cycle, + values // + ); + + // + result = GetSpecifiedMin(values); + + // + return result; + } + + // + double GetCycleBearishMax( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // Cycle + ) + { + // + double result = 0; + + // + bool isBearish = IsCycleBearish( + barIndex, + cycle // + ); + if (!isBearish) + { + return result; + } + + // + double values[]; + int count = GetCycleBearishValues( + barIndex, + cycle, + values // + ); + + // + result = GetSpecifiedMax(values); + + // + return result; + } + + // + double GetCycleBearishMin( + int barIndex, // Bar Index + ENUM_X_MARKET_CYCLES cycle // Cycle + ) + { + // + double result = 0; + + // + bool isBearish = IsCycleBearish( + barIndex, + cycle // + ); + if (!isBearish) + { + return result; + } + + // + double values[]; + int count = GetCycleBearishValues( + barIndex, + cycle, + values // + ); + + // + result = GetSpecifiedMin(values); + + // + return result; + } + // double GetBullishPower( int barIndex // Bar Index diff --git a/Libraries/x-saherelm.xtrade.lib.mq5 b/Libraries/x-saherelm.xtrade.lib.mq5 index fb259488..12205858 100644 --- a/Libraries/x-saherelm.xtrade.lib.mq5 +++ b/Libraries/x-saherelm.xtrade.lib.mq5 @@ -133,6 +133,7 @@ enum ENUM_X_SIGNAL_EXECUTION_RESULT X_SIGNAL_EXECUTION_UNKNOWN, // Unknown X_SIGNAL_EXECUTION_SUCCEED, // Succed X_SIGNAL_EXECUTION_FAILED_SPREAD, // Spread more than Max Allowed + X_SIGNAL_EXECUTION_FAILED_NOT_ALLOWED, // Not Allowed Trade Type X_SIGNAL_EXECUTION_FAILED_NO_EQUITY, // No Equity for Trade X_SIGNAL_EXECUTION_FAILED_PRICE_ERROR, // Price Error X_SIGNAL_EXECUTION_FAILED_MAX_REACHED, // Max Allowed Positions Reached @@ -735,7 +736,8 @@ struct XSignal XSignal supports[]; // a Collecion of Support Signals ... // - int pushers; // Signal Pushers ... + int pushers; // Signal Pushers ... + string conditions; // Signal Conditions ... // // Constructor ... @@ -1152,6 +1154,7 @@ struct XSignal period = NULL; comment = NULL; provider = NULL; + conditions = NULL; // Clean(supports); @@ -3406,6 +3409,8 @@ struct XTradeData datetime endTime; // End Time // + int pushers; // Signal Pushers + string conditions; // Signal Conditions // // Constructor ... @@ -3742,7 +3747,13 @@ struct XTradeData ToString("Max Drawdown", maxDrawdown) + ToString("End Time", endTime) + ToString("Age", age) + - ToString("Message", message) + ToString("Message", message) + + "-------------" + "\n" + + ToString("Pushers", pushers) + + "Conditions:" + "\n" + + "-------------" + "\n" + + conditions + + "" // ) + // diff --git a/Strategies/x-saherelm.xchkm.strategy.mq5 b/Strategies/x-saherelm.xch.strategy.mq5 similarity index 71% rename from Strategies/x-saherelm.xchkm.strategy.mq5 rename to Strategies/x-saherelm.xch.strategy.mq5 index b094faa9..e73d66ee 100644 --- a/Strategies/x-saherelm.xchkm.strategy.mq5 +++ b/Strategies/x-saherelm.xch.strategy.mq5 @@ -2,7 +2,7 @@ // // SaherElm IT Center MQL5 Class Library // -------------------------------------- -// Name: XSCXCHKMStrategy +// Name: XSCXCHStrategy // Description: provides all based classes for use ... // // @@ -36,20 +36,320 @@ // Base Classes ... #include "../Classes/x-saherelm.xstrategy.class.mq5" +// +// Definitions ... + // // Specific Identifier(s) of XStrategy ... -string XCHKMStartegyToken = "XCHKM"; +string XCHStartegyToken = "XCH"; + +// +struct XCHStrategyConditions +{ + // + // Props ... + + // + // Common ... + string symbol; + ENUM_TIMEFRAMES period; + datetime time; + + // + // Helper Conditions ... + XPVConditions pvConditions; + XCHMConditions chmConditions; + XCHHKConditions chhkConditions; + XCHTDConditions chtdConditions; + XCHCHEConditions chcheConditions; + XCHSTRConditions chstrConditions; + XCHVLMConditions chvlmConditions; + + // + // Constructor ... + void XCHStrategyConditions() + { + Clean(); + } + + // + // Tools ... + + // + // Cleanup ... + void Clean() + { + // + symbol = NULL; + period = NULL; + time = NULL; + + // + pvConditions.Clean(); + chmConditions.Clean(); + chhkConditions.Clean(); + chtdConditions.Clean(); + chcheConditions.Clean(); + chstrConditions.Clean(); + chvlmConditions.Clean(); + } + + // + // Validate ... + bool IsValid() + { + // + bool result = false; + + // + result = + // + IsValid(time) && + IsValid(symbol) && + IsValid(period) + // + ; + + // + return result; + } + + // + // Generate Provided Scores ... + void GenerateScore( + double &bullishScore, + double &bearishScore // + ) + { + // + bullishScore = 0; + bearishScore = 0; + + // + if (!IsValid()) + { + return; + } + + // + double bullScore = 0; + double bearScore = 0; + + // + // XPV ... + pvConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHM ... + chmConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHHK ... + chhkConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHTD ... + chtdConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHCHE ... + chcheConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHSTR ... + chstrConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + + // + // XCHVLM ... + chvlmConditions.GenerateScore( + bullScore, + bearScore // + ); + bullishScore += bullScore; + bearishScore += bearScore; + } + + // + // Generate Summary ... + string GenerateSummary( + bool onlyCommons = false, + bool onlyConditions = false, + bool includeScores = true, + bool ignoreFalseConditions = true, + string separator = "\n" // + ) + { + // + string result = NULL; + + // + double bullishScore = 0; + double bearishScore = 0; + GenerateScore( + bullishScore, + bearishScore // + ); + + // + string commonStr = GenerateSpecifiedCommonSummary( + this, + separator, + includeScores, + true // + ); + + // + // XPV ... + string pvStr = pvConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHM ... + string chmStr = chmConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHHK ... + string chhkStr = chhkConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHTD ... + string chtdStr = chtdConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHCHE ... + string chcheStr = chcheConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHSTR ... + string chstrStr = chstrConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + // XCHVLM ... + string chvlmStr = chvlmConditions.GenerateSummary( + false, + true, + false, + ignoreFalseConditions // + ); + + // + string conditionsStr = + // + pvStr + separator + + chmStr + separator + + chhkStr + separator + + chtdStr + separator + + chcheStr + separator + + chstrStr + separator + + chvlmStr + separator + + "" + // + ; + + // + result = + // + "[" + GetTag() + "]" + separator + + "----------" + separator + + (onlyConditions + ? "" + : commonStr) + + " " + separator + + (onlyCommons + ? "" + : conditionsStr) + + "" + // + ; + + // + return result; + } + + // + string GetTag() + { + return XCHStartegyToken; + } + + // +}; + +// +typedef void (*TOnXCHSignal)( + XSignal &signal, + XCHStrategyConditions &conditions // +); // // XStrategy Class Implementation(s) ... -class XSCXCHKMStrategy : public XSCBaseStrategy +class XSCXCHStrategy : public XSCBaseStrategy { // // Public ... public: // // Constructor(s) ... - void XSCXCHKMStrategy( + void XSCXCHStrategy( // // Base ... string _symbol, // Trading Symbol @@ -99,7 +399,7 @@ public: // // Deconstructor ... - void ~XSCXCHKMStrategy() + void ~XSCXCHStrategy() { // delete pvHelper; @@ -162,6 +462,20 @@ public: mEnableXCHSTR = value; } + // + // Event Handlers ... + + // + // On Signal Handlers ... + void AddXCHSignalEventHandler(TOnXCHSignal handler) + { + // + Add( + handler, + mOnXCHSignalEventHandlers // + ); + } + // // Overrides ... @@ -169,7 +483,7 @@ public: // Customize Strategy Identifier ... string GetTag() override { - return XCHKMStartegyToken; + return XCHStartegyToken; } // @@ -228,6 +542,15 @@ public: return result; } + // + // XCHTD ... + XCHTDConditions chtdConditions; + result = chtdHelper.GetConditions(chtdConditions); + if (!result) + { + return result; + } + // // XCHSTR ... XCHSTRConditions chstrConditions; @@ -246,6 +569,15 @@ public: return result; } + // + // XCHVLM ... + XCHVLMConditions chvlmConditions; + result = chvlmHelper.GetConditions(chvlmConditions); + if (!result) + { + return result; + } + // // Start Calculations ... @@ -382,6 +714,13 @@ public: double chhkMaxBullishLow = chhkHelper.GetMaxBullishLow(cIndex); double chhkMinBullishLow = chhkHelper.GetMinBullishLow(cIndex); + // + // XCHTD ... + + // + double chtdBullishPower = chtdHelper.GetBullishPower(cIndex); + double chtdBearishPower = chtdHelper.GetBearishPower(cIndex); + // // XCHSTR ... @@ -408,6 +747,50 @@ public: double chcheMaxBearish = chcheHelper.GetBearishMax(cIndex); double chcheMinBearish = chcheHelper.GetBearishMin(cIndex); + // + // Change XCHCHE Current State ... + if (chcheConditions.cLE1[pIndex] > 0 && + chcheConditions.cLE2[pIndex] > 0 && + chcheConditions.cLE1[pIndex] != EMPTY_VALUE && + chcheConditions.cLE2[pIndex] != EMPTY_VALUE && + !chcheConditions.isCStrongBullish) + { + // + chcheCLastLongExitTime = pBar.time; + chcheCLastLongExit1 = chcheConditions.cLE1[pIndex]; + chcheCLastLongExit2 = chcheConditions.cLE2[pIndex]; + } + + // + if (chcheConditions.cSE1[pIndex] > 0 && + chcheConditions.cSE2[pIndex] > 0 && + chcheConditions.cSE1[pIndex] != EMPTY_VALUE && + chcheConditions.cSE2[pIndex] != EMPTY_VALUE && + !chcheConditions.isCStrongBearish) + { + // + chcheCLastShortExitTime = pBar.time; + chcheCLastShortExit1 = chcheConditions.cSE1[pIndex]; + chcheCLastShortExit2 = chcheConditions.cSE2[pIndex]; + } + + // + double chcheMinCBullish = chcheHelper.GetCycleBullishMin( + cIndex, + X_MARKET_CYCLE_UNKNOWN // Current ... + ); + double chcheMaxCBearish = chcheHelper.GetCycleBearishMax( + cIndex, + X_MARKET_CYCLE_UNKNOWN // Current ... + ); + + // + // XCHVLM ... + + // + double chvlmBullishPower = chvlmHelper.GetBullishPower(cIndex); + double chvlmBearishPower = chvlmHelper.GetBearishPower(cIndex); + // DetectImportantAreas(); @@ -657,19 +1040,20 @@ public: if (mEnableXCHCHE) { // - if (chcheConditions.isBullishPowerUp) + if (chcheConditions.isCStrongBullish) { // bool chcheHasLong = // hasBullishPower && + HasCHCHECLast() && cBar.IsBullish() && - cBar.low > chcheMinBullish && - chcheConditions.isBullishPowerUp && - chcheConditions.isCStrongBearish && - (chmConditions.hasBullishPower || - chhkConditions.hasBullishPower || - chstrConditions.hasBullishPower) + chcheMinCBullish > 0 && + hasBullishPattern && + hasBullishPressure && + chcheConditions.hasBullishPower && + chcheConditions.isCStrongBullish && + chcheMinCBullish > GetMaxCHCHECLast() // ; @@ -695,19 +1079,20 @@ public: } // - if (chcheConditions.isBearishPowerUp) + if (chcheConditions.isCStrongBearish) { // bool chcheHasShort = // hasBearishPower && + HasCHCHECLast() && cBar.IsBearish() && - cBar.high < chcheMaxBearish && - chcheConditions.isBearishPowerUp && + chcheMaxCBearish > 0 && + hasBearishPattern && + hasBearishPressure && + chcheConditions.hasBearishPower && chcheConditions.isCStrongBearish && - (chmConditions.hasBearishPower || - chhkConditions.hasBearishPower || - chstrConditions.hasBearishPower) + chcheMaxCBearish > GetMaxCHCHECLast() // ; @@ -852,12 +1237,49 @@ protected: XCHVLMInputs chvlmInputs; XSCXCHVLMHelper *chvlmHelper; + // + // // Private ... private: // // Props ... + // + // On XCH Signal Recieved Event Handler(s) ... + TOnXCHSignal mOnXCHSignalEventHandlers[]; + + // + // Notified Signal Event Handler(s) ... + void NotifyOnXCHSignalEventHandlers( + XSignal &signal, + XCHStrategyConditions &conditions // + ) + { + // + if (!signal.IsValid() || !conditions.IsValid()) + { + return; + } + + // + int count = ArraySize(mOnXCHSignalEventHandlers); + if (!IsValidSize(count)) + { + return; + } + + // + for (int i = 0; i < count; i++) + { + // + mOnXCHSignalEventHandlers[i]( + signal, + conditions // + ); + } + } + // // Install all Helpers and Prepare all // Configurations for required Indicators ... @@ -1146,6 +1568,114 @@ private: } // + // XCHE Custom Data ... + + // + double chcheCLastLongExit1; + double chcheCLastLongExit2; + datetime chcheCLastLongExitTime; + double GetMaxCHCHECLastLong() + { + // + return MathMax( + chcheCLastLongExit1, + chcheCLastLongExit2 // + ); + } + double GetMinCHCHECLastLong() + { + // + return MathMin( + chcheCLastLongExit1, + chcheCLastLongExit2 // + ); + } + + // + double chcheCLastShortExit1; + double chcheCLastShortExit2; + datetime chcheCLastShortExitTime; + double GetMaxCHCHECLastShort() + { + // + return MathMax( + chcheCLastShortExit1, + chcheCLastShortExit2 // + ); + } + double GetMinCHCHECLastShort() + { + // + return MathMin( + chcheCLastShortExit1, + chcheCLastShortExit2 // + ); + } + + // + double GetMaxCHCHECLast() + { + // + return MathMax( + GetMaxCHCHECLastLong(), + GetMaxCHCHECLastShort() // + ); + } + double GetMinCHCHECLast() + { + // + return MathMin( + GetMinCHCHECLastLong(), + GetMinCHCHECLastShort() // + ); + } + + // + bool HasCHCHECLast() + { + // + bool result = false; + + // + result = + IsValid(chcheCLastLongExitTime) || + IsValid(chcheCLastShortExitTime); + + // + return result; + } + + // +}; + +// +// Conditions Parser ... +struct XCHStartegyConditionsParser +{ + // + string _version; + + // + bool IsFiltered( + XSignal &signal, // Provided Signal + XCHStrategyConditions &conditions // Market Conditions + ) + { + // + bool result = false; + + // + // Validate Args ... + if (!signal.IsValid() || !conditions.IsValid()) + { + // + result = true; + return result; + } + + // + return result; + } }; // \ No newline at end of file