/////////////////////////////////////////////////////// // // SaherElm IT Center XST_XMA Strategy Expert Advisor // --------------------------------------------- // saherelm implementation of strategy expert advisor ... // // ShortName: XST_XMA // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XST_XMA Strategy Expert Advisor" #property strict // // START Inputs ... // // // Signal Prefixe ... input string signalPrefix = "XST_XMA"; // Signal Prefix // // Signal Draw Specifications ... input string bullishSignalLabel = "X_BUY"; // Bullish Signal Label input color bullishSignalColor = clrAqua; // Bullish Signal Color // input string bearishSignalLabel = "X_SELL"; // Bearish Signal Label input color bearishSignalColor = clrFuchsia; // Bearish Signal Color // input color signalEntryColor = clrAquamarine; // Signal Entry Ptice Color input color signalSLColor = clrRed; // Signal SL Color input color signalTPColor = clrGreen; // Signal TP Color // // Trade ... input bool allowTrade = true; // Allow Trade Based on given Signals input bool allowLongTrades = true; // Allow Long Trades input bool allowShortTrades = true; // Allow Short Trades // // Alerts ... input bool alertEvents = true; // Alert Events input bool alertPositions = true; // Alert Positions input bool longPositionAlerts = true; // Alert Long Positions input bool shortPositionAlerts = true; // Alert Short Positions // // Alert Types ... input bool terminalAlert = false; // Terminal Alert input bool pushAlert = false; // Push Notification Alerts // // Balance and Finanical Specifications ... input double lotsPerTradePercent = 0.0001; // Lots Per Trade Percent input int maxOpenTrades = 3; // Maximum Open Trade input double maxDrawdownPercentPerPTrade = 0; // Maximum DrawDown Per Trade input double minBalancePercent = 0.5; // Minimum Balance for Trading input double maxEquityPercent = 0.1; // Maximum Trade Equity // // XMA Inputs ... // // Market Specification Inpouts ... input int marketLength = 7; // Market Length input double riskToRewardRatio = 2; // Risk to Reward Ratio // input int shortCycleFastMultiplier = 1; // Short Cycle Fast Multiplier input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier input int mediumCycleFastMultiplier = 7; // Medium Cycle Fast Multiplier input int mediumCycleSlowMultiplier = 14; // Medium Cycle Slow Multiplier input int longCycleFastMultiplier = 70; // Long Cycle Fast Multiplier input int longCycleSlowMultiplier = 140; // Long Cycle Slow Multiplier // // Show/Hide Inputs ... input bool showShortCycle = false; // Show Short Cycle input bool showShortCycleCrossLines = false; // Show Short Cycle Vertical Lines input bool showMediumCycle = false; // Show Medium Cycle input bool showMediumCycleCrossLines = false; // Show Medium Cycle Vertical Lines input bool showLongCycle = false; // Show Long Cycle input bool showLongCycleCrossLines = false; // Show Long Cycle Vertical Lines // // Color Inputs ... input color shortCycleFastColor = clrGreen; // Short Cycle Fast Color ... input color shortCycleSlowColor = clrRed; // Short Cycle Slow Color ... input color mediumCycleFastColor = clrAqua; // Medium Cycle Fast Color ... input color mediumCycleSlowColor = clrFuchsia; // Medium Cycle Slow Color ... input color longCycleFastColor = clrGoldenrod; // Medium Cycle Fast Color ... input color longCycleSlowColor = clrBrown; // Medium Cycle Slow Color ... // // END Inputs ... // // // START Global Definitions: Variables, Properties and etc ... // int totalBars; int countedBars = 0; int lastSignalledBar = 0; // bool waitForLongSignals = true; bool closeLongTrades = false; // bool waitForShortSignals = true; bool closeShortTrades = false; // // Includes our shared library ... #include "../Libraries/x-saherelm.lib.mq4" // // Includes our shared library ... #include "../Libraries/x-saherelm.xma.signal.lib.mq4" // // here we specify logging enabled or not ... bool enableLogging = true; // // this is a Tag which attached to our Logger ... string logTag = "XST_XMA"; // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... bool inputsNotValiid = // // EA ... lotsPerTradePercent < 0 || maxOpenTrades <= 0 || maxDrawdownPercentPerPTrade < 0 || minBalancePercent < 0 || maxEquityPercent < 0 || marketLength < 0 // // XMA ... // // Validate Short Cycle ... || shortCycleFastMultiplier <= 0 || shortCycleSlowMultiplier <= 0 || shortCycleFastMultiplier >= shortCycleSlowMultiplier // // Validate Medium Cycle ... || mediumCycleFastMultiplier <= 0 || mediumCycleSlowMultiplier <= 0 || mediumCycleFastMultiplier >= mediumCycleSlowMultiplier // // Validate Long Cycle ... || longCycleFastMultiplier <= 0 || longCycleSlowMultiplier <= 0 || longCycleFastMultiplier >= longCycleSlowMultiplier // // Validate Series of Multipliers ... || shortCycleFastMultiplier >= mediumCycleFastMultiplier || mediumCycleFastMultiplier >= longCycleFastMultiplier ; // if (inputsNotValiid) { return INIT_PARAMETERS_INCORRECT; } // totalSignals = 0; totalLongSignals = 0; totalShortSignals = 0; // initialBalance = 0; // ArraySetAsSeries( scTrendPower, true ); // ArraySetAsSeries( shortMarketCrossPointsTime, true ); // ArraySetAsSeries( mcTrendPower, true ); // ArraySetAsSeries( mediumMarketCrossPointsTime, true ); // ArraySetAsSeries( lcTrendPower, true ); // ArraySetAsSeries( longMarketCrossPointsTime, true ); // // // // Set Event Timer on One Seccond ... // bool isEventSet = EventSetTimer(1); // if (!isEventSet) { // LogMessage("Error: " + GetLastError()); // return INIT_FAILED; // } // return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // Killing Event Timer ... EventKillTimer(); } // // Ticker Event Handler ... void OnTick() { // // Checking State for Signal Handling ... CheckState(); // // Process Signals to Open Positions ... ProcessSignals(); // // Process Open Positions for Trailing Stop Loss or Close ... // ProcessOpenPositions(); } // // Timer Event Handler ... void OnTimer() { // CheckState(); ProcessOpenPositions(); } // // END Event Handlers ... // // // START Functions ... // // // Check State for Signal Handling ... void CheckState() { // // Here we Must to Check Market State in Big Picture ... // // Check if Medium Cycle Fast cross Short Cycle Slow // Turn off Longs ... // // // if ( // waitForLongSignals // && ( // xmaState.isMCFastCrossUnderSlow || // xmaState.isLCFastCrossUnderSlow // ) // ) { // // // closeLongTrades = true; // waitForLongSignals = false; // // // string msg = "Pause Long Handler ..."; // LogMessage(msg); // SendAlert(msg); // return; // } // // // if ( // !waitForLongSignals // && ( // xmaState.isMCFastCrossOverSlow || // xmaState.isLCFastCrossOverSlow // ) // ) { // // // closeShortTrades = true; // waitForLongSignals = true; // // // string msg = "Play Long Handler ..."; // LogMessage(msg); // SendAlert(msg); // return; // } // // // bool isXMASlowCrossOverXMMALongFast = // xmaState.xmaSlow > xmmaState.longFast // && !( // xmaState.xmaSlowPrev > xmmaState.longFastPrev // ); // // // bool isXMASlowCrossOverXMMALongSlow = // xmaState.xmaSlow > xmmaState.longSlow // && !( // xmaState.xmaSlowPrev > xmmaState.longSlowPrev // ); // // // bool isXMASlowCrossUnderXMMALongFast = // xmaState.xmaSlow < xmmaState.longFast // && !( // xmaState.xmaSlowPrev < xmmaState.longFastPrev // ); // // // bool isXMASlowCrossUnderXMMALongSlow = // xmaState.xmaSlow < xmmaState.longSlow // && !( // xmaState.xmaSlowPrev < xmmaState.longSlowPrev // ); // // // // Find Sharp Dump and Sharp Pump ... // bool isMarketSharpDump = false; // // // bool isMarketSharpPump = false; // // // // // if ( // // waitForLongSignals // // && ( // // isMarketSharpDump || // // isXMASlowCrossOverXMMALongFast // // ) // // ) { // // // // // closeLongTrades = true; // // waitForLongSignals = false; // // // // // string msg = "Pause Long Handler ..."; // // LogMessage(msg); // // SendAlert(msg); // // return; // // } // // // // // if ( // // !waitForLongSignals // // && ( // // isMarketSharpPump || // // isXMASlowCrossOverXMMALongSlow // // ) // // ) { // // // // // closeShortTrades = true; // // waitForLongSignals = true; // // // // // string msg = "Play Long Handler ..."; // // LogMessage(msg); // // SendAlert(msg); // // return; // // } } // // Calculate Signals and Process Based on Exists Signals ... void ProcessSignals() { // // Prevent Multiple Calculating on Same Bars ... if (IsNewBar()) { countedBars++; } // // Retrieve Signal Exists ... XSignalRequest request = CalculateSignal( // // Bar Index ... 0, // // Market Specification Inpouts ... marketLength, // Market Length ... // // Risk To Reward Ratio ... riskToRewardRatio, // // XMA Inputs ... shortCycleFastMultiplier, // Short Cycle Fast Multiplier ... shortCycleSlowMultiplier, // Short Cycle Slow Multiplier ... mediumCycleFastMultiplier, // Medium Cycle Fast Multiplier ... mediumCycleSlowMultiplier, // Medium Cycle Slow Multiplier ... longCycleFastMultiplier, // Long Cycle Fast Multiplier ... longCycleSlowMultiplier, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showShortCycle, showShortCycleCrossLines, showMediumCycle, showMediumCycleCrossLines, showLongCycle, showLongCycleCrossLines, // // Color Inputs ... shortCycleFastColor, shortCycleSlowColor, mediumCycleFastColor, mediumCycleSlowColor, longCycleFastColor, longCycleSlowColor ); // // Prevent doing anything else, if there is no signals ... if ( !request.hasSignal || request.type == X_NONE ) { return; } // bool hasLongSignal = request.type == X_LONG; // // Check For Bot State ... if ( (hasLongSignal && !waitForLongSignals) || (!hasLongSignal && !waitForShortSignals) ) { return; } // // Check last Signalled Bar with Counted Bars ... // Prevent Multiple Signalling on Same Bar ... if (lastSignalledBar == countedBars) { // totalSignals--; if (hasLongSignal) { totalLongSignals--; } else { totalShortSignals--; } return; } // // increase last signalled bar ... lastSignalledBar = countedBars; // // Calculate Can Trade or not ... bool allowDoTrade = allowTrade && ( hasLongSignal ? allowLongTrades : allowShortTrades ); // // Check Balance ... if (initialBalance > 0) { // // Retrieve Account Balance ... double balance = AccountInfoDouble(ACCOUNT_BALANCE); double minimumBalanceForTrade = minBalancePercent * initialBalance; // // Retrieve Account Equity ... double equity = AccountInfoDouble(ACCOUNT_EQUITY); double maxAllowedEquity = balance - (balance * maxEquityPercent); // // Retrieve Free Marigin ... double freeMargin = AccountFreeMargin(); double maximumMariginRisk = balance - (balance * maxEquityPercent); // if ( // // Do not Open Positions if equity not passed ... equity < maxAllowedEquity || // // Do not Open Positions if free margin not passed ... freeMargin <= maximumMariginRisk || // // Do not open positions if balance less than minimum ... balance <= minimumBalanceForTrade ) { // allowDoTrade = false; // string message = StringConcatenate( "Trading Pause => ", "Balance: ", balance, ", Equity: ", equity, ", FreeMargin: ", freeMargin ); // LogMessage(message); SendAlert(message); } } // // Chack Maximum Open Positions ... int openTrades = CountOpenTrades(); if (maxOpenTrades > 0) { // if (openTrades >= maxOpenTrades) { // allowDoTrade = false; // string message = StringConcatenate( "Trading Pause => ", "Max Open Trades (", maxOpenTrades, ") reached ..." ); // LogMessage(message); SendAlert(message); } } // // Retrieve Signal Verification ... bool isVerified = true; if (!isVerified) { // allowDoTrade = false; // string message = StringConcatenate( "Trading Pause => ", "Signal Verification failed ..." ); // LogMessage(message); SendAlert(message); } // // Check Trading is Enable or not ... // nothing to do if trading is disabled ... if (!allowDoTrade) { // string message = StringConcatenate( "Trading Not Allowed ..." ); // LogMessage(message); SendAlert(message); return; } // bool isPositionOpened = TradeSignal( request.signal, signalPrefix, lotsPerTradePercent, bullishSignalLabel, bullishSignalColor, bearishSignalLabel, bearishSignalColor ); // if (isPositionOpened) { // bool canAlert = alertPositions && ( hasLongSignal ? longPositionAlerts : shortPositionAlerts ); // if (canAlert) { // // Alert Message ... string message = StringConcatenate( "Trade on Signal ID: ", request.signal.id, ", Entry: ", request.signal.entryPrice, ", TP: ", request.signal.tp ); // // Terminal Alert ... if (terminalAlert) { Alert(message); } // // Push Alert ... if (pushAlert) { SendNotification(message); } } } } // // Process All Open Positions ... void ProcessOpenPositions() { // // Retrieve Account Balance ... double balance = AccountInfoDouble(ACCOUNT_BALANCE); double minimumBalanceForTrade = minBalancePercent * initialBalance; // // Retrieve Account Equity ... double equity = AccountInfoDouble(ACCOUNT_EQUITY); double maxAllowedEquity = balance - (balance * maxEquityPercent); // // Retrieve Free Marigin ... double freeMargin = AccountFreeMargin(); double maximumMariginRisk = balance - (balance * maxEquityPercent); // if (closeLongTrades) { // closeLongTrades = false; // CloseAllLongTrades(); LogMessage("Close All Long Trades ..."); } // if (closeShortTrades) { // closeShortTrades = false; CloseAllShortTrades(); LogMessage("Close All Short Trades ..."); } } // // Send Special Type of Alerts ... void SendAlert(string message) { // if (!alertEvents) { return; } // // Terminal Alert ... if (terminalAlert) { Alert(message); } // // Push Alert ... if (pushAlert) { SendNotification(message); } } //