/////////////////////////////////////////////////////// // // SaherElm IT Center XST_OSC Strategy Expert Advisor // --------------------------------------------- // saherelm implementation of strategy expert advisor ... // // ShortName: XST_OSC // // 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_OSC Strategy Expert Advisor" #property strict // // START Inputs ... // // // Signal Prefixe ... input string signalPrefix = "XST_OSC"; // 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 = false; // Allow Short Trades // // Market Specification Inpouts ... input int marketLength = 7; // Market Length input double riskToRewardRatio = 2; // Risk to Reward Ratio // // 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.00001; // Lots Per Trade Percent input int maxOpenTrades = 4; // Maximum Open Trade input double maxDrawdownPercentPerPTrade = 0.1; // Maximum DrawDown Per Trade input double minBalancePercent = 0.5; // Minimum Balance for Trading input double maxEquityPercent = 0.1; // Maximum Trade Equity input int closeAllOpenTradesAfterCandle = 864; // Close All Open Trades After Passed Candles // // OSC Inputs ... // // FastOSC ... // Short Cycle (Fast OSC) ... input int fastOSCLength = 7; // FastOSC Length input double fastOSCMultiplier = 1.0; // FastOSC Multiplier // // SlowOSC ... // Medium Cycle (Slow OSC) ... input int slowOSCLength = 14; // SlowOSC Length input double slowOSCMultiplier = 3.0; // SlowOSC Multiplier // // Power OSC ... input double minPowerOSC = 0.055; // Minimum Signal Power // // Variance OSC ... input double minVarianceOSC = 0; // Minimum Var Power // // ZIGZAG Inputs ... input int zDeviation = 5; // ZigZag Deviation input int zBackStep = 3; // ZigZag Back Step // // XMA Inputs ... // 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 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.osc.signal.lib.mq4" // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... bool inputsNotValiid = // // MARKET ... marketLength < 0 || riskToRewardRatio < 0 // // EA ... || lotsPerTradePercent < 0 || maxOpenTrades <= 0 || maxDrawdownPercentPerPTrade < 0 || minBalancePercent < 0 || maxEquityPercent < 0 || marketLength < 0 // // OSC ... || fastOSCLength < 0 || fastOSCMultiplier < 0 || slowOSCLength < 0 || slowOSCMultiplier < 0 || minPowerOSC < 0 || minVarianceOSC < 0 || slowOSCLength <= fastOSCLength // // ZIGZAG ... || zDeviation < 0 || zBackStep < 0 || zBackStep >= marketLength // // 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; // // START Define Array Series ... // // // END Define Array Series ... // // // here we specify logging enabled or not ... enableLogging = true; // // this is a Tag which attached to our Logger ... logTag = "XST_OSC"; // // // // 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 ... // bool isSCFastCrossUnderSlow = xmaState.scFast < xmaState.scSlow && !(xmaState.scFastPrev < xmaState.scSlowPrev); // bool isMCFastCrossUnderSlow = xmaState.mcFast < xmaState.mcSlow && !(xmaState.mcFastPrev < xmaState.mcSlowPrev); // bool isLCFastCrossUnderSlow = xmaState.lcFast < xmaState.lcSlow && !(xmaState.lcFastPrev < xmaState.lcSlowPrev); // closeLongTrades = ( isSCFastCrossUnderSlow && isMCFastCrossUnderSlow ) || ( isSCFastCrossUnderSlow && isLCFastCrossUnderSlow ) || ( isMCFastCrossUnderSlow && isLCFastCrossUnderSlow ) ; // waitForLongSignals = waitForLongSignals ? true : ( ( xmaState.lcFast > xmaState.lcSlow && !(xmaState.lcFastPrev > xmaState.lcSlowPrev) ) || ( xmaState.mcFast > xmaState.mcSlow && !(xmaState.mcFastPrev > xmaState.mcSlowPrev) ) ) ; } // // Calculate Signals and Process Based on Exists Signals ... void ProcessSignals() { // XSignalRequest request = {}; request.type = X_NONE; request.hasSignal = false; // // Prevent Multiple Calculating on Same Bars ... isNewBar = IsNewBar(); if (isNewBar) { // countedBars++; // // // LogMessage( // StringConcatenate( // "Check Signals, Bars: ", // countedBars // ) // ); // // Retrieve Signal Exists ... // 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, // // // // OSC ... // fastOSCLength, // FastOSC Length ... // fastOSCMultiplier, // FastOSC Multiplier ... // slowOSCLength, // SlowOSC Length ... // slowOSCMultiplier, // SlowOSC Multiplier ... // minPowerOSC, // Minimum Signal Power ... // minVarianceOSC, // Minimum Var Power ... // // // // ZIGZAG Inputs ... // zDeviation, // ZigZag Deviation ... // zBackStep // ZigZag Back Step ... // ); } // bool allowDoTrade = true; // // Check Balance ... if (initialBalance > 0) { // // Retrieve Account Balance ... double balance = AccountInfoDouble(ACCOUNT_BALANCE); double minimumBalanceForTrade = balance > initialBalance ? minBalancePercent * balance : 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); // // Close In Profit Trades ... // then Recheck Signal ... // bool hasInProfitTradeClosed = CloseAllInProfitTrades(); // if (hasInProfitTradeClosed) { // ProcessSignals(); // } } } // // Retrieve Signal Exists ... 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, // // OSC ... fastOSCLength, // FastOSC Length ... fastOSCMultiplier, // FastOSC Multiplier ... slowOSCLength, // SlowOSC Length ... slowOSCMultiplier, // SlowOSC Multiplier ... minPowerOSC, // Minimum Signal Power ... minVarianceOSC, // Minimum Var Power ... // // ZIGZAG Inputs ... zDeviation, // ZigZag Deviation ... zBackStep // ZigZag Back Step ... ); // // Prevent doing anything else, if there is no signals ... if ( !allowDoTrade || !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; } // // Prevent Signals if openTrades on last Market ... // this means for each trades at least we have to wait market length passed from last signal ... // if (lastSignalledBar + (marketLength) > countedBars) { // return; // } // // increase last signalled bar ... lastSignalledBar = countedBars; // // Calculate Can Trade or not ... allowDoTrade = allowTrade && ( hasLongSignal ? allowLongTrades : allowShortTrades ); // // 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); } } // // 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() { // // TODO: // - Order 5 Long Time; // - Order 8 Long Time; // - Order 13 Long Time; // - lcTrendDown; // - mcTrendUp; // - scTrendDown; // - marketMiddleage < mcSlow; // - longEntryPrice > lcSlow; // - scTrendPowerUp; // - Order 14 All Long Trades; // - lcMarket TrendUp; // - mcMarket TrendUp; // - // - Order 16 Long Time; // - Ordrr 17 Long Time; // - Ordrr 22 Long Time; // - Ordrr 26 Long Time; // - Ordrr 32 All Long Trades; // - Ordrr 40 Long Time; // - Ordrr 41 Long Time; // - Ordrr 52 Long Time; // - Ordrr 66 Long Time; // - Ordrr 73 Long Time; // - Ordrr 74 All Long Trades; // - Ordrr 78 Long Time; // - Ordrr 78 Long Time; // - Ordrr 87 All Long Trades; // - Ordrr 95 Long Time; // - Ordrr 97 Long Time; // - Ordrr 106 Long Time; // - Ordrr 107 All Long Trades; // - Ordrr 109 Long Time; // - Ordrr 111 Long Time; // if (closeLongTrades) { // closeLongTrades = false; // bool isAllLongTradesClosed = CloseAllLongTrades(); if (isAllLongTradesClosed) { waitForLongSignals = false; } } // if (closeShortTrades) { // closeShortTrades = false; // bool isAllShortTradesClosed = CloseAllShortTrades(); if (isAllShortTradesClosed) { waitForShortSignals = false; } } // bool hasClosedLongTimeTrade = CloseAllLongTimeTrades( closeAllOpenTradesAfterCandle ); // // Close Maximum DrawDown Passed Trades ... bool hasClosedInDrawDownLongTrade = CloseAllMaximumDrawDownPassedTrades( maxDrawdownPercentPerPTrade ); // if ( hasClosedLongTimeTrade || hasClosedInDrawDownLongTrade ) { // waitForLongSignals = false; waitForShortSignals = false; } } // // Send Special Type of Alerts ... void SendAlert(string message) { // // // if (!alertEvents) { // return; // } // // // // Terminal Alert ... // if (terminalAlert) { // Alert(message); // } // // // // Push Alert ... // if (pushAlert) { // SendNotification(message); // } } // // END Functions ... //