/////////////////////////////////////////////////////// // // SaherElm IT Center XST Strategy Expert Advisor // --------------------------------------------- // saherelm implementation of strategy expert advisor ... // in this EA, we try to combine multiple tools, to ashive best // results ... // // ShortName: XST // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // +989121694056 // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm XST Strategy Expert Advisor" #property strict // // START Inputs ... // // // Signal Prefixe ... input string signalPrefix = "XST"; // 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 bool useOSCSignalling = false; // Use XOSC Signalling input string oscSignalIdentifier = "XOSC"; // XOSC Signal Identifier // input bool useXMASignalling = false; // Use XMA Signalling input string xmaSignalIdentifier = "XMA"; // XMA Signal Identifier // input bool useXSHPSignalling = true; // Use XSHP Signalling input string xshpSignalIdentifier = "XSHP"; // XSHP Signal Identifier // input bool useXMNTMSignalling = false; // Use XMNTM Signalling input string xmntmSignalIdentifier = "XMNTM"; // XMNTM Signal Identifier // input bool useXRSISignalling = true; // Use XRSI Signalling input string xrsiSignalIdentifier = "XRSI"; // XRSI Signal Identifier // 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.015; // Maximum DrawDown Per Trade input double minBalancePercent = 0.5; // Minimum Balance for Trading input double maxEquityPercent = 0.1; // Maximum Trade Equity input int closeAllOpenTradesAfterCandle = 504; // Close All Open Trades After Passed Candles input bool closeAllInProfitOpenTradesWhenMaxOpenTradesReached = false; // Close All In Profit Open Trades When Max Open Trades Reached and New Signal Income // // OSC Inputs ... // // FastOSC ... // Short Cycle (Fast OSC) ... input int fastOSCLength = 10; // FastOSC Length input double fastOSCMultiplier = 1.0; // FastOSC Multiplier // // SlowOSC ... // Medium Cycle (Slow OSC) ... input int slowOSCLength = 30; // SlowOSC Length input double slowOSCMultiplier = 3.0; // SlowOSC Multiplier // // Power OSC ... input double minPowerOSC = 0.04; // Minimum Signal Power // // Variance OSC ... input double minVarianceOSC = 0.1; // Minimum Var Power // // ZIGZAG Inputs ... input int zDeviation = 5; // ZigZag Deviation input int zBackStep = 3; // ZigZag Back Step // // XMA Inputs ... // input double step = 0.02; // SAR Step input double maximum = 0.2; // SAR Maximum input int shortCycleFastMultiplier = 2; // Short Cycle Fast Multiplier input int shortCycleSlowMultiplier = 4; // Short Cycle Slow Multiplier input int mediumCycleFastMultiplier = 6; // Medium Cycle Fast Multiplier input int mediumCycleSlowMultiplier = 12; // Medium Cycle Slow Multiplier input int longCycleFastMultiplier = 36; // Long Cycle Fast Multiplier input int longCycleSlowMultiplier = 72; // Long Cycle Slow Multiplier // // Show/Hide Inputs ... input bool showPSar = false; // Show Parabolic Sar input bool showMarketMiddle = false; // Show Market Middle 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 pSarColor = clrCornflowerBlue; // Parabolic Sar Color 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 ... // // XMKT Inputs ... // // Market Specifications ... input bool showHighestHigh = false; // Show Market Highest High input bool showHighestLow = false; // Show Market Highest Low input bool showHighestOpen = false; // Show Market Highest Open input bool showHighestClose = false; // Show Market Highest Close input bool showLowestHigh = false; // Show Market Lowest High input bool showLowestLow = false; // Show Market Lowest Low input bool showLowestOpen = false; // Show Market Lowest Open input bool showLowestClose = false; // Show Market Lowest Close // input color highestHighColor = clrDeepPink; // Market Highest High Color input color highestLowColor = clrDarkOrange; // Market Highest Low Color input color highestOpenColor = clrDodgerBlue; // Market Highest Open Color input color highestCloseColor = clrOrchid; // Market Highest Close Color input color lowestHighColor = clrHotPink; // Market Lowest High Color input color lowestLowColor = clrOrange; // Market Lowest Low Color input color lowestOpenColor = clrPowderBlue; // Market Lowest Open Color input color lowestCloseColor = clrMediumOrchid; // Market Lowest Close Color // input ENUM_LINE_STYLE highestHighStyle = STYLE_DOT; // Market Highest High Line Style input ENUM_LINE_STYLE highestLowStyle = STYLE_DOT; // Market Highest Low Line Style input ENUM_LINE_STYLE highestOpenStyle = STYLE_DOT; // Market Highest Open Line Style input ENUM_LINE_STYLE highestCloseStyle = STYLE_DOT; // Market Highest Close Line Style input ENUM_LINE_STYLE lowestHighStyle = STYLE_DOT; // Market Lowest High Line Style input ENUM_LINE_STYLE lowestLowStyle = STYLE_DOT; // Market Lowest Low Line Style input ENUM_LINE_STYLE lowestOpenStyle = STYLE_DOT; // Market Lowest Open Line Style input ENUM_LINE_STYLE lowestCloseStyle = STYLE_DOT; // Market Lowest Close Line Style // // SHPD Indicator ... input double sharpDetectMultiplier = 500; // Sharp Detect Multiplier // // // input bool drawSharpDetectedLabels = false; // Draw Labels on Founded Sharps // // // input string sharpBullishLabel = "SH_BULL"; // Sharp Bullish Label // input color sharpBullishColor = clrAqua; // Sharp Bullish color // // // input string sharpBearishLabel = "SH_BEAR"; // Sharp Bearish Label // input color sharpBearishColor = clrFuchsia; // Sharp Bearish 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; // bool isMCGoingToClose; bool isSharpBullishHappens; bool isSharpBearishHappens; // datetime startMarketTime; // // Includes our shared library ... #include "../Libraries/x-saherelm.lib.mq4" // // Includes our shared library ... #include "../Libraries/x-saherelm.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"; // // // // 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() { // isNewDay = IsNewDay(); if (isNewDay) { // LogMessage( StringConcatenate( "New Day: ", TimeCurrent() ) ); } // // Process Signals to Open Positions ... ProcessSignals(); // // Checking State for Signal Handling ... CheckState(); // // Process Open Positions for Trailing Stop Loss or Close ... ProcessOpenPositions(); } // // Timer Event Handler ... void OnTimer() { // CheckState(); // ProcessOpenPositions(); } // // END Event Handlers ... // // // START Functions ... // // // START Signal Related Functions ... // // // Calculate Signal ... // in this function we calculate a signal exists in // specific bar or not ... XSignalRequest GenerateSignal( const int bar_index // Bar Index ... ) { // // create temp result ... XSignalRequest result = {}; result.hasSignal = false; result.type = X_NONE; // XSignal signal = {}; // XOSCState emptyOscState = {}; ArrayFree(oscStates); ArrayResize( oscStates, marketLength ); for (int i = 0; i < marketLength; i++) { oscStates[i] = emptyOscState; } // XMAState emptyXmaState = {}; ArrayFree(xmaStates); ArrayResize( xmaStates, shortCycleSlowMultiplier * marketLength ); for (int i = 0; i < shortCycleSlowMultiplier * marketLength; i++) { xmaStates[i] = emptyXmaState; } // XMKTState emptyXmktState = {}; ArrayFree(xmktStates); ArrayResize( xmktStates, marketLength ); for (int i = 0; i < marketLength; i++) { xmktStates[i] = emptyXmktState; } // // Retrieve Bar Index Time ... datetime barTime = iTime( _Symbol, _Period, bar_index + 1 ); // // START Retrieve Statets ... // // // Loop through Market Length ... int index = 0; for (int i = bar_index; i < bar_index + marketLength; i++) { // // Retrieve Index OSC State ... XOSCState oscState = GetOSCState( i, // Bar Index ... fastOSCLength, fastOSCMultiplier, slowOSCLength, slowOSCMultiplier ); // // Retrieve XMarketState ... XMKTState xmktState = GetMarketState( // i, marketLength, // showHighestHigh, highestHighColor, highestHighStyle, // showHighestLow, highestLowColor, highestLowStyle, // showHighestOpen, highestOpenColor, highestOpenStyle, // showHighestClose, highestCloseColor, highestCloseStyle, // showLowestHigh, lowestHighColor, lowestHighStyle, // showLowestLow, lowestLowColor, lowestLowStyle, // showLowestOpen, lowestOpenColor, lowestOpenStyle, // showLowestClose, lowestCloseColor, lowestCloseStyle ); // // Set Retrieved Index States ... oscStates[index] = oscState; xmktStates[index] = xmktState; // index++; } index = 0; for (int i = bar_index; i < bar_index + (shortCycleSlowMultiplier * marketLength); i++) { // // Retrieve XMA State ... XMAState xmaState = GetXMAState( i, // Bar Index ... marketLength, // Market Length ... step, // SAR Step ... maximum, // SAR Maximum ... 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 ... showPSar, // Show Parabolic Sar showMarketMiddle, // Show Market Middle ... showShortCycle, // Show Short Cycle showShortCycleCrossLines, // Show Short Cycle Vertical Lines showMediumCycle, // Show Medium Cycle showMediumCycleCrossLines, // Show Medium Cycle Vertical Lines showLongCycle, // Show Long Cycle showLongCycleCrossLines, // Show Long Cycle Vertical Lines pSarColor, // Parabolic Sar Color shortCycleFastColor, // Short Cycle Fast Color ... shortCycleSlowColor, // Short Cycle Slow Color ... mediumCycleFastColor, // Medium Cycle Fast Color ... mediumCycleSlowColor, // Medium Cycle Slow Color ... longCycleFastColor, // Medium Cycle Fast Color ... longCycleSlowColor // Medium Cycle Slow Color ... ); // xmaStates[index] = xmaState; // index++; } // // END Retrieve Statets ... // // // START States Calculations ... // // // START OSC Calculations ... // // // END OSC Calculations ... // // // START XMA Calculations ... // // // END XMA Calculations ... // // // START Momentum Calculations ... // // // END Momentum Calculations ... // // // START RSI Calculations ... // // // END RSI Calculations ... // // // START PRICE Calculations ... // RefreshRates(); // double marketLow[]; double marketOpen[]; double marketHigh[]; double marketClose[]; // double marketUp[]; double marketDown[]; // ArrayResize( marketLow, marketLength ); ArrayResize( marketOpen, marketLength ); ArrayResize( marketHigh, marketLength ); ArrayResize( marketClose, marketLength ); // ArrayResize( marketUp, marketLength ); ArrayResize( marketDown, marketLength ); // index = 0; for (int i = bar_index; i < marketLength + bar_index; i++) { // marketLow[index] = iLow( _Symbol, _Period, i ); // marketOpen[index] = iOpen( _Symbol, _Period, i ); // marketHigh[index] = iHigh( _Symbol, _Period, i ); // marketClose[index] = iClose( _Symbol, _Period, i ); // // marketUp[i] = MathMax(marketOpen[i], marketClose[i]); marketUp[index] = marketHigh[i]; // // marketDown[i] = MathMin(marketOpen[i], marketClose[i]); marketDown[index] = marketLow[i]; // index++; } // // LONG Prices ... double longEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double longClosePrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double longPriceGap = longClosePrice - longEntryPrice; // // SHORT Prices ... double shortEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double shortClosePrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double shortPriceGap = shortEntryPrice - shortClosePrice; // if (startMarketTime == 0) { startMarketTime = barTime; } // int startBarIndex = iBarShift( _Symbol, _Period, startMarketTime ); // if (startBarIndex > bar_index + marketLength) { // startBarIndex = 0; startMarketTime = 0; } // bool isSharpBullishDetected = false; bool isShareBearishDetected = false; double sharpDetectionValue = sharpDetectMultiplier * _Point; if (startBarIndex > bar_index + 1) { // double marketStartHigh = iHigh( _Symbol, _Period, startBarIndex ); double marketStartLow = iLow( _Symbol, _Period, startBarIndex ); // double prevCandleOpen = iOpen( _Symbol, _Period, bar_index + 1 ); // double prevCandleHigh = iHigh( _Symbol, _Period, bar_index + 1 ); // double prevCandleClose = iClose( _Symbol, _Period, bar_index + 1 ); // double candleOpen = iOpen( _Symbol, _Period, bar_index ); // double prevCandleComparedPrice = MathMin(prevCandleOpen, prevCandleClose); isShareBearishDetected = prevCandleHigh < marketStartHigh && prevCandleComparedPrice < marketStartHigh && marketStartHigh - prevCandleComparedPrice >= sharpDetectionValue; // // // isSharpBullishDetected = // marketStartHigh - MathMin(prevCandleOpen, prevCandleClose) >= sharpDetectionValue; } // if ( isShareBearishDetected || isSharpBullishDetected ) { startBarIndex = 0; startMarketTime = 0; } // // // END PRICE Calculations ... // // // START Capturing Signal ... // // // START LONG Signals ... // // // NOTES: // when MC Fast is Over MC Slow, // All Long Trades must be down when Market Middle is above MCSlow ... // and must be paused when Market Middle is Going Under MCSlow ... // // OSC ... bool oscHasLongSignal = false; if (useOSCSignalling) { // oscHasLongSignal = true && ( oscStates[0].fastOSC < 0 ) ; } // // XMA ... bool xmaHasLongSignal = false; if (useXMASignalling) { // xmaHasLongSignal = // // Long Cycle Trend Up ... xmaStates[0].lcFast > xmaStates[0].lcSlow // Lowest Low Must be Higher than lcFast ... && xmktStates[0].lowestLow > xmaStates[0].lcFast // // Medium Cycle in Up Trend ... && xmaStates[0].mcFast > xmaStates[0].mcSlow // // and the Medium Cycle Distance must be at least 100 Point ... && (xmaStates[0].mcFast - xmaStates[0].mcSlow) > (100 * _Point) // // then looking for parabolic sar cross down market middleage ... && xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage && !(xmaStates[1].parabolicSAR <= xmaStates[1].marketMiddleage) // && xmaStates[0].scFast > xmaStates[0].marketMiddleage // // in crossing time Parabolic SAR must be greater than mcFast ... && xmaStates[0].parabolicSAR > xmaStates[0].mcFast // // in this conditions, entry price must below than highest high, in market ... && longEntryPrice < xmktStates[0].highestHigh ; } // bool xshpHasLongSignal = false; if (useXSHPSignalling) { // xshpHasLongSignal = // isShareBearishDetected // && xmaStates[0].mcFast > xmaStates[0].mcSlow && xmaStates[1].mcFast > xmaStates[1].mcSlow && xmaStates[2].mcFast > xmaStates[3].mcSlow // && xmaStates[1].mcFast - xmaStates[1].mcSlow > (100 * _Point) // && xmktStates[1].lowestLow > xmaStates[1].mcSlow && xmktStates[1].highestLow > xmktStates[1].lowestHigh && MathAbs(xmktStates[0].highestLow - xmktStates[0].lowestHigh) > (50 * _Point) // && longEntryPrice != xmktStates[0].lowestHigh && MathAbs(longEntryPrice - xmktStates[0].lowestHigh) > (50 * _Point) // && (xmaStates[0].marketMiddleage > xmaStates[0].mcFast || ( xmaStates[0].marketMiddleage > xmaStates[0].mcSlow && xmaStates[0].marketMiddleage < xmaStates[0].mcFast ) ) ? !(longEntryPrice < xmaStates[0].mcSlow) && !( longEntryPrice > xmaStates[0].mcSlow && longEntryPrice < xmaStates[0].mcFast ) : true ; } // bool xmntmHasLongSignal = false; if (useXMNTMSignalling) { } // bool xrsiHasLongSignal = false; if (useXRSISignalling) { } // bool hasLongSignal = // // OSC Signals ... oscHasLongSignal || xmaHasLongSignal || xshpHasLongSignal || xmntmHasLongSignal || xrsiHasLongSignal ; // // END LONG Signals ... // // // START SHORT Signals ... // bool hasShortSignal = false; // // END SHORT Signals ... // // // Check Signal Exists regardless of Long or Short ... bool hasSignal = hasLongSignal || hasShortSignal; // // // // Check Short Cycle For Double Crossing ... // int scCrosses = 0; // int pSarCrosses = 0; // // // // SC Crosses ... // for (int i = bar_index; i < bar_index + (shortCycleSlowMultiplier * marketLength) - 1; i++) { // // // bool isPSarCrossUnderMarketMid = // xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage // && !(xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage); // // // bool isPSarCrossOverMarketMid = // xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage // && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage); // // // if ( // isPSarCrossUnderMarketMid // || isPSarCrossOverMarketMid // ) { // pSarCrosses++; // } // // // bool isSCFastCrossOverSlow = // xmaStates[i].scFast > xmaStates[i].scSlow // && !(xmaStates[i].scFast > xmaStates[i].scSlow); // // // bool isSCFastCrossUnderSlow = // xmaStates[i].scFast < xmaStates[i].scSlow // && !(xmaStates[i].scFast < xmaStates[i].scSlow); // // // if ( // isSCFastCrossOverSlow // || isSCFastCrossUnderSlow // ) { // scCrosses++; // } // } // // // // Parabolic SAR ... // for (int i = bar_index; i < bar_index + (shortCycleFastMultiplier * marketLength) - 1; i++) { // // // bool isPSarCrossUnderMarketMid = // xmaStates[0].parabolicSAR < xmaStates[0].marketMiddleage // && !(xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage); // // // bool isPSarCrossOverMarketMid = // xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage // && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage); // // // if ( // isPSarCrossUnderMarketMid // || isPSarCrossOverMarketMid // ) { // pSarCrosses++; // } // } // // // if ( // scCrosses > 1 // || pSarCrosses > 1 // ) { // LogMessage("Crosses Exceed ..."); // hasSignal = false; // } // // Prevent from Going forward if there is not a Signal ... if (!hasSignal) { // result.signal = signal; return result; } // totalSignals++; // // Define Price Related Variables ... // double price = 0; double priceGap = 0; double sl = 0; double risk; double reward; double tp = 0; double r2rRatio = riskToRewardRatio; // datetime time = iTime( _Symbol, _Period, bar_index ); // // Fill Signal Related Variables ... if (hasLongSignal) { // price = longEntryPrice; priceGap = longPriceGap; // // Setting Up SL Based on Last Market Lowest ... sl = GetMarketLowestLow( bar_index, marketLength ); // risk = price - sl; if (risk > (MathAbs(xmaStates[0].mcFast - xmaStates[0].mcSlow) / 2)) { risk = risk / 3; } reward = risk * r2rRatio; tp = price + reward; // // Check TP based on Spread ... if (tp < price + priceGap) { tp = tp + priceGap; } // sl = 0; // totalLongSignals++; } else if (hasShortSignal) { // totalShortSignals++; // price = shortEntryPrice; priceGap = shortPriceGap; // risk = sl - price; reward = risk * r2rRatio; tp = price - reward; } // // Normalize Prices ... price = NormalizeDouble(price, _Digits); sl = NormalizeDouble(sl, _Digits); tp = NormalizeDouble(tp, _Digits); // // Generate Signal Structure ... signal.type = hasLongSignal ? X_LONG : X_SHORT; signal.tp = tp; signal.sl = sl; signal.time = time; signal.symbol = _Symbol; signal.entryPrice = price; signal.id = totalLongSignals; // // TODO: Fill Signal Comment By Sgnal Provider signal.comment = useOSCSignalling && oscHasLongSignal ? oscSignalIdentifier : useXMASignalling && xmaHasLongSignal ? xmaSignalIdentifier : useXSHPSignalling && xshpHasLongSignal ? xshpSignalIdentifier : useXMNTMSignalling && xmntmHasLongSignal ? xmntmSignalIdentifier : useXRSISignalling && xrsiHasLongSignal ? xrsiSignalIdentifier : "" ; // // END Capturing Signal ... // // // Fill Result ... result.hasSignal = hasSignal; result.signal = signal; result.type = signal.type; // // Return Result ... return result; } // // Check State for Signal Handling ... void CheckState() { // // Here we Must to Check Market State for enable or disable // Signal Handlers and also make dection to close all long/short // trades ... // // Prevent from Checking, if there is no states available ... if (ArraySize(xmaStates) == 0) { return; } // // // closeLongTrades = // xmaStates[0].parabolicSAR > xmaStates[0].marketMiddleage // && !(xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage) // ; // // // closeLongTrades = // false // ; } // // 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++; } // 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); } } // // Retrieve Signal Exists ... request = GenerateSignal(0); // // 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 ... bool isInLastSignalledBars = false; for (int i=0; i < marketLength; i++) { // isInLastSignalledBars = isInLastSignalledBars || lastSignalledBar == countedBars - i ; } if (isInLastSignalledBars) { // totalSignals--; if (hasLongSignal) { totalLongSignals--; } else { totalShortSignals--; } 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; // if (closeAllInProfitOpenTradesWhenMaxOpenTradesReached) { // // Close All In Profit Trades ... bool hasClosedInProfitTrade = CloseAllInProfitTrades(); if (hasClosedInProfitTrade) { // openTrades = CountOpenTrades(); // allowDoTrade = !(openTrades >= maxOpenTrades); } } // if (!allowDoTrade) { // 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, // // Signal Identifiers ... oscSignalIdentifier, xmaSignalIdentifier, xshpSignalIdentifier, xmntmSignalIdentifier, xrsiSignalIdentifier ); // 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() { // // this comes from check state ... if (closeLongTrades) { // closeLongTrades = false; // bool isAllLongTradesClosed = CloseAllLongTrades(); if (isAllLongTradesClosed) { // waitForLongSignals = false; } } // // this comes from check state ... 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 ... //