/////////////////////////////////////////////////////// // // SaherElm IT Center X5121EA MQL5 Expert Advisor // ------------------------------------------------- // Name: X5121EA and X121EA // Description: an Exper Advisor which used RSI and MA // 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 X5121EA" #property strict // #define ShortName "X5121EA" // #include "../Classes/x-saherelm.xalert.class.mq5" #include "../Classes/x-saherelm.xtrade.class.mq5" #include "../Classes/x-saherelm.x5.provider.class.mq5" #include "../Classes/x-saherelm.x121.provider.class.mq5" // // a Provider Descriptor which holds // X5 and X121 Provider at the Same time ... struct X5121ProviderDescriptor { // string symbol; // Trading Symbol ENUM_TIMEFRAMES period; // Trading Timeframe bool allowLong; // Allow Long Signals bool allowShort; // Allow Short Signals ENUM_X5_SIGNAL_PROVIDERS signallers[]; // Allowed Signal Providers // X5ProviderInputs x5Inputs; XSCX5Provider *x5Provider; // X121ProviderInputs x121Inputs; XSCX121Provider *x121Provider; // XSignal signal; X5MarketConditions x5Conditions; X121MarketConditions x121Conditions; // // Tools ... // // Initial Provider ... // bool Init() { // bool result = false; // result = this.Init( this.symbol, this.period, this.signallers, this.allowLong, this.allowShort // ); // return result; } // bool Init( ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals bool mAllowShort = true // Allow Short Signals ) { // bool result = false; // result = this.Init( this.symbol, this.period, mSignallers, mAllowLong, mAllowShort // ); // return result; } // bool Init( string mSymbol, // Trading Symbol ENUM_TIMEFRAMES mPeriod, // Trading Timeframe ENUM_X5_SIGNAL_PROVIDERS &mSignallers[], // Allowed Signal Providers bool mAllowLong = true, // Allow Long Signals bool mAllowShort = true // Allow Short Signals ) { // bool result = false; // result = // x5Inputs.IsValid() && IsValid(mSymbol) && IsValid(mPeriod) && (allowLong || allowShort) && ArraySize(mSignallers) > 0 // ; if (!result) { return result; } // this.symbol = mSymbol; this.period = mPeriod; this.allowLong = mAllowLong; this.allowShort = mAllowShort; // ENUM_X5_SIGNAL_PROVIDERS tmp[]; Copy( mSignallers, tmp // ); Copy( tmp, this.signallers // ); // // Instantiate Provider ... x5Provider = new XSCX5Provider( this.symbol, this.period // ); // // Instantiate Provider ... x121Provider = new XSCX121Provider( this.symbol, this.period // ); // // Set Long/Short State ... // x5Provider .SetSignalTypeState( POSITION_TYPE_BUY, this.allowLong // ); // x5Provider .SetSignalTypeState( POSITION_TYPE_SELL, this.allowShort // ); // x121Provider .SetSignalTypeState( POSITION_TYPE_BUY, this.allowLong // ); // x121Provider .SetSignalTypeState( POSITION_TYPE_SELL, this.allowShort // ); // // Enable Required Signallers ... x5Provider .SetSignalProviderStates( this.signallers, true // ); // // Now Must to Initialize Provider ... result = x5Provider.Init( this.x5Inputs // ); if (!result) { return result; } // result = x121Provider.Init( this.x121Inputs // ); // return result; } // // Cleanup ... void Clean() { // signal.Clean(); x5Conditions.Clear(); x121Conditions.Clear(); } // // Validate ... bool IsValid(bool validateInputs = true) { // bool result = false; // result = // IsValid(symbol) && IsValid(period) && (validateInputs ? x5Inputs.IsValid() && x121Inputs.IsValid() : true) && (allowLong || allowShort) && ArraySize(signallers) > 0 // ; // return result; } // // Check Signal ... bool HasSignal(int barIndex = 0) { // bool result = false; // result = x5Inputs.IsValid(); if (!result) { return result; } // result = x121Inputs.IsValid(); if (!result) { return result; } // // Clear Signal and Conditions ... Clean(); // result = x5Provider .HasSignal( barIndex, signal, x5Conditions // ); // if (result) { // x121Provider .GetMarketConditions( x121Conditions, barIndex // ); } // return result; } // void GenerateScore( double &bullishScore, double &bearishScore // ) { // double x5BullishScore = 5; double x5BearishScore = 5; // GenerateX5Score( x5BullishScore, x5BearishScore // ); // double x121BullishScore = 5; double x121BearishScore = 5; // GenerateX121Score( x121BullishScore, x121BearishScore // ); // bullishScore = x5BullishScore + x121BullishScore; bearishScore = x5BearishScore + x121BearishScore; } // void GenerateX5Score( double &bullishScore, double &bearishScore // ) { // x5Conditions.GenerateScore( bullishScore, bearishScore // ); } // void GenerateX121Score( double &bullishScore, double &bearishScore // ) { // x121Conditions.GenerateScore( bullishScore, bearishScore // ); } // string GenerateSummary( const bool onlySummary = false, bool ignoreFalseConditions = true // ) { // string x5Str = GenerateX5Summary( onlySummary, ignoreFalseConditions // ); // string x121Str = GenerateX121Summary( onlySummary, ignoreFalseConditions // ); // string result = // x5Str + "\n" + x121Str // ; // return result; } // string GenerateX5Summary( const bool onlySummary = false, bool ignoreFalseConditions = true // ) { return x5Conditions.GenerateSummary( onlySummary, 1, "\n", ignoreFalseConditions // ); } // string GenerateX121Summary( const bool onlySummary = false, bool ignoreFalseConditions = true // ) { return x121Conditions.GenerateSummary( onlySummary, 1, 1.1, 1.2, 1.6, 1.8, "\n", NULL, ignoreFalseConditions // ); } }; // // "EURUSDb,USDCHFb,USDJPYb,XAUUSDb" // // Inputs ... long x5121EAMagicNumber = 78692110; // Magic Number int x5121EASlippage = 10; // Slippgae string x5121EASymbols = "EURUSDb"; // Symbols // bool x5121EAAllowLong = true; // Allow Long Trades bool x5121EAAllowShort = true; // Allow Short Trades int x5121EAManageInterval = 5; // Manager Check Intervals Seconds int x5121EAMaxAllowedPositions = 15; // Max Allowed Positions double x5121EAMaxAllowedSpread = 0; // Max Allowed Spred for Opening Trades double x5121EAMinProfitPerTrade = 0; // Min Profit Per Trade based On Volume Factor (Hedge) double x5121EAMinProfitPerVolumeFactor = 0; // Min Volume Factor for Calculating Profit (Hedge) double x5121EAMaxAllowedDrawdownFactor = 0; // Max Allowed Drawdown Factor // double x5121EAVolume = 0.01; // bool x5121EAEnableAlerts = true; // Enable Alerts bool x5121EALogAlerts = true; // Log Alerts bool x5121EATerminalAlerts = false; // Terminal Alerts bool x5121EAMailAlerts = false; // Mail Alerts bool x5121EAPushAlerts = false; // Push Alerts // // Vars ... string x5121EASymbol; ENUM_TIMEFRAMES x5121EAPeriod; // MqlTick x5121EATick; // // Trade Class Instance ... XSCTrade *x5121EATrader; XSCAlert *x5121EAAlert; // // Providers ... X5121ProviderDescriptor x5121EAProviders[]; // // Event Handlers ... // // Initialization ... int OnInit() { // if (x5121EASymbol == NULL || StringLen(x5121EASymbol) <= 0) { x5121EASymbol = _Symbol; } // if (x5121EAPeriod == NULL) { x5121EAPeriod = _Period; } // // Validate Inputs ... if (!X5121EAValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // // Initial EA ... if (!InitialEA()) { return INIT_PARAMETERS_INCORRECT; } // // TesterHideIndicators(true); // // 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 // // De Initialize X5121EA Providers ... } // // On Tick Handler ... void OnTick() { // // Reading Tick ... if (!SymbolInfoTick(x5121EASymbol, x5121EATick)) { return; } // // Draw ... HandleOnDraw(); // // Check Trade Events ... XOnTradeHandlerState tState; x5121EATrader.HandleOnTradeEvent(tState); // // First Check For Any Guard Actions ... // then Handle Guards if Provided ... XGuard guards[]; bool hasGuard = CheckForGuard(guards); if (hasGuard) { // // TODO: Complete this ... // DoGuards(guards); } // // Second Check for Position Management or Equity Management // Actions like Supports or etc ... bool isIgnored = HandleStateManagement(); if (isIgnored) { return; } // // Second Check For Signals ... // then Execute Signals if Provided ... XSignal signals[]; int signalsCount = RequestForSignal(signals); if (signalsCount <= 0) { return; } // // Execute Signals ... HandleSignalsExecution(signals); } // // Custom Functions ... // // Validate Variables nd Inputs ... bool X5121EAValidateInputs() { // bool result = false; // result = // x5121EASlippage > 0 && x5121EAMagicNumber > 0 // ; // return result; } // // Initialize Specific Providers ... bool InitialEA() { // bool result = false; // // Here We Have to Initial 4 instance of X5Provider ... // - EURUSD/M5; // - USDCHF/M5; // - USDJPY/M5; // - XAUUSD/M5; // result = IsValid(x5121EASymbols); if (!result) { return result; } // string symbols[]; int symbolsCount = SplitContent( symbols, x5121EASymbols); result = symbolsCount > 0; if (!result) { return result; } // // Instance XSCTrade Class ... x5121EATrader = new XSCTrade( x5121EASlippage, x5121EAMagicNumber, x5121EAManageInterval, x5121EAMaxAllowedSpread, x5121EAMaxAllowedPositions, x5121EAMaxAllowedDrawdownFactor // ); // // Instantiate Alert Class ... x5121EAAlert = new XSCAlert( "X5121EA", x5121EAEnableAlerts, x5121EALogAlerts, x5121EATerminalAlerts, x5121EAMailAlerts, x5121EAPushAlerts // ); // // Define Signallers ... ENUM_X5_SIGNAL_PROVIDERS signallers[]; GetAllX5SignalProviders(signallers); // Clean(x5121EAProviders); // // Prepare Providers and Add them into mX5121EA class ... for (int i = 0; i < symbolsCount; i++) { // // Define Structure ... X5121ProviderDescriptor iDescriptor; // iDescriptor.symbol = symbols[i]; iDescriptor.period = PERIOD_M5; iDescriptor.allowLong = x5121EAAllowLong; iDescriptor.allowShort = x5121EAAllowShort; Copy( signallers, iDescriptor.signallers); // // Set Inputs to Default ... iDescriptor.x5Inputs.Default(); iDescriptor.x121Inputs.Default(); // // X121 Inputs ... // // Prepare Input Requirements ... // // XMC ... iDescriptor.x121Inputs.mcInputs.showFastMa = false; iDescriptor.x121Inputs.mcInputs.showSlowMa = false; iDescriptor.x121Inputs.mcInputs.showVerifierMa = false; // // XICH ... iDescriptor.x121Inputs.ichInputs.showKumo = false; iDescriptor.x121Inputs.ichInputs.showKijunSen = false; iDescriptor.x121Inputs.ichInputs.showTenkanSen = false; iDescriptor.x121Inputs.ichInputs.showChikouSpan = false; iDescriptor.x121Inputs.ichInputs.showSenkouSpanA = false; iDescriptor.x121Inputs.ichInputs.showSenkouSpanB = false; iDescriptor.x121Inputs.ichInputs.showKijunSenPlus = false; iDescriptor.x121Inputs.ichInputs.showKijunSenNegative = false; // // XSTR ... iDescriptor.x121Inputs.cheInputs.showLongExit1Line = false; iDescriptor.x121Inputs.cheInputs.showShortExit1Line = false; iDescriptor.x121Inputs.cheInputs.showLongExit2Line = false; iDescriptor.x121Inputs.cheInputs.showShortExit2Line = false; // // XPV ... iDescriptor.x121Inputs.pvInputs.showPeaksAndVales = true; iDescriptor.x121Inputs.pvInputs.showLevels = false; iDescriptor.x121Inputs.pvInputs.showConsolidations = false; iDescriptor.x121Inputs.pvInputs.showFibo1Levels = false; iDescriptor.x121Inputs.pvInputs.showFibo2Levels = false; iDescriptor.x121Inputs.pvInputs.showFibo3Levels = true; iDescriptor.x121Inputs.pvInputs.showFibo4Levels = false; iDescriptor.x121Inputs.pvInputs.showFibo5Levels = false; // // XZG ... iDescriptor.x121Inputs.zgInputs.showZigZag = false; iDescriptor.x121Inputs.zgInputs.showPeaksAndVales = false; // // XDON ... iDescriptor.x121Inputs.donInputs.showOpen = true; iDescriptor.x121Inputs.donInputs.showHigh = true; iDescriptor.x121Inputs.donInputs.showClose = true; iDescriptor.x121Inputs.donInputs.showLow = true; // // XSTR ... iDescriptor.x121Inputs.strInputs.showTrends = true; iDescriptor.x121Inputs.strInputs.fillTrends = false; // iDescriptor.x121Inputs.symbol = iDescriptor.symbol; iDescriptor.x121Inputs.period = iDescriptor.period; // // Short MArket ... iDescriptor.x121Inputs.sMarketPeriod = NULL; iDescriptor.x121Inputs.sMarketMethod = X_PERIOD_AUTO; // // Medium Market ... iDescriptor.x121Inputs.mMarketPeriod = NULL; iDescriptor.x121Inputs.mMarketMethod = X_PERIOD_AUTO; // // Long Market ... iDescriptor.x121Inputs.lMarketPeriod = NULL; iDescriptor.x121Inputs.lMarketMethod = X_PERIOD_AUTO; // int fontSize = 12; double fontAngel = 90; string fontName = "Arial"; ENUM_ANCHOR_POINT fontAnchor = ANCHOR_LEFT_UPPER; // // Hind Market ... iDescriptor.x121Inputs.hMarketPeriod = NULL; iDescriptor.x121Inputs.hMarketMethod = X_PERIOD_AUTO; iDescriptor.x121Inputs.hMarketInputs.drawLabels = false; iDescriptor.x121Inputs.hMarketInputs.drawCBar = true; iDescriptor.x121Inputs.hMarketInputs.drawPBar = true; iDescriptor.x121Inputs.hMarketInputs.drawCBarMid = true; iDescriptor.x121Inputs.hMarketInputs.drawPBarMid = true; iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.Default(); iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.Default(); // iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.openStyle.Label( "C Hind Open", iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.openStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.highStyle.Label( "C Hind High", iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.highStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.closeStyle.Label( "C Hind Close", iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.closeStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.lowStyle.Label( "C Hind Low", iDescriptor.x121Inputs.hMarketInputs.cBarDrawSpecs.lowStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); // iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.openStyle.Label( "P Hind Open", iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.openStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.highStyle.Label( "P Hind High", iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.highStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.closeStyle.Label( "P Hind Close", iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.closeStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.lowStyle.Label( "P Hind Low", iDescriptor.x121Inputs.hMarketInputs.pBarDrawSpecs.lowStyle.clr, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.cBarMidDrawSpecs.clr = clrYellow; iDescriptor.x121Inputs.hMarketInputs.cBarMidDrawSpecs.Label( "C Hind Mid", clrYellow, fontName, fontSize, fontAnchor, fontAngel // ); iDescriptor.x121Inputs.hMarketInputs.pBarMidDrawSpecs.clr = clrYellow; iDescriptor.x121Inputs.hMarketInputs.pBarMidDrawSpecs.Label( "P Hind Mid", clrYellow, fontName, fontSize, fontAnchor, fontAngel // ); // // Validate Inputs ... bool isX5InputsValid = iDescriptor.x5Inputs.IsValid(); if (!isX5InputsValid) { break; } // // Init X121 Inputs ... bool isX121InputsInit = iDescriptor.x121Inputs.Init(); if (!isX121InputsInit) { break; } // // Initialize ... // bool isDescriptorInitialized = iDescriptor.Init(); if (!isDescriptorInitialized) { break; } // AddRef( iDescriptor, x5121EAProviders // ); // } // result = ArraySize(x5121EAProviders) == symbolsCount; // return result; } // void HandleOnDraw() {} // bool HandleStateManagement() { return false; } // bool CheckForGuard(XGuard &guards[]) { return false; } // int RequestForSignal( XSignal &signals[] // Holds Signals ... ) { // int result = 0; // Clean(signals); // int descriptorsCount = ArraySize(x5121EAProviders); if (descriptorsCount <= 0) { return result; } // for (int i = 0; i < descriptorsCount; i++) { // X5121ProviderDescriptor iDescriptor = x5121EAProviders[i]; // iDescriptor.x5Provider.GetMarketConditions( iDescriptor.x5Conditions // ); // iDescriptor.x121Provider.GetMarketConditions( iDescriptor.x121Conditions // ); // X5MarketConditions x5Conditions = iDescriptor.x5Conditions; X121MarketConditions x121Conditions = iDescriptor.x121Conditions; // // Check For Long ... bool hasLong = // (x121Conditions.hMarketConditions.isTrendSwitchedToBullish && (x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) // || // (x121Conditions.lMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) // || // (x121Conditions.mMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) // || // (x121Conditions.sMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.cMarketConditions.isTrendBullish)) // || // (x121Conditions.cMarketConditions.isTrendSwitchedToBullish && (x121Conditions.hMarketConditions.isTrendBullish && x121Conditions.lMarketConditions.isTrendBullish && x121Conditions.mMarketConditions.isTrendBullish && x121Conditions.sMarketConditions.isTrendBullish)) // ; // // Check For Short ... bool hasShort = // false // ; if (hasLong) { Print(""); } // // bool iHasSignal = iDescriptor.HasSignal(0); // if (iHasSignal) // { // // // AddRef( // iDescriptor.signal, // signals // // ); // // // // // string conditionsStr = iDescriptor.GenerateSummary(); // // Print(conditionsStr); // // // double bullScore = 0; // double bearScore = 0; // iDescriptor.GenerateScore( // bullScore, // bearScore // // ); // // // Print(" "); // Print((IsLong(iDescriptor.signal.type) ? "Long" : "Short")); // Print(iDescriptor.signal.symbol, ",", ToString(iDescriptor.signal.period), ",", iDescriptor.signal.provider); // Print("========================"); // Print("bullScore: ", bullScore); // Print("bearScore: ", bearScore); // // // Print(""); // // // Print(iDescriptor.GenerateX121Summary()); // } } // result = ArraySize(signals); // return result; } // void HandleSignalsExecution(XSignal &signals[]) { // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return; } // // Filter Signals Based on their Types ... XSignal filteredSignals[]; // // Try to Filter Signals ... for (int i = 0; i < signalsCount; i++) { // XSignal iSignal = signals[i]; // bool isLong = IsLong(iSignal.type); // if ((isLong && !x5121EAAllowLong) || (!isLong && !x5121EAAllowShort)) { continue; } // AddRef( iSignal, filteredSignals // ); } // int filteredSignalsCount = ArraySize(filteredSignals); if (filteredSignalsCount <= 0) { return; } // // Try to Execute Signals ... ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; int executedSignalsCount = x5121EATrader.ExecuteSignals( filteredSignals, reasons // ); // string message = NULL; if (executedSignalsCount == 0) { // message = "(" + ToString(filteredSignalsCount) + ") Signals Execution Failed ..."; // for (int j = 0; j < ArraySize(reasons); j++) { // string iReason = ToString(reasons[j]); // // ToString(GetSpread(filteredSignals[j].symbol)) + "," message += "\n" + ToString(j) + ": " + iReason; } } else if (executedSignalsCount < filteredSignalsCount) { // int diff = filteredSignalsCount - executedSignalsCount; // message = "Failed to Execute (" + ToString(diff) + ") Signals ..."; } else if (executedSignalsCount == filteredSignalsCount) { message = "(" + ToString(executedSignalsCount) + ") Signals Executed Successfully ..."; } // if (IsValid(message)) { x5121EAAlert.Alert(message); } } //