/////////////////////////////////////////////////////// // // SaherElm IT Center XTest MQL5 Expert Advisor // ------------------------------------------------- // Name: X121EA // Description: an Exper Advisor which used to // XCH and XCHCHE Strategy to Analyse Market ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // //////////////////////////////////////////////////////x // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm X121EA" #property strict // #define ShortName "X121EA" // // Imports ... #include "../Classes/x-saherelm.x121.xtrade.handler.class.mq5" #include "../Helpers/x-saherelm.xcc.helper.mq5" #include "../Helpers/x-saherelm.xct.helper.mq5" // #include "../Parsers/x-saherelm.xch.parser.mq5" #include "../Strategies/x-saherelm.xch.strategy.mq5" // #include "../Parsers/x-saherelm.xch.che.parser.mq5" #include "../Strategies/x-saherelm.xch.che.strategy.mq5" // #include "../Classes/XCObjects/x-saherelm.x-panel.class.mq5" // // Inputs ... // // Common ... input group "Common"; input long eaMagicNumber = 78692110; // Magic Number input int eaSlippage = 10; // Slippgae input string eaLogSuffix = ""; // Log Suffix // // Symbols ... input group "Symbols"; input bool eaMultiSymbol = false; // Use Multi Symbol input bool eaUseMaxAllowedTradesPerSymbol = true; // Use Max Allowed Trades Per Symbol input string eaSymbols = "EURUSDb,GBPUSDb,EURGBPb,USDJPYb,EURJPYb,USDCHFb,EURCHFb,AUDUSDb,EURAUDb,NZDUSDb,EURNZDb,USDCADb,EURCADb,XAUUSDb,XAGUSDb,BRENT,DowJones30"; // Trading Symbols // // Risk Management ... input group "Risk Management"; // // Risk Management > Risk / Reward Calculation ... input group "Risk/Reward"; input bool eaIgnoreTP = false; // Ignore TP input bool eaIgnoreSL = false; // Ignore SL input double eaTPPoint = 200; // Static TP Point input double eaSLPoint = 200; // Static SL Point // // Risk Management > Volume Calculation ... input group "Volume"; input bool eaUseDynamicVolume = false; // Use Dynamic Volume input double eaDynamicVolumeStep = 0.01; // Increase Volume Step input double eaDynamicVolumeBalanceFactor = 200; // Balance Factor for Generate Dynamic Volume input double eaVolume = 0.05; // Static Volume // // Risk Management > Trade Management ... input group "Trade Management"; input bool eaAllowLong = true; // Allow Long Positions input bool eaAllowShort = true; // Allow Short Positions input int eaMaxAllowedLongs = 2; // Max Allowed Long Positions input int eaMaxAllowedShorts = 2; // Max Allowed Short Positions input double eaMaxDrawdownPercentForOpenTrades = 3; // Max Drawdown Percent for Open Trades // // Protector ... input group "Protector"; input int eaDelayBarBetweenTwoSameSignal = 5; // Delay Bars Between Two Same Type Signal // // Protector > Hedging Properties ... input group "Hedging"; input bool eaAllowHedge = true; // Allow Hedge Positions input double eaHedgeMinVolumeStep = 0.01; // Minimum Volume Step For Hedge input int eaMinimumOpenPositionsForHEHedge = 2; // Minimum Open Positions For HE Hedge input double eaHedgeHEMinProfitPerVolumeStep = 1; // Minimum Required Profit For HE Hedge Per Volume Step input double eaHedgeBEMinProfitPerVolumeStep = 0.5; // Minimum Required Profit For BE Hedge Per Volume Step // // Protector > In Profit Positions Protecting ... input group "In Profit Positions Protecting"; // // Trail ... input group "Trail"; input bool eaAllowTrail = true; // Allow Trail Stop for Positions input double eaTrailStartDistance = 35; // Specify Trail Start in Point input double eaTrailStep = 10; // Trail Step in Point input bool eaOnlyTrailUnprotected = true; // Only Trail Unprotected Positionss // // Partial Close (In Profit) ... input group "Partial Close"; input double eaPartialCloseInProfitDistance = 0; // Specify Partial Close Profit in Point input double eaPartialCloseInProfitVolume = 0; // Specify Partial Close in Profit Volume // // Protector > In Drawdown Positions Protecting ... input group "In Drawdown Positions Protecting"; // // Protect ... input group "Protect"; input bool eaAllowProtect = true; // Allow Proptecting input int eaProtectionDelay = 300; // Delay Between two Protection in Secconds input int eaMaxAllowedProtection = 1; // Max Allowed Protection input bool eaUseEntryAsProtectionSL = true; // Use Position Entry For SL of Protect input bool eaProtectOnConditions = true; // Do Protection only when Conditions happens input bool eaAllowDirectionProtct = false; // Allow also Directional Protect input double eaProtectionStartDistance = 100; // Protection Start Drawdown in Point input double eaProtectionVolumeMultiplier = 1; // Protection Volume Multiplier // // Partial Close (In Drawdown) ... input group "Partial Close"; input double eaPartialCloseInDrawdownDistance = 0; // Specify Partial Close Drawdown in Point input double eaPartialCloseInDrawdownVolume = 0; // Specify Partial Close in Drawdown Volume // // Alert ... input group "Alert"; input bool eAEnableAlerts = true; // Enable Alerts input bool eALogAlerts = true; // Log Alerts input bool eAMailAlerts = false; // Mail Alerts input bool eAPushAlerts = false; // Push Alerts input bool eATerminalAlerts = false; // Terminal Alerts // // Time Report ... input group "Reports"; input bool eaAlertNewMonths = false; // Alert New Month input bool eaAlertNewWeeks = false; // Alert New Weeks input bool eaAlertNewDays = true; // Alert New Days input bool eaAlertNewHours = false; // Alert New Hours input bool eaAlertRawSignals = false; // Alert Raw Signals input bool eaAlertStrongSignals = false; // Alert Strong Signals // // Variables ... // // Bar Style nad Time Instances ... XSCXCTHelper *mCTHelper; XSCXCCHelper *mCCHelper; // // Registred Strategies ... XSCBaseStrategy *strategies[]; // // Trader Instance Class ... XSCTrade *eaTrader; // // Alert Class ... XSCAlert *eaAlert; // // Time Tracker ... XTimeTracker eaTimeTracker; // // Trade Handler Instance Class ... X121SCTradeHandler *eaTradeHandler; // string mTag = ""; // double eaR2R = 1.5; datetime lastSignalOn = NULL; bool eaUseFixedTPSLPoints = true; // // SIGNALLING GUI ... XCPanel eaSignallingPanel; XCButton eaSignallingBtn; XCButton eaSignallingLongBtn; XCButton eaSignallingShortBtn; bool eaEnableLongs = eaAllowLong && eaMaxAllowedLongs >= 0; bool eaEnableShorts = eaAllowShort && eaMaxAllowedShorts >= 0; // // PROTECTOR GUI ... XCPanel eaProtectorPanel; XCButton eaHedgingBtn; XCButton eaTraillingBtn; XCButton eaProtectingBtn; bool eaEnableHedging = false; bool eaEnableTrailling = false; bool eaEnableProtecting = false; // // VOLUME GUI ... XCPanel eaVolumePanel; XCButton eaDynamicVolumeBtn; XCEdit eaStaticVolumeTb; XCLabel eaStaticVolumeLbl; XCButton eaSetStaticVolumeBtn; XCButton eaResetStaticVolumeBtn; double eaAppliedStaticVolume = eaVolume; bool eEnableDynamicVolumeVolume = eaUseDynamicVolume && eaDynamicVolumeStep > 0 && eaDynamicVolumeBalanceFactor > 0; // // Event Handlers ... // // Initialization ... int OnInit() { // if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // if (!InitEA()) { return INIT_FAILED; } // mTag = !IsValid(eaLogSuffix) ? ShortName : ShortName + "_" + eaLogSuffix; // drawPrefix = mTag; // // EventSetTimer(1); // EventSetMillisecondTimer(100); // if (!InitGUI()) { return INIT_FAILED; } // // Alert Initialization ... string msg = "Initialized Successfully ..."; eaAlert.Alert(msg); // // 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 // DestroyGUI(); // // Alert De Initialization Succeeded ... string msg = "De Initialized Successfully ..."; eaAlert.Alert(msg); // // De Initialize XSampleEA Providers ... delete mCTHelper; delete mCCHelper; // delete eaAlert; delete eaTrader; delete eaTradeHandler; // Clean(strategies); } // // On Tick Handler ... void OnTick() { // UpdateGUI(); HandleTradeState(); HandleTimeReport(); HandleStrategiesOnTick(); } // // Handle On Trade Event ... void OnTrade() { eaTrader.HandleOnTrade(); } // // On Timer ... void OnTimer() { // // HandleTradeState(); // HandleTimeReport(); // HandleStrategiesOnTick(); } // // Chart Event Handler ... void OnChartEvent( const int id, const long &lparam, const double &dparam, const string &sparam // ) { // // Handle Panel Removing ... eaVolumePanel.OnEvent(id, lparam, dparam, sparam); eaProtectorPanel.OnEvent(id, lparam, dparam, sparam); eaSignallingPanel.OnEvent(id, lparam, dparam, sparam); // // Handle OnClick Event ... if (id == CHARTEVENT_OBJECT_CLICK) { HandleOnClickEvent(sparam); } } // // Custom Functions ... // // Validate Inputs ... bool ValidateInputs() { // bool result = false; // string errMessage = ""; // bool isCommonValid = ( // eaSlippage > 0 && eaMagicNumber > 0 // ); if (!isCommonValid) { // errMessage += "common configurations error;" + "\n"; } // bool isSymbolsValid = ( // eaMultiSymbol ? IsValid(eaSymbols) : true // ); if (!isSymbolsValid) { // errMessage += "symbols configurations error;" + "\n"; } // bool isRiskRewardValid = ( // (eaUseFixedTPSLPoints ? eaTPPoint > 0 || eaSLPoint > 0 : eaR2R > 0) && !(eaIgnoreTP && eaIgnoreSL) // ); if (!isRiskRewardValid) { // errMessage += "risk/reward configurations error;" + "\n"; } // bool isVolumeValid = ( // eaUseDynamicVolume ? eaDynamicVolumeStep >= 0.01 && eaDynamicVolumeBalanceFactor > 0 : eaVolume >= 0.01 // ); if (!isVolumeValid) { // errMessage += "volume configurations error;" + "\n"; } // bool isTradeManagementValid = ( // !(!eaAllowLong && !eaAllowShort) && eaMaxAllowedLongs >= 0 && eaMaxAllowedShorts >= 0 // ); if (!isTradeManagementValid) { // errMessage += "trade management configurations error;" + "\n"; } // result = // // Common ... isCommonValid && // // Symbols ... isSymbolsValid && // // Risk/Reward ... isRiskRewardValid && // // Volume ... isVolumeValid && // // Trade Management ... isTradeManagementValid // ; // if (!result) { Print("Errors: \n", errMessage); } // return result; } // // Initialize all Requirements ... bool InitEA() { // bool result = false; // // Bar Timer ... XCTInputs ctInputs; ctInputs.Default(); mCTHelper = new XSCXCTHelper(); result = mCTHelper.Init( _Symbol, _Period, ctInputs // ); if (!result) { return result; } // // Bar Styles ... XCCInputs ccInputs; ccInputs.Default(); mCCHelper = new XSCXCCHelper(); result = mCCHelper.Init( _Symbol, _Period, ccInputs // ); if (!result) { return result; } // // Create Instance of Alert Class ... eaAlert = new XSCAlert(); eaAlert.SetPrefix(mTag); eaAlert.SetLogAlerts(eALogAlerts); eaAlert.SetMailAlerts(eAMailAlerts); eaAlert.SetPushAlerts(eAPushAlerts); eaAlert.SetEnableAlerts(eAEnableAlerts); eaAlert.SetTerminalAlerts(eATerminalAlerts); // // Create Trader Instance ... eaTrader = new XSCTrade( eaSlippage, eaMagicNumber // ); eaTrader.AddOnStopLossEventHandler(OnStopLossTriggered); eaTrader.AddOnTakeProfitEventHandler(OnTakeProfitTriggered); eaTrader.AddOnForceClosePositionEventHandler(OnPositionForceClosed); // // Initialize Trade Handler ... eaTradeHandler = new X121SCTradeHandler(eaTrader); eaTradeHandler.SaveTrades(true); eaTradeHandler.SaveSignals(true); eaTradeHandler.SaveConditions(true); // // Configure Alerts ... eaTradeHandler.SetAlertPrefix(mTag); eaTradeHandler.SetAlertEnableAlerts(eAEnableAlerts); eaTradeHandler.SetAlertLogAlerts(eALogAlerts); eaTradeHandler.SetAlertMailAlerts(eAMailAlerts); eaTradeHandler.SetAlertPushAlerts(eAPushAlerts); eaTradeHandler.SetAlertTerminalAlerts(eATerminalAlerts); // // Configure Trade Management ... eaTradeHandler.AllowLong(eaAllowLong); eaTradeHandler.AllowShort(eaAllowShort); eaTradeHandler.MaxAllowedLongs(eaMaxAllowedLongs); eaTradeHandler.MaxAllowedShorts(eaMaxAllowedShorts); eaTradeHandler.UseMaxAllowedTradesPerSymbol(eaUseMaxAllowedTradesPerSymbol); eaTradeHandler.MaxDrawdownPercentForOpenTrades(eaMaxDrawdownPercentForOpenTrades); // // Configure Position Protector ... // eaTradeHandler.DelayBarBetweenTwoSameSignal(eaDelayBarBetweenTwoSameSignal); // // Configure Hedging ... eaTradeHandler.AllowHedge(eaAllowHedge); eaTradeHandler.HedgeMinVolumeStep(eaHedgeMinVolumeStep); eaTradeHandler.MinimumOpenPositionsForHEHedge(eaMinimumOpenPositionsForHEHedge); eaTradeHandler.HedgeHEMinProfitPerVolumeStep(eaHedgeHEMinProfitPerVolumeStep); eaTradeHandler.HedgeBEMinProfitPerVolumeStep(eaHedgeBEMinProfitPerVolumeStep); // // In Profit Position Protecting ... // // Trail ... eaTradeHandler.AllowTrail(eaAllowTrail); eaTradeHandler.TrailStartDistance(eaTrailStartDistance); eaTradeHandler.TrailStep(eaTrailStep); eaTradeHandler.OnlyTrailUnprotected(eaOnlyTrailUnprotected); // // Partial Close (In Profit) ... eaTradeHandler.PartialCloseInProfitDistance(eaPartialCloseInProfitDistance); eaTradeHandler.PartialCloseInProfitVolume(eaPartialCloseInProfitVolume); // // In Drawdown Positions Protecting ... // // Protect ... eaTradeHandler.AllowProtect(eaAllowProtect); eaTradeHandler.ProtectionDelay(eaProtectionDelay); eaTradeHandler.MaxAllowedProtection(eaMaxAllowedProtection); eaTradeHandler.UseEntryAsProtectionSL(eaUseEntryAsProtectionSL); eaTradeHandler.ProtectOnConditions(eaProtectOnConditions); eaTradeHandler.AllowDirectionProtct(eaAllowDirectionProtct); eaTradeHandler.ProtectionStartDistance(eaProtectionStartDistance); eaTradeHandler.ProtectionVolumeMultiplier(eaProtectionVolumeMultiplier); // // Partial Close (In Profit) ... eaTradeHandler.PartialCloseInDrawdownDistance(eaPartialCloseInDrawdownDistance); eaTradeHandler.PartialCloseInDrawdownVolume(eaPartialCloseInDrawdownVolume); // // Configure Strategies ... // // Single Symbol ... if (!eaMultiSymbol) { // // Register XCH Strategy ... // // Create Class Instance ... XSCXCHStrategy *xchStrategy; xchStrategy = new XSCXCHStrategy( _Symbol, _Period, PERIOD_H1, // Analyzing Period eaVolume, eaR2R, // R2R ... eaSlippage, eaMagicNumber, true, // Ignore Signal Execution eaUseFixedTPSLPoints, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL eaIgnoreTP, eaIgnoreSL, eaAllowLong, eaAllowShort, eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); // // Configuere Strategy ... xchStrategy.EnableXCHM(true); xchStrategy.EnableXCHHK(true); xchStrategy.EnableXCHSTR(true); xchStrategy.EnableXCHCHE(true); xchStrategy.DrawImportantAreas(false); xchStrategy.AddXCHSignalEventHandler(OnSignalRecieved); // // Configure Alerts ... xchStrategy.SetAlertPrefix(mTag); xchStrategy.SetAlertEnableAlerts(eAEnableAlerts); xchStrategy.SetAlertLogAlerts(eALogAlerts); xchStrategy.SetAlertMailAlerts(eAMailAlerts); xchStrategy.SetAlertPushAlerts(eAPushAlerts); xchStrategy.SetAlertTerminalAlerts(eATerminalAlerts); // // Register Strategy ... RegisterStrategy(xchStrategy); // // Register XCHCHE Strategy ... // // Create Class Instance ... XSCXCHCHEStrategy *xchcheStrategy; xchcheStrategy = new XSCXCHCHEStrategy( _Symbol, _Period, PERIOD_H1, // Analyzing Period eaVolume, eaR2R, // R2R ... eaSlippage, eaMagicNumber, true, // Ignore Signal Execution eaUseFixedTPSLPoints, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL eaIgnoreTP, eaIgnoreSL, eaAllowLong, eaAllowShort, eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); // // Configuere Strategy ... xchcheStrategy.DrawImportantAreas(false); xchcheStrategy.AddXCHSignalEventHandler(OnSignalRecieved); // // Configure Alerts ... xchcheStrategy.SetAlertPrefix(mTag); xchcheStrategy.SetAlertEnableAlerts(eAEnableAlerts); xchcheStrategy.SetAlertLogAlerts(eALogAlerts); xchcheStrategy.SetAlertMailAlerts(eAMailAlerts); xchcheStrategy.SetAlertPushAlerts(eAPushAlerts); xchcheStrategy.SetAlertTerminalAlerts(eATerminalAlerts); // // Register Strategy ... RegisterStrategy(xchcheStrategy); } // // Multi Symbol ... else { // // Parse Symbols ... string symbols[]; int symbolsCount = SplitContent( symbols, eaSymbols // ); result = IsValidSize(symbolsCount); if (!result) { return result; } // for (int i = 0; i < symbolsCount; i++) { // // Select Symbol ... string iSymbol = symbols[i]; // // Register XCH Strategy ... // // Create Class Instance ... XSCXCHStrategy *iXCHStrategy; iXCHStrategy = new XSCXCHStrategy( iSymbol, _Period, PERIOD_H1, // Analyzing Period eaVolume, eaR2R, // R2R ... eaSlippage, eaMagicNumber, true, // Ignore Signal Execution eaUseFixedTPSLPoints, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL eaIgnoreTP, eaIgnoreSL, eaAllowLong, eaAllowShort, eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); // // Configuere Strategy ... iXCHStrategy.EnableXCHM(true); iXCHStrategy.EnableXCHHK(true); iXCHStrategy.EnableXCHSTR(true); iXCHStrategy.EnableXCHCHE(true); iXCHStrategy.DrawImportantAreas(false); iXCHStrategy.AddXCHSignalEventHandler(OnSignalRecieved); // // Configure Alerts ... iXCHStrategy.SetAlertPrefix(mTag); iXCHStrategy.SetAlertEnableAlerts(eAEnableAlerts); iXCHStrategy.SetAlertLogAlerts(eALogAlerts); iXCHStrategy.SetAlertMailAlerts(eAMailAlerts); iXCHStrategy.SetAlertPushAlerts(eAPushAlerts); iXCHStrategy.SetAlertTerminalAlerts(eATerminalAlerts); // // Register Strategy ... RegisterStrategy(iXCHStrategy); // // Register XCHCHE Strategy ... // // Create Class Instance ... XSCXCHCHEStrategy *iXCHCHEStrategy; iXCHCHEStrategy = new XSCXCHCHEStrategy( iSymbol, _Period, PERIOD_H1, // Analyzing Period eaVolume, eaR2R, // R2R ... eaSlippage, eaMagicNumber, true, // Ignore Signal Execution eaUseFixedTPSLPoints, // Use TP SL Point false, // Use Max eaTPPoint, // TP eaSLPoint, // SL eaIgnoreTP, eaIgnoreSL, eaAllowLong, eaAllowShort, eaMaxAllowedLongs, // Max Longs eaMaxAllowedShorts // Max Shorts ); // // Configuere Strategy ... iXCHCHEStrategy.DrawImportantAreas(false); iXCHCHEStrategy.AddXCHSignalEventHandler(OnSignalRecieved); // // Configure Alerts ... iXCHCHEStrategy.SetAlertPrefix(mTag); iXCHCHEStrategy.SetAlertEnableAlerts(eAEnableAlerts); iXCHCHEStrategy.SetAlertLogAlerts(eALogAlerts); iXCHCHEStrategy.SetAlertMailAlerts(eAMailAlerts); iXCHCHEStrategy.SetAlertPushAlerts(eAPushAlerts); iXCHCHEStrategy.SetAlertTerminalAlerts(eATerminalAlerts); // // Register Strategy ... RegisterStrategy(iXCHCHEStrategy); } } // return result; } // // Initial GUI ... bool InitGUI() { // bool result = false; // // Initial Signalling GUI ... result = InitSignallingGUI(); if (!result) { return result; } // // Initial Protector GUI ... result = InitProtectorGUI(); if (!result) { return result; } // // Initial Volume GUI ... result = InitVolumeGUI(); if (!result) { return result; } // return result; } // // Update GUi ... void UpdateGUI() { // UpdateVolumeGUI(); UpdateProtectorGUI(); UpdateSignallingGUI(); } // // Destroy GUI ... void DestroyGUI() { // DestroyVolumeGUI(); DestroyProtectorGUI(); DestroySignallingGUI(); } // // HANDLERS ... // // Call All Registered Strategis Tick Handler Functions ... void HandleStrategiesOnTick() { // int count = ArraySize(strategies); if (!IsValidSize(count)) { return; } // for (int i = 0; i < count; i++) { // // Call Tick Handler Function ... strategies[i].HandleTick(); } } // // Manage Trading States ... void HandleTradeState() { // // Implement All Trade States here ... eaTradeHandler.UpdateData(); // // Do Protection Senarios ... eaTradeHandler.HandleProtection(); } // // Time Reporting ... void HandleTimeReport() { // // Monthly Report .... if (eaAlertNewMonths && eaTimeTracker.IsNewMonth()) { // string msg = "New Month ..."; // eaAlert.Alert(msg); } // // Weekly Report .... if (eaAlertNewWeeks && eaTimeTracker.IsNewWeek()) { // string msg = "New Week ..."; // eaAlert.Alert(msg); } // // Daily Report .... if (eaAlertNewDays && eaTimeTracker.IsNewDay()) { // string msg = "New Day ..."; // eaAlert.Alert(msg); } // // Hourly Report .... if (eaAlertNewHours && eaTimeTracker.IsNewHour()) { // string msg = "New Hour ..."; // eaAlert.Alert(msg); } } // // Report Account Balance ... void HandleReportBalance() { // if (!IsRunningOnTestMode()) { return; } // string msg = "Balance: " + ToString(eaTrader.mAccount.GetBalance()); eaAlert.Log(msg); } // // Handle On Click Event for GUI Components ... void HandleOnClickEvent(string name) { // if (!IsValid(name)) { return; } // bool isClicked = false; // // Signalling State Button ... if (name == eaSignallingBtn.Name()) { // isClicked = true; HandleChangeState(); eaSignallingBtn.State(false); } // // Long Signalling State ... else if (name == eaSignallingLongBtn.Name()) { // isClicked = true; HandleChangeLongsState(); eaSignallingLongBtn.State(false); } // // Short Signalling State ... else if (name == eaSignallingShortBtn.Name()) { // isClicked = true; HandleChangeShortsState(); eaSignallingShortBtn.State(false); } // // Hedging State Button ... else if (name == eaHedgingBtn.Name()) { // isClicked = true; HandleChangeHedgingState(); eaHedgingBtn.State(false); } // // Trailling State Button ... else if (name == eaTraillingBtn.Name()) { // isClicked = true; HandleChangeTraillingState(); eaTraillingBtn.State(false); } // // Protecting State Button ... else if (name == eaProtectingBtn.Name()) { // isClicked = true; HandleChangeProtectingState(); eaProtectingBtn.State(false); } // // Dynamic Volume State ... else if (name == eaDynamicVolumeBtn.Name()) { // isClicked = true; HandleChangeDynamicVolumeState(); eaDynamicVolumeBtn.State(false); } // // Change Static Volume ... else if (name == eaSetStaticVolumeBtn.Name()) { // isClicked = true; HandleChangeStaticVolume(); eaSetStaticVolumeBtn.State(false); } // // Reset Static Volume to Default Value ... else if (name == eaResetStaticVolumeBtn.Name()) { // isClicked = true; HandleResetStaticVolume(); eaResetStaticVolumeBtn.State(false); } // if (isClicked) { UpdateGUI(); } } // // SIGNAL EVENT Handlers ... // // All Signals from Strategies Comming Here for Execution or // Analyzing ... void OnSignalRecieved( XSignal &signal, XCHStrategyConditions &conditions // ) { // // Check Signal and Conditions Validations ... // if (!signal.IsValid()) { return; } // if (!conditions.IsValid()) { return; } // bool isLong = IsLong(signal.type); // // Notify When a Raw (Unfiltered) Signal Recieved // if it's Provided ... if (eaAlertRawSignals) { // string msg = "Raw " + (IsLong(signal.type) ? "Long" : "Short") + " Signal Recieved: (" + signal.provider + "," + signal.symbol + "," + ToString(signal.period) + ") ..."; eaAlert.Alert(msg); } // // Apply Volume On Signal ... ApplyVolumeOnSignal(signal); // // Chekc Signalling Enable or not ... bool canContinue = isLong ? eaEnableLongs : eaEnableShorts; if (!canContinue) { return; } // // Since Signal Filtering done based on // Strategy and it's not related to Public // TradeHandler for Seperation of Concern issue, // we do this here ... XCHStartegyConditionsParser chParser; XCHCHEStartegyConditionsParser chcheParser; // bool isXCHSignal = signal.provider == XCHStartegyToken; bool isXCHCHESignal = signal.provider == XCHCHEStartegyToken; bool isFiltered = isXCHSignal ? chParser.IsFiltered( signal, conditions // ) : isXCHCHESignal ? chcheParser.IsFiltered( signal, conditions // ) : true; if (isFiltered) { // eaTradeHandler.RemoveSignal(signal); return; } // // Attach Conditions Summary to Signal ... string conditionsSummary = conditions.GenerateSummary( false, false, true, false // ); // signal.conditions = isXCHSignal ? chParser.GenerateSignalConditions( signal, conditions // ) : isXCHCHESignal ? chcheParser.GenerateSignalConditions( signal, conditions // ) : conditionsSummary; // // Check Signal Delay ... datetime currentTime = TimeCurrent(); int delay = eaDelayBarBetweenTwoSameSignal; bool isDelayPassed = delay <= 0 ? true : !IsValid(lastSignalOn) ? true : MathAbs(TimeToSeconds(currentTime)) - MathAbs(TimeToSeconds(lastSignalOn)) >= ulong(delay * PeriodSeconds(_Period)); if (!isDelayPassed) { return; } // // Execute Signal Using Trade Handler ... ENUM_X_SIGNAL_EXECUTION_RESULT state; bool isExecuted = eaTradeHandler.ExecuteSignal( signal, state // ); // if (isExecuted) { lastSignalOn = currentTime; } } // // Handle StopLoss Triggered Positions ... void OnStopLossTriggered(const XDeal &deal) { // // Finish ... eaTradeHandler.Finish(deal); // HandleReportBalance(); } // // Handle Take Profit Triggered Positions ... void OnTakeProfitTriggered(const XDeal &deal) { // // Finish ... eaTradeHandler.Finish(deal); // HandleReportBalance(); } // // Handle Force Close a Position ... void OnPositionForceClosed( const ulong ticket, const XPosition &position, const string comment // ) { // // Finish ... eaTradeHandler.Finish( ticket, position, comment // ); // HandleReportBalance(); } // // HELPERS ... // // Register Strategy ... void RegisterStrategy(XSCBaseStrategy *strategy) { // if (strategy == NULL) { return; } // ArrayResize( strategies, ArraySize(strategies) + 1 // ); // strategies[ArraySize(strategies) - 1] = strategy; } /** * Apply Volume Based On Configurations on Signal ... * * @param signal: XSignal instance */ void ApplyVolumeOnSignal(XSignal &signal) { // // Prepare Signal Dynamic Volume // if Provided ... if (eEnableDynamicVolumeVolume && eaDynamicVolumeStep > 0 && eaDynamicVolumeBalanceFactor > 0) { // double dVolume = eaTrader.GetDynamicVolume( signal.symbol, eaDynamicVolumeBalanceFactor, eaDynamicVolumeStep // ); // if (dVolume > 0) { signal.volume = dVolume; } else { signal.volume = eaAppliedStaticVolume; } } else { signal.volume = eaAppliedStaticVolume; } // eaTradeHandler.UpdateSignal(signal); } // // GUI Parts ... // // SIGNALLING GUI ... /** * Initialize State and Signalling GUI ... * * @return ( bool ) */ bool InitSignallingGUI() { // bool result = false; // string eaSignallingPanelName = mTag + "SIGNALLING"; // // Create a Panel ... result = eaSignallingPanel.Create( eaSignallingPanelName, 10, 40, 300, 50 // ); if (!result) { return result; } eaSignallingPanel.Caption("Signalling"); // // Create Activation Button ... string eaSignallingPrefix = eaSignallingPanelName + "_"; // // Signalling ... string eaSignallingBtnName = eaSignallingPrefix + "btn"; result = eaSignallingBtn.Create( eaSignallingBtnName, 10, 60, 300, 25 // ); if (!result) { return result; } eaSignallingBtn.Text(""); eaSignallingPanel.Add(eaSignallingBtnName); // // Long Signalling ... string eaSignallingLongBtnName = eaSignallingPrefix + "_Long_btn"; result = eaSignallingLongBtn.Create( eaSignallingLongBtnName, 10, 85, 150, 25 // ); if (!result) { return result; } eaSignallingLongBtn.Text(""); eaSignallingPanel.Add(eaSignallingLongBtnName); // // Short Signalling ... string eaSignallingShortBtnName = eaSignallingPrefix + "_Short_btn"; result = eaSignallingShortBtn.Create( eaSignallingShortBtnName, 160, 85, 150, 25 // ); if (!result) { return result; } eaSignallingShortBtn.Text(""); eaSignallingPanel.Add(eaSignallingShortBtnName); // UpdateSignallingGUI(); // return result; } /** * Update Signalling GUI Content ... */ void UpdateSignallingGUI() { // // Preparing State ... bool isSignallingActive = eaEnableLongs || eaEnableShorts; // // All Signalls ... color mSignallingBtnTextColor = isSignallingActive ? clrRed : clrGreen; string mSignallingBtnText = isSignallingActive ? "Deactive" : "Active"; eaSignallingBtn.Text(mSignallingBtnText); eaSignallingBtn.Color(mSignallingBtnTextColor); // // Long Signals ... color mSignallingLongBtnTextColor = eaEnableLongs ? clrRed : clrGreen; string mSignallingLongBtnText = eaEnableLongs ? "Deactive Longs" : "Active Longs"; eaSignallingLongBtn.Text(mSignallingLongBtnText); eaSignallingLongBtn.Color(mSignallingLongBtnTextColor); // // Short Signals ... color mSignallingShortBtnTextColor = eaEnableShorts ? clrRed : clrGreen; string mSignallingShortBtnText = eaEnableShorts ? "Deactive Shorts" : "Active Shorts"; eaSignallingShortBtn.Text(mSignallingShortBtnText); eaSignallingShortBtn.Color(mSignallingShortBtnTextColor); } /** * Destroy Signalling GUI ... */ void DestroySignallingGUI() { // eaSignallingBtn.Destroy(); eaSignallingLongBtn.Destroy(); eaSignallingShortBtn.Destroy(); // eaSignallingPanel.Destroy(); } /** * Toggle Signalling State ... */ void HandleChangeState() { // // Preparing State ... bool isSignallingActive = eaEnableLongs || eaEnableShorts; // if (isSignallingActive) { // eaEnableLongs = false; eaEnableShorts = false; } else { // eaEnableLongs = true; eaEnableShorts = true; } // UpdateSignallingOnTradeHandler(); } /** * Toggle Longs Signalling ... */ void HandleChangeLongsState() { // eaEnableLongs = !eaEnableLongs; // UpdateSignallingOnTradeHandler(); } /** * Toggle Shorts Signalling ... */ void HandleChangeShortsState() { // eaEnableShorts = !eaEnableShorts; // UpdateSignallingOnTradeHandler(); } /** * Update Signalling Features on Trade Handler ... */ void UpdateSignallingOnTradeHandler() { // eaTradeHandler.AllowLong(eaEnableLongs); eaTradeHandler.AllowShort(eaEnableShorts); // UpdateSignallingGUI(); } // // PROTECTOR GUI ... /** * Initial Protector GUI ... * * @return ( bool ) */ bool InitProtectorGUI() { // bool result = false; // string eaProtectorPanelName = mTag + "PROTECTOR"; // // Create a Panel ... result = eaProtectorPanel.Create( eaProtectorPanelName, 10, 110, 300, 75 // ); if (!result) { return result; } eaProtectorPanel.Caption("Protector"); // string eaProtectorPrefix = eaProtectorPanelName + "_"; // // Hedging ... string eaHedgingBtnName = eaProtectorPrefix + "HEDGING_btn"; result = eaHedgingBtn.Create( eaHedgingBtnName, 10, 130, 300, 25 // ); if (!result) { return result; } eaHedgingBtn.Text(""); eaProtectorPanel.Add(eaHedgingBtnName); // // Trailling ... string eaTraillingBtnName = eaProtectorPrefix + "TRAILLING_btn"; result = eaTraillingBtn.Create( eaTraillingBtnName, 10, 155, 300, 25 // ); if (!result) { return result; } eaTraillingBtn.Text(""); eaProtectorPanel.Add(eaTraillingBtnName); // // Protecting ... string eaProtectingBtnName = eaProtectorPrefix + "FREEZING_btn"; result = eaProtectingBtn.Create( eaProtectingBtnName, 10, 180, 300, 25 // ); if (!result) { return result; } eaProtectingBtn.Text(""); eaProtectorPanel.Add(eaProtectingBtnName); // UpdateProtectorGUI(); // return result; } /** * Update Protector GUI ... */ void UpdateProtectorGUI() { // // Hedging ... // // Checking Hedging Props ... bool isHedgingActiveProps = eaHedgeMinVolumeStep > 0 && ((eaMinimumOpenPositionsForHEHedge > 0 && eaHedgeHEMinProfitPerVolumeStep > 0) || eaHedgeBEMinProfitPerVolumeStep); // // Check Hedging State ... bool isHedgingActived = eaAllowHedge && isHedgingActiveProps; eaEnableHedging = isHedgingActived; // color eaHedgingBtnTextColor = !isHedgingActiveProps ? clrGray : isHedgingActived ? clrRed : clrGreen; string eaHedgingBtnText = !isHedgingActiveProps ? "Hedging Disabled" : isHedgingActived ? "Deactive Hedging" : "Active Hedging"; eaHedgingBtn.Text(eaHedgingBtnText); eaHedgingBtn.Color(eaHedgingBtnTextColor); // // Trailling ... // // Checking Trailling Props ... bool isTraillingActiveProps = eaTrailStep > 0 && eaTrailStartDistance > 0 && eaTrailStep < eaTrailStartDistance; // // Check Trailling State ... bool isTraillingActived = eaAllowTrail && isTraillingActiveProps; eaEnableTrailling = isTraillingActived; // color eaTraillingBtnTextColor = !isTraillingActiveProps ? clrGray : isTraillingActived ? clrRed : clrGreen; string eaTraillingBtnText = !isTraillingActiveProps ? "Trailling Disabled" : isTraillingActived ? "Deactive Trailling" : "Active Trailling"; eaTraillingBtn.Text(eaTraillingBtnText); eaTraillingBtn.Color(eaTraillingBtnTextColor); // // Protecting ... // // Checking Protection Props ... bool isProtectingActiveProps = eaProtectionDelay >= 0 && eaProtectionStartDistance > 0 && eaProtectionVolumeMultiplier > 0; // // Check Protection State ... bool isProtectingActived = eaAllowProtect && isProtectingActiveProps; eaEnableProtecting = isProtectingActived; // color eaProtectingBtnTextColor = !isProtectingActiveProps ? clrGray : isProtectingActived ? clrRed : clrGreen; string eaProtectingBtnText = !isProtectingActiveProps ? "Protecting Disabled" : isProtectingActived ? "Deactive Protecting" : "Active Protecting"; eaProtectingBtn.Text(eaProtectingBtnText); eaProtectingBtn.Color(eaProtectingBtnTextColor); } /** * Destroy Protector GUI ... */ void DestroyProtectorGUI() { // eaHedgingBtn.Destroy(); eaTraillingBtn.Destroy(); eaProtectingBtn.Destroy(); // eaProtectorPanel.Destroy(); } /** * Toggle Hedging State ... */ void HandleChangeHedgingState() { // // Checking Hedging Props ... bool isHedgingActiveProps = eaHedgeMinVolumeStep > 0 && ((eaMinimumOpenPositionsForHEHedge > 0 && eaHedgeHEMinProfitPerVolumeStep > 0) || eaHedgeBEMinProfitPerVolumeStep); // if (!isHedgingActiveProps) { return; } // eaEnableHedging = !eaEnableHedging; // UpdateProtectingOnTradeHandler(); } /** * Toggle Trailling State ... */ void HandleChangeTraillingState() { // // Checking Trailling Props ... bool isTraillingActiveProps = eaTrailStep > 0 && eaTrailStartDistance > 0 && eaTrailStep < eaTrailStartDistance; // if (!isTraillingActiveProps) { return; } // eaEnableTrailling = !eaEnableTrailling; // UpdateProtectingOnTradeHandler(); } /** * Toggle Protecting State ... */ void HandleChangeProtectingState() { // // Checking Protection Props ... bool isProtectingActiveProps = eaProtectionDelay >= 0 && eaProtectionStartDistance > 0 && eaProtectionVolumeMultiplier > 0; // if (!isProtectingActiveProps) { return; } // eaEnableProtecting = !eaEnableProtecting; } /** * Update Protecting Features on Trade Handler ... */ void UpdateProtectingOnTradeHandler() { // eaTradeHandler.AllowHedge(eaEnableHedging); eaTradeHandler.AllowTrail(eaEnableTrailling); eaTradeHandler.AllowProtect(eaEnableProtecting); // UpdateProtectorGUI(); } // // VOLUME GUI ... /** * Initial Volume GUI ... * * @return ( bool ) */ bool InitVolumeGUI() { // bool result = false; // string eaVolumePanelName = mTag + "VOLUME"; // // Create a Panel ... result = eaVolumePanel.Create( eaVolumePanelName, 10, 205, 300, 75 // ); if (!result) { return result; } eaVolumePanel.Caption("Volume"); // string eaVolumePrefix = eaVolumePanelName + "_"; // // Dynamic Volume ... string eaDynamicVolumeBtnName = eaVolumePrefix + "DYNAMIC_VOLUME_btn"; result = eaDynamicVolumeBtn.Create( eaDynamicVolumeBtnName, 10, 225, 300, 25 // ); if (!result) { return result; } eaDynamicVolumeBtn.Text(""); eaVolumePanel.Add(eaDynamicVolumeBtnName); // // Static Volume ... // // Label ... string eaStaticVolumeLblName = eaVolumePrefix + "STATIC_VOLUME_lbl"; result = eaStaticVolumeLbl.Create( eaStaticVolumeLblName, 10, 250 // ); if (!result) { return result; } eaStaticVolumeLbl.FontSize(10); eaStaticVolumeLbl.Color(clrWhite); eaStaticVolumeLbl.Text("Static Volume: "); eaVolumePanel.Add(eaStaticVolumeLblName); // // Text Box ... string eaStaticVolumeTbName = eaVolumePrefix + "STATIC_VOLUME_tb"; result = eaStaticVolumeTb.Create( eaStaticVolumeTbName, 160, 250, 150, 25 // ); if (!result) { return result; } eaStaticVolumeTb.Text(""); eaStaticVolumeTb.FontSize(10); eaStaticVolumeTb.Color(clrBlack); eaStaticVolumeTb.BGColor(clrWhite); eaVolumePanel.Add(eaStaticVolumeTbName); // // Set Static Volume ... string eaSetStaticVolumeBtnName = eaVolumePrefix + "STATIC_VOLUME_SET_btn"; result = eaSetStaticVolumeBtn.Create( eaSetStaticVolumeBtnName, 10, 275, 150, 25 // ); if (!result) { return result; } eaSetStaticVolumeBtn.Text("Set"); eaVolumePanel.Add(eaSetStaticVolumeBtnName); // // Reset Static Volume ... string eaResetStaticVolumeBtnName = eaVolumePrefix + "STATIC_VOLUME_RESET_btn"; result = eaResetStaticVolumeBtn.Create( eaResetStaticVolumeBtnName, 160, 275, 150, 25 // ); if (!result) { return result; } eaResetStaticVolumeBtn.Text("Default"); eaVolumePanel.Add(eaResetStaticVolumeBtnName); // return result; } /** * Update Volume GUI ... */ void UpdateVolumeGUI() { // string tbVolume = eaStaticVolumeTb.Text(); // // Set Current Volume if it's Empty ... if (!IsValid(tbVolume)) { eaStaticVolumeTb.Text(ToString(eaVolume)); } // bool isDefault = ToString(tbVolume) == ToString(eaVolume); bool isCurrent = ToString(tbVolume) == ToString(eaAppliedStaticVolume); // // Set Static Volume Color ... color eaSetStaticVolumeBtnColor = (isDefault || isCurrent) ? clrGray : clrGreen; eaSetStaticVolumeBtn.Color(eaSetStaticVolumeBtnColor); // // Reset Static Volume Color ... color eaResetStaticVolumeBtnColor = isDefault ? clrGray : clrRed; eaResetStaticVolumeBtn.Color(eaResetStaticVolumeBtnColor); // // Dynamic Volume State ... // // Check Required Props ... bool isDynamicVolumeActivedProps = eaDynamicVolumeStep > 0 && eaDynamicVolumeBalanceFactor > 0; // color eaDynamicVolumeBtnColor = !isDynamicVolumeActivedProps ? clrGray : eEnableDynamicVolumeVolume ? clrRed : clrGreen; string eaDynamicVolumeBtnText = !isDynamicVolumeActivedProps ? "Disabled" : eEnableDynamicVolumeVolume ? "Deactive Dynamic Volume" : "Active Dynamic Volume"; eaDynamicVolumeBtn.Text(eaDynamicVolumeBtnText); eaDynamicVolumeBtn.Color(eaDynamicVolumeBtnColor); } /** * Destroy Volume GUI ... */ void DestroyVolumeGUI() { // eaStaticVolumeTb.Destroy(); eaStaticVolumeLbl.Destroy(); eaDynamicVolumeBtn.Destroy(); eaSetStaticVolumeBtn.Destroy(); eaResetStaticVolumeBtn.Destroy(); // eaVolumePanel.Destroy(); } /** * Toggle Dynamic Volume Usage ... */ void HandleChangeDynamicVolumeState() { // // Check Required Props ... bool isDynamicVolumeActivedProps = eaDynamicVolumeStep > 0 && eaDynamicVolumeBalanceFactor > 0; // if (!isDynamicVolumeActivedProps) { return; } // eEnableDynamicVolumeVolume = !eEnableDynamicVolumeVolume; } /** * Change Static Volume ... */ void HandleChangeStaticVolume() { // string tbVolume = eaStaticVolumeTb.Text(); // // Set Current Volume if it's Empty ... if (!IsValid(tbVolume)) { return; } // bool isCurrent = ToString(tbVolume) == ToString(eaAppliedStaticVolume); if (isCurrent) { return; } // eaAppliedStaticVolume = (double)tbVolume; if (eaAppliedStaticVolume <= 0) { eaAppliedStaticVolume = eaVolume; } } /** * Set Default Static Volume Value ... */ void HandleResetStaticVolume() { // string tbVolume = eaStaticVolumeTb.Text(); // // Set Current Volume if it's Empty ... if (!IsValid(tbVolume)) { return; } // bool isDefault = ToString(tbVolume) == ToString(eaVolume); if (isDefault) { return; } // eaStaticVolumeTb.Text(ToString(eaVolume)); } //