/////////////////////////////////////////////////////// // // SaherElm IT Center MQL4 Signal Draw Global Library // --------------------------------------------------- // saherelm useful tools and definitions ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // Includes Logger library ... #include "../Libraries/x-saherelm.lib.mq4" // // Includes Models library ... #include "../Libraries/x-saherelm.osc.models.lib.mq4" // // Includes Drawing library ... #include "../Libraries/x-saherelm.draw.lib.mq4" // // START Global Requirement Functions ... // // static int totalSignals = 0; static int totalLongSignals = 0; static int totalShortSignals = 0; // static double initialBalance = 0; // static int countedBars = 0; static bool isNewBar = false; // static bool isSharpBullishHappens; static bool isSharpBearishHappens; // static XOSCState oscStates[]; // static bool isOSCFastCrossOverSlow; static datetime oscFastCrossOverSlowTime; static datetime lastOSCFastCrossOverSlowTime; // static bool isOSCFastCrossUnderSlow; static datetime oscFastCrossUnderSlowTime; static datetime lastOSCFastCrossUnderSlowTime; // static bool isOSCTrendUp; static double minOSCPower; static double maxOSCPower; static bool isOSCTrendDown; static bool isOSCPowerTrendUp; static bool isOSCMarketRanging; static bool isOSCPowerTrendDown; // static XMAState xmaStates[]; // static bool isSCFastCrossOverSlow; static datetime scFastCrossOverSlowTime; static datetime lastSCFastCrossOverSlowTime; static bool isSCFastCrossOverSlowValid; // static bool isSCFastCrossUnderSlow; static datetime scFastCrossUnderSlowTime; static datetime lastSCFastCrossUnderSlowTime; static bool isSCFastCrossUnderSlowValid; // static bool isSCTrendUp; static bool isSCTrendDown; // static bool isMCFastCrossOverSlow; static datetime mcFastCrossOverSlowTime; static datetime lastMCFastCrossOverSlowTime; static bool isMCFastCrossOverSlowValid; // static bool isMCTrendUp; static bool isMCTrendDown; // static double mcTrendPowers[]; static double marketMiddles[]; // static bool isMCFastCrossUnderSlow; static datetime mcFastCrossUnderSlowTime; static datetime lastMCFastCrossUnderSlowTime; static bool isMCFastCrossUnderSlowValid; // static bool isMarketMiddleCrossOverMCFast; static datetime marketMiddleCrossOverMCFastTime; static datetime lastMarketMiddleCrossOverMCFastTime; static bool isMarketMiddleCrossOverMCFastValid; // static bool isMarketMiddleCrossOverMCSlow; static datetime marketMiddleCrossOverMCSlowTime; static datetime lastMarketMiddleCrossOverMCSlowTime; static bool isMarketMiddleCrossOverMCSlowValid; // static bool isMarketMiddleCrossUnderMCFast; static datetime marketMiddleCrossUnderMCFastTime; static datetime lastMarketMiddleCrossUnderMCFastTime; static bool isMarketMiddleCrossUnderMCFastValid; // static bool isMarketMiddleCrossUnderMCSlow; static datetime marketMiddleCrossUnderMCSlowTime; static datetime lastMarketMiddleCrossUnderMCSlowTime; static bool isMarketMiddleCrossUnderMCSlowValid; // static bool isParabolicCrossOverMarketMiddle; static datetime parabolicCrossOverMarketMiddleTime; static datetime lastParabolicCrossOverMarketMiddleTime; static bool isParabolicCrossOverMarketMiddleValid; // static bool isParabolicCrossUnderMarketMiddle; static datetime parabolicCrossUnderMarketMiddleTime; static datetime lastParabolicCrossUnderMarketMiddleTime; static bool isParabolicCrossUnderMarketMiddleValid; // static bool isParabolicTrendUp; static bool isParabolicTrendDown; // static bool isLCFastCrossOverSlow; static datetime lcFastCrossOverSlowTime; static datetime lastLCFastCrossOverSlowTime; // static bool isLCFastCrossUnderSlow; static datetime lcFastCrossUnderSlowTime; static datetime lastLCFastCrossUnderSlowTime; // static bool isMarketMiddleageTrendUp; static bool isMarketMiddleageTrendDown; // // Retrieve State ... XOSCState GetOSCState( const int bar_index, const int foLen, const double foMul, const int slLen, const double slMul ) { // // Define Trend Direction Related Values ... // XOSCState result = {}; // // START Extract Data from Oscillator ... // // // Fast OSC ... double fastOSC = iCustom( _Symbol, _Period, oscIndicatorName, foLen, foMul, slLen, slMul, 0, // Fast OSC Buffer Index ... bar_index ); result.fastOSC = fastOSC; // // Slow OSC ... double slowOSC = iCustom( _Symbol, _Period, oscIndicatorName, foLen, foMul, slLen, slMul, 1, // Slow OSC Buffer Index ... bar_index ); result.slowOSC = slowOSC; // // Power OSC ... double powerOSC = iCustom( _Symbol, _Period, oscIndicatorName, foLen, foMul, slLen, slMul, 2, // Power OSC Buffer Index ... bar_index ); result.powerOSC = powerOSC; // // Var OSC ... double varOSC = iCustom( _Symbol, _Period, oscIndicatorName, foLen, foMul, slLen, slMul, 3, // Var OSC Buffer Index ... bar_index ); result.varOSC = varOSC; // // Tan FS OSC ... double tanFSOSC = iCustom( _Symbol, _Period, oscIndicatorName, foLen, foMul, slLen, slMul, 4, // Tan F/S OSC Buffer Index ... bar_index ); result.tanFSOSC = tanFSOSC; // // END Extract Data from Oscillator ... // // return result; } // // Check Market Ranging or not based on OSC ... bool IsOSCMarketRanging( // const int bar_index, // Bar Index ... const int marketLen, // Market Length ... // const double rangingThreshold, // Detect Ranging based On Power OSC ... // // OSC Specifications ... const int foLen, // Fast OSC Length ... const double foMul, // Fast OSC Multiplier ... const int slLen, // Slow OSC Length ... const double slMul // Slow OSC Multiplier ... ) { // bool result = false; // // Detect Buffer Size ... const int bufferSize = marketLen + bar_index; double powerOSCBuffer[]; ArraySetAsSeries( powerOSCBuffer, true ); ArrayResize( powerOSCBuffer, bufferSize ); // // Loop through Market for Extract PowerOSC from OSC Indicator ... for (int i = bufferSize - 1; i >= 0; i--) { // // Retrieve OSC State at Specific Bar Index ... XOSCState state = GetOSCState( i, foLen, foMul, slLen, slMul ); // powerOSCBuffer[i] = state.powerOSC; } // // now we have to extract min and max value of Splitted Buffer ... XMinMax minMax = GetBufferMinMax(powerOSCBuffer); // // now Check Min and Max Direction and Compare them with Ranging Value ... result = MathAbs(minMax.min) > rangingThreshold || MathAbs(minMax.max) > rangingThreshold; // return result; } // // Retrieve and Calculate XMA State ... XMAState GetXMAState( // // Market Specification Inpouts ... const int bar_index, // Bar Index ... const int marketLen, // Market Length ... const double stp, // SAR Step ... const double maxm, // SAR Maximum ... // // XMA Inputs ... const int scFastMul, // Short Cycle Fast Multiplier ... const int scSlowMul, // Short Cycle Slow Multiplier ... const int mcFastMul, // Medium Cycle Fast Multiplier ... const int mcSlowMul, // Medium Cycle Slow Multiplier ... const int lcFastMul, // Long Cycle Fast Multiplier ... const int lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... const bool showPSr, // Show Parabolic Sar const bool showSC, // Show Short Cycle const bool showSCCrossLines, // Show Short Cycle Vertical Lines const bool showMC, // Show Medium Cycle const bool showMCCrossLines, // Show Medium Cycle Vertical Lines const bool showLC, // Show Long Cycle const bool showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... const color pSrColor, // Parabolic Sar Color const color scFastColor, // Short Cycle Fast Color ... const color scSlowColor, // Short Cycle Slow Color ... const color mcFastColor, // Medium Cycle Fast Color ... const color mcSlowColor, // Medium Cycle Slow Color ... const color lcFastColor, // Medium Cycle Fast Color ... const color lcSlowColor // Medium Cycle Slow Color ... ) { // // Temp Result ... XMAState result = {}; // // START Reading Buffers ... // // // Define BufferIndexes ... int scFastBufIndex = 0; int scSlowBufIndex = 1; int mcFastBufIndex = 2; int mcSlowBufIndex = 3; int lcFastBufIndex = 4; int lcSlowBufIndex = 5; int midBufIndex = 6; int pSarBufIndex = 7; // // START Short Cycle ... // // // Short Cycle Fast ... double scFast = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // scFastBufIndex, // Buffer Index ... bar_index ); result.scFast = scFast; // // Short Cycle Slow ... double scSlow = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // scSlowBufIndex, // Buffer Index ... bar_index ); result.scSlow = scSlow; // // END Short Cycle ... // // // START Medium Cycle ... // // // Medium Cycle Fast ... double mcFast = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // mcFastBufIndex, // Buffer Index ... bar_index ); result.mcFast = mcFast; // // Medium Cycle Slow ... double mcSlow = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // mcSlowBufIndex, // Buffer Index ... bar_index ); result.mcSlow = mcSlow; // // END Medium Cycle ... // // // START Long Cycle ... // // // Long Cycle Fast ... double lcFast = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // lcFastBufIndex, // Buffer Index ... bar_index ); result.lcFast = lcFast; // // Long Cycle Slow ... double lcSlow = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // lcSlowBufIndex, // Buffer Index ... bar_index ); result.lcSlow = lcSlow; // // END Long Cycle ... // // // START Makret Middleage ... // // // Market Middleage ... double marketMiddleage = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // midBufIndex, // Buffer Index ... bar_index ); result.marketMiddleage = marketMiddleage; // // END Makret Middleage ... // // // START Parabolic SAR ... // // // Parabolic ... double parabolicSAR = iCustom( _Symbol, _Period, xmaIndicatorName, // // XMA Inputs ... // // Market Specification Inpouts ... marketLen, // Market Length ... stp, // PSAR Step ... maxm, // PSAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... showPSr, // Show Parabolic SAR ... showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... pSrColor, // Parabolic Sar Color ... scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor, // Medium Cycle Slow Color ... // pSarBufIndex, // Buffer Index ... bar_index ); result.parabolicSAR = parabolicSAR; // // END Makret Middleage ... // // // END Reading Buffers ... // // return result; } // // Calculate Fib Level ... double GetFibonacciLevel( double upPrice, double downPrice, double level, X_DIRECTION direction ) { // double ling = upPrice - downPrice; double pLevel = (ling / 100) * (level * 100); // double result = direction == X_UP ? upPrice - pLevel : downPrice + pLevel; result = NormalizeDouble(result, _Digits); // return result; } // // END Global Requirement Functions ... // // // START Signal Related Functions ... // // // Calculate Signal ... // in this function we calculate a signal exists in // specific bar or not ... XSignalRequest CalculateSignal( // const int bar_index, // Bar Index ... // // MARKET Specifications ... const int marketLen, // Market Length ... const int reverseLookupInMarket,//Revrse Lookup In Marketfor TP, SL, ... const double r2r, // Risk To Reward Ratio ... // // TODO: here we can add different Signalling Strategies // usages variables to handle On/Off them in where we want ... // // XMA Inputs ... // const double stp, // SAR Step ... const double maxm, // SAR Maximum ... const int scFastMul, // Short Cycle Fast Multiplier ... const int scSlowMul, // Short Cycle Slow Multiplier ... const int mcFastMul, // Medium Cycle Fast Multiplier ... const int mcSlowMul, // Medium Cycle Slow Multiplier ... const int lcFastMul, // Long Cycle Fast Multiplier ... const int lcSlowMul, // Long Cycle Slow Multiplier ... // // Show/Hide Inputs ... const bool showPSr, // Show Parabolic Sar const bool showSC, // Show Short Cycle const bool showSCCrossLines, // Show Short Cycle Vertical Lines const bool showMC, // Show Medium Cycle const bool showMCCrossLines, // Show Medium Cycle Vertical Lines const bool showLC, // Show Long Cycle const bool showLCCrossLines, // Show Long Cycle Vertical Lines // // Color Inputs ... const color pSrColor, // Parabolic Sar Color ... const color scFastColor, // Short Cycle Fast Color ... const color scSlowColor, // Short Cycle Slow Color ... const color mcFastColor, // Medium Cycle Fast Color ... const color mcSlowColor, // Medium Cycle Slow Color ... const color lcFastColor, // Medium Cycle Fast Color ... const color lcSlowColor, // Medium Cycle Slow Color ... // // OSC Inputs ... const int fastOSCLen, // FastOSC Length ... const double fastOSCMul, // FastOSC Multiplier ... const int slowOSCLen, // SlowOSC Length ... const double slowOSCMul, // SlowOSC Multiplier ... const double minPowOSC, // Minimum Signal Power ... const double minVarOSC, // Minimum Var Power ... // // ZIGZAG Inputs ... const int zDev, // ZigZag Deviation ... const int zBkStep // ZigZag Back Step ... ) { // // create temp result ... XSignalRequest result = {}; result.hasSignal = false; result.type = X_NONE; // XSignal signal = {}; // XOSCState emptyOscState = {}; ArrayFree(oscStates); ArrayResize( oscStates, marketLen ); for (int i = 0; i < marketLen; i++) { oscStates[i] = emptyOscState; } // XMAState emptyXmaState = {}; ArrayFree(xmaStates); ArrayResize( xmaStates, marketLen ); for (int i = 0; i < marketLen; i++) { xmaStates[i] = emptyXmaState; } // // Retrieve Bar Index Time ... datetime barTime = iTime( _Symbol, _Period, bar_index + 1 ); // minOSCPower = 0; maxOSCPower = 0; // // START Retrieve Statets ... // // // Loop through Market Length ... int index = 0; for (int i = bar_index; i < bar_index + marketLen; i++) { // // Retrieve Index OSC State ... XOSCState oscState = GetOSCState( index, // Bar Index ... fastOSCLen, fastOSCMul, slowOSCLen, slowOSCMul ); // // Retrieve XMA State ... XMAState xmaState = GetXMAState( index, // Bar Index ... marketLen, // Market Length ... stp, // SAR Step ... maxm, // SAR Maximum ... scFastMul, // Short Cycle Fast Multiplier ... scSlowMul, // Short Cycle Slow Multiplier ... mcFastMul, // Medium Cycle Fast Multiplier ... mcSlowMul, // Medium Cycle Slow Multiplier ... lcFastMul, // Long Cycle Fast Multiplier ... lcSlowMul, // Long Cycle Slow Multiplier ... showPSr, // Show Parabolic Sar showSC, // Show Short Cycle showSCCrossLines, // Show Short Cycle Vertical Lines showMC, // Show Medium Cycle showMCCrossLines, // Show Medium Cycle Vertical Lines showLC, // Show Long Cycle showLCCrossLines, // Show Long Cycle Vertical Lines pSrColor, // Parabolic Sar Color scFastColor, // Short Cycle Fast Color ... scSlowColor, // Short Cycle Slow Color ... mcFastColor, // Medium Cycle Fast Color ... mcSlowColor, // Medium Cycle Slow Color ... lcFastColor, // Medium Cycle Fast Color ... lcSlowColor // Medium Cycle Slow Color ... ); // // Set Retrieved Index States ... oscStates[index] = oscState; xmaStates[index] = xmaState; // index++; } // // END Retrieve Statets ... // // // START States Calculations ... // // // START OSC Calculations ... // // // Check OSC Fast Cross Over Slow ... isOSCFastCrossOverSlow = oscStates[1].fastOSC > oscStates[1].fastOSC && !(oscStates[2].fastOSC >= oscStates[2].fastOSC) && !(oscStates[3].fastOSC >= oscStates[3].fastOSC) ; // // Setting Date Time ... if (isOSCFastCrossOverSlow) { // lastOSCFastCrossOverSlowTime = oscFastCrossOverSlowTime; oscFastCrossOverSlowTime = barTime; } // // Check OSC Fast Cross Under Slow ... isOSCFastCrossUnderSlow = oscStates[1].fastOSC < oscStates[1].fastOSC && !(oscStates[2].fastOSC <= oscStates[2].fastOSC) && !(oscStates[3].fastOSC <= oscStates[3].fastOSC) ; // // Setting Date Time ... if (isOSCFastCrossUnderSlow) { // lastOSCFastCrossUnderSlowTime = oscFastCrossUnderSlowTime; oscFastCrossUnderSlowTime = barTime; } // // Check OSC Trending Up ... isOSCTrendUp = oscStates[1].fastOSC > oscStates[2].fastOSC && oscStates[1].fastOSC > oscStates[3].fastOSC && ( oscStates[1].fastOSC > oscStates[3].fastOSC || oscStates[1].fastOSC > oscStates[4].fastOSC ); // // Check OSC Trending Down ... isOSCTrendDown = oscStates[1].fastOSC < oscStates[2].fastOSC && oscStates[1].fastOSC < oscStates[3].fastOSC && ( oscStates[1].fastOSC < oscStates[3].fastOSC || oscStates[1].fastOSC < oscStates[4].fastOSC ); // isOSCPowerTrendUp = oscStates[1].powerOSC > oscStates[2].powerOSC && oscStates[1].powerOSC > oscStates[3].powerOSC; // isOSCPowerTrendDown = oscStates[1].powerOSC < oscStates[2].powerOSC && oscStates[1].powerOSC < oscStates[3].powerOSC; // for (int i = 0; i < marketLen; i++) { // minOSCPower = minOSCPower == 0 || oscStates[i].powerOSC < minOSCPower ? oscStates[i].powerOSC : minOSCPower ; // maxOSCPower = maxOSCPower == 0 || oscStates[i].powerOSC > maxOSCPower ? oscStates[i].powerOSC : maxOSCPower ; } // // now Check Min and Max Direction and Compare them with Ranging Value ... isOSCMarketRanging = MathAbs(minOSCPower) <= minPowOSC || MathAbs(maxOSCPower) <= minOSCPower; // // END OSC Calculations ... // // // START XMA Calculations ... // // // Check SC Fast Cross Over Slow ... isSCFastCrossOverSlow = xmaStates[1].scFast > xmaStates[1].scSlow && !(xmaStates[2].scFast >= xmaStates[2].scSlow); // // Setting Date Time ... if (isSCFastCrossOverSlow) { // lastSCFastCrossOverSlowTime = scFastCrossOverSlowTime; scFastCrossOverSlowTime = barTime; } int scFastCrossOverSlowBarIndex = iBarShift( _Symbol, _Period, scFastCrossOverSlowTime, false ); int lastSCFastCrossOverSlowTimeBarIndex = iBarShift( _Symbol, _Period, lastSCFastCrossOverSlowTime, false ); isSCFastCrossOverSlowValid = lastSCFastCrossOverSlowTimeBarIndex - scFastCrossOverSlowBarIndex > (scFastMul * marketLen); // // Check SC Fast Cross Under Slow ... isSCFastCrossUnderSlow = xmaStates[1].scFast < xmaStates[1].scSlow && !(xmaStates[2].scFast <= xmaStates[2].scSlow); // // Setting Date Time ... if (isSCFastCrossUnderSlow) { // lastSCFastCrossUnderSlowTime = scFastCrossUnderSlowTime; scFastCrossUnderSlowTime = barTime; } int scFastCrossUnderSlowBarIndex = iBarShift( _Symbol, _Period, scFastCrossUnderSlowTime, false ); int lastSCFastCrossUnderSlowBarIndex = iBarShift( _Symbol, _Period, lastSCFastCrossUnderSlowTime, false ); isSCFastCrossUnderSlowValid = lastSCFastCrossUnderSlowBarIndex - scFastCrossUnderSlowBarIndex > (scFastMul * marketLen); // isSCTrendUp = xmaStates[1].scFast > xmaStates[1].scSlow && xmaStates[2].scFast > xmaStates[2].scSlow && xmaStates[3].scFast > xmaStates[3].scSlow; // isSCTrendDown = xmaStates[1].scFast < xmaStates[1].scSlow && xmaStates[2].scFast < xmaStates[2].scSlow && xmaStates[3].scFast < xmaStates[3].scSlow; // // Check MC Fast Cross Over Slow ... isMCFastCrossOverSlow = xmaStates[1].mcFast > xmaStates[1].mcSlow && !(xmaStates[2].mcFast >= xmaStates[2].mcSlow); // // Setting Date Time ... if (isMCFastCrossOverSlow) { // lastMCFastCrossOverSlowTime = mcFastCrossOverSlowTime; mcFastCrossOverSlowTime = barTime; } int mcFastCrossOverSlowBarIndex = iBarShift( _Symbol, _Period, mcFastCrossOverSlowTime, false ); int lastMCFastCrossOverSlowBarIndex = iBarShift( _Symbol, _Period, lastMCFastCrossOverSlowTime, false ); isMCFastCrossOverSlowValid = lastMCFastCrossOverSlowBarIndex - mcFastCrossOverSlowBarIndex > (mcFastMul * marketLen); // // Check MC Fast Cross Under Slow ... isMCFastCrossUnderSlow = xmaStates[1].mcFast < xmaStates[1].mcSlow && !(xmaStates[2].mcFast <= xmaStates[2].mcSlow); // // Setting Date Time ... if (isMCFastCrossUnderSlow) { // lastMCFastCrossUnderSlowTime = mcFastCrossUnderSlowTime; mcFastCrossUnderSlowTime = barTime; } int mcFastCrossUnderSlowBarIndex = iBarShift( _Symbol, _Period, mcFastCrossUnderSlowTime, false ); int lastMCFastCrossUnderSlowBarIndex = iBarShift( _Symbol, _Period, lastMCFastCrossUnderSlowTime, false ); isMCFastCrossUnderSlowValid = lastMCFastCrossUnderSlowBarIndex - mcFastCrossUnderSlowBarIndex > (mcFastMul * marketLen); // // Reset Arrays if Cross Over Happens ... if ( isMCFastCrossOverSlow // || isMCFastCrossUnderSlow ) { // ArrayFree(mcTrendPowers); ArrayFree(marketMiddles); } // double tempMCTrendPowers[]; if ( isNewBar || ArraySize(mcTrendPowers) == 0 ) { // ArrayResize( tempMCTrendPowers, ArraySize(mcTrendPowers) ); ArrayCopy( tempMCTrendPowers, mcTrendPowers, 0, 0 ); // ArrayResize( mcTrendPowers, ArraySize(mcTrendPowers) + 1 ); } // double tempMarketMiddles[]; if ( isNewBar || ArraySize(marketMiddles) == 0 ) { // ArrayResize( tempMarketMiddles, ArraySize(marketMiddles) ); ArrayCopy( tempMarketMiddles, marketMiddles, 0, 0 ); // ArrayResize( marketMiddles, ArraySize(marketMiddles) + 1 ); } // double mcPow = MathAbs( xmaStates[1].mcFast - xmaStates[1].mcSlow ); mcTrendPowers[bar_index] = mcPow; ArrayCopy( mcTrendPowers, tempMCTrendPowers, bar_index + 1, bar_index ); ArrayFree(tempMCTrendPowers); // double marketMiddleage = xmaStates[0].marketMiddleage; marketMiddles[bar_index] = marketMiddleage; ArrayCopy( marketMiddles, tempMarketMiddles, bar_index + 1, bar_index ); ArrayFree(tempMCTrendPowers); // XMinMax mcTrendMinMax = GetBufferMinMax(mcTrendPowers); XMinMax marketMiddlesMinMax = GetBufferMinMax(marketMiddles); // isMCTrendUp = xmaStates[1].mcFast > xmaStates[1].mcSlow && xmaStates[2].mcFast > xmaStates[2].mcSlow && xmaStates[3].mcFast > xmaStates[3].mcSlow; // isMCTrendDown = xmaStates[1].mcFast < xmaStates[1].mcSlow && xmaStates[2].mcFast < xmaStates[2].mcSlow && xmaStates[3].mcFast < xmaStates[3].mcSlow; // // Market Middleage Length ... int marketMiddleageLength = (int)(marketLen * 1.5); // // Check Market Middleage Cross Over MC Fast ... isMarketMiddleCrossOverMCFast = xmaStates[1].marketMiddleage > xmaStates[1].mcFast && !(xmaStates[2].marketMiddleage >= xmaStates[2].mcFast) && !(xmaStates[3].marketMiddleage >= xmaStates[3].mcFast) ; // // Setting Date Time ... if (isMarketMiddleCrossOverMCFast) { // lastMarketMiddleCrossOverMCFastTime = marketMiddleCrossOverMCFastTime; marketMiddleCrossOverMCFastTime = barTime; } int marketMiddleCrossOverMCFastBarIndex = iBarShift( _Symbol, _Period, marketMiddleCrossOverMCFastTime, false ); int lastMarketMiddleCrossOverMCFastBarIndex = iBarShift( _Symbol, _Period, lastMarketMiddleCrossOverMCFastTime, false ); isMarketMiddleCrossOverMCFastValid = lastMarketMiddleCrossOverMCFastBarIndex - marketMiddleCrossOverMCFastBarIndex > (marketMiddleageLength); // // Check Market Middleage Cross Over MC Slow ... isMarketMiddleCrossOverMCSlow = xmaStates[1].marketMiddleage > xmaStates[1].mcSlow && !(xmaStates[2].marketMiddleage >= xmaStates[2].mcSlow) && !(xmaStates[3].marketMiddleage >= xmaStates[3].mcSlow) ; // // Setting Date Time ... if (isMarketMiddleCrossOverMCSlow) { // lastMarketMiddleCrossOverMCSlowTime = marketMiddleCrossOverMCSlowTime; marketMiddleCrossOverMCSlowTime = barTime; } int marketMiddleCrossOverMCSlowBarIndex = iBarShift( _Symbol, _Period, marketMiddleCrossOverMCSlowTime, false ); int lastMarketMiddleCrossOverMCSlowBarIndex = iBarShift( _Symbol, _Period, lastMarketMiddleCrossOverMCSlowTime, false ); isMarketMiddleCrossOverMCSlowValid = lastMarketMiddleCrossOverMCSlowBarIndex - marketMiddleCrossOverMCSlowBarIndex > (marketMiddleageLength); // // Check Market Middleage Cross Under MC Fast ... isMarketMiddleCrossUnderMCFast = xmaStates[1].marketMiddleage < xmaStates[1].mcFast && !(xmaStates[2].marketMiddleage <= xmaStates[2].mcFast) && !(xmaStates[3].marketMiddleage <= xmaStates[3].mcFast) ; // // Setting Date Time ... if (isMarketMiddleCrossUnderMCFast) { // lastMarketMiddleCrossUnderMCFastTime = marketMiddleCrossUnderMCFastTime; marketMiddleCrossUnderMCFastTime = barTime; } int marketMiddleCrossUnderMCFastBarIndex = iBarShift( _Symbol, _Period, marketMiddleCrossUnderMCFastTime, false ); int lastMarketMiddleCrossUnderMCFastBarIndex = iBarShift( _Symbol, _Period, lastMarketMiddleCrossUnderMCFastTime, false ); isMarketMiddleCrossUnderMCFastValid = lastMarketMiddleCrossUnderMCFastBarIndex - marketMiddleCrossUnderMCFastBarIndex > (marketMiddleageLength); // // Check Market Middleage Cross Under MC Slow ... isMarketMiddleCrossUnderMCSlow = xmaStates[1].marketMiddleage < xmaStates[1].mcSlow && !(xmaStates[2].marketMiddleage <= xmaStates[2].mcSlow) && !(xmaStates[3].marketMiddleage <= xmaStates[3].mcSlow) ; // // Setting Date Time ... if (isMarketMiddleCrossUnderMCSlow) { // lastMarketMiddleCrossUnderMCSlowTime = marketMiddleCrossUnderMCSlowTime; marketMiddleCrossUnderMCSlowTime = barTime; } int marketMiddleCrossUnderMCSlowBarIndex = iBarShift( _Symbol, _Period, marketMiddleCrossUnderMCSlowTime, false ); int lastMarketMiddleCrossUnderMCSlowBarIndex = iBarShift( _Symbol, _Period, lastMarketMiddleCrossUnderMCSlowTime, false ); isMarketMiddleCrossUnderMCSlowValid = lastMarketMiddleCrossUnderMCSlowBarIndex - marketMiddleCrossUnderMCSlowBarIndex > (marketMiddleageLength); // isParabolicCrossOverMarketMiddle = xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage && !(xmaStates[2].parabolicSAR >= xmaStates[2].marketMiddleage); // if (isParabolicCrossOverMarketMiddle) { // lastParabolicCrossOverMarketMiddleTime = parabolicCrossOverMarketMiddleTime; parabolicCrossOverMarketMiddleTime = barTime; } // // Find Distance between two Parabolic Cross ... int parabolicCrossOverMarketMiddleBarIndex = iBarShift( _Symbol, _Period, parabolicCrossOverMarketMiddleTime, false ); int lastParabolicCrossOverMarketMiddleBarIndex = iBarShift( _Symbol, _Period, lastParabolicCrossOverMarketMiddleTime, false ); isParabolicCrossOverMarketMiddleValid = lastParabolicCrossOverMarketMiddleBarIndex - parabolicCrossOverMarketMiddleBarIndex > marketLen; // isParabolicCrossUnderMarketMiddle = xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage && !(xmaStates[2].parabolicSAR <= xmaStates[2].marketMiddleage); // if (isParabolicCrossUnderMarketMiddle) { // lastParabolicCrossUnderMarketMiddleTime = parabolicCrossUnderMarketMiddleTime; parabolicCrossUnderMarketMiddleTime = barTime; } // // Find Distance between two Parabolic Cross ... int parabolicCrossUnderMarketMiddleBarIndex = iBarShift( _Symbol, _Period, parabolicCrossUnderMarketMiddleTime, false ); int lastParabolicCrossUnderMarketMiddleBarIndex = iBarShift( _Symbol, _Period, lastParabolicCrossUnderMarketMiddleTime, false ); isParabolicCrossUnderMarketMiddleValid = lastParabolicCrossUnderMarketMiddleTime - parabolicCrossUnderMarketMiddleTime > marketLen; // isParabolicTrendUp = xmaStates[1].parabolicSAR > xmaStates[1].marketMiddleage && xmaStates[2].parabolicSAR > xmaStates[2].marketMiddleage; // isParabolicTrendDown = xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage && xmaStates[2].parabolicSAR < xmaStates[2].marketMiddleage; // // Check LC Fast Cross Over Slow ... isLCFastCrossOverSlow = xmaStates[1].lcFast > xmaStates[1].lcSlow && !(xmaStates[2].lcFast >= xmaStates[2].lcSlow); // // Setting Date Time ... if (isLCFastCrossOverSlow) { // lastLCFastCrossOverSlowTime = lcFastCrossOverSlowTime; lcFastCrossOverSlowTime = barTime; } // // Check LC Fast Cross Under Slow ... isLCFastCrossUnderSlow = xmaStates[1].lcFast < xmaStates[1].lcSlow && !(xmaStates[2].lcFast <= xmaStates[2].lcSlow); // // Setting Date Time ... if (isLCFastCrossUnderSlow) { // lastLCFastCrossUnderSlowTime = lcFastCrossUnderSlowTime; lcFastCrossUnderSlowTime = barTime; } // // Check Market Middleage Trends Up ... isMarketMiddleageTrendUp = xmaStates[0].marketMiddleage > xmaStates[1].marketMiddleage && xmaStates[0].marketMiddleage > xmaStates[2].marketMiddleage && xmaStates[0].marketMiddleage > xmaStates[3].marketMiddleage && xmaStates[1].marketMiddleage > xmaStates[2].marketMiddleage && xmaStates[1].marketMiddleage > xmaStates[3].marketMiddleage && xmaStates[2].marketMiddleage > xmaStates[3].marketMiddleage; // // Check Market Middleage Trends Down ... isMarketMiddleageTrendDown = xmaStates[0].marketMiddleage < xmaStates[1].marketMiddleage && xmaStates[0].marketMiddleage < xmaStates[2].marketMiddleage && xmaStates[0].marketMiddleage < xmaStates[3].marketMiddleage && xmaStates[1].marketMiddleage < xmaStates[2].marketMiddleage && xmaStates[1].marketMiddleage < xmaStates[3].marketMiddleage && xmaStates[2].marketMiddleage < xmaStates[3].marketMiddleage; // // END XMA Calculations ... // // // START PRICE Calculations ... // RefreshRates(); // // double candleOpen = iOpen( // _Symbol, // _Period, // bar_index // ); // double marketLow[]; double marketOpen[]; double marketHigh[]; double marketClose[]; ArrayResize( marketLow, marketLen ); ArrayResize( marketOpen, marketLen ); ArrayResize( marketHigh, marketLen ); ArrayResize( marketClose, marketLen ); for (int i = bar_index; i < marketLen + bar_index - 1; i++) { // marketLow[i] = iLow( _Symbol, _Period, i ); // marketOpen[i] = iOpen( _Symbol, _Period, i ); // marketHigh[i] = iHigh( _Symbol, _Period, i ); // marketClose[i] = iClose( _Symbol, _Period, i ); } // // Retrieve Market Price Actions Min/Max ... XMinMax marketLowMinMax = GetBufferMinMax(marketLow); XMinMax marketHighMinMax = GetBufferMinMax(marketHigh); XMinMax marketOpenMinMax = GetBufferMinMax(marketOpen); XMinMax marketCloseMinMax = GetBufferMinMax(marketClose); // isSharpBullishHappens = IsSharpBullishHappens( bar_index, marketLen ); // isSharpBearishHappens = IsSharpBearishHappens( bar_index, marketLen ); // // 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; // // END PRICE Calculations ... // // // START Capturing Signal ... // // // START LONG Signals ... // // // OSC ... bool oscHasLongSignal = // // Check Power OSC Cross Over 0 ... oscStates[1].powerOSC > 0 && oscStates[2].powerOSC < 0 && MathAbs(oscStates[1].powerOSC) > minPowOSC && MathAbs(oscStates[2].powerOSC) > minPowOSC // // Check MC Market Trending Up ... && xmaStates[1].mcFast > xmaStates[1].mcSlow // // Check Parabolic below market miidleage ... && xmaStates[1].parabolicSAR < xmaStates[1].marketMiddleage && xmaStates[2].parabolicSAR < xmaStates[2].marketMiddleage // // Check Parabolic Value bigger than MC Slow ... && xmaStates[1].parabolicSAR > xmaStates[1].mcSlow // // Check Distance between two Parabolic Cross Under // Market Middleage or current barIndex and current Cross is Valid or not ... && ( isParabolicCrossUnderMarketMiddleValid || parabolicCrossUnderMarketMiddleBarIndex - bar_index > marketLen ) // // Check Market Middleage not Max ... && xmaStates[1].marketMiddleage < marketMiddlesMinMax.max // // Check Entry Price Lower than Market Highest High ... && longEntryPrice < marketHighMinMax.max && MathAbs(longEntryPrice - marketHighMinMax.max) > (5 * _Point) // // We Have to prevent signaling when a Bullish Sharp occured ... && !isSharpBullishHappens; // bool hasLongSignal = // // OSC Signals ... oscHasLongSignal ; // // END LONG Signals ... // // // START SHORT Signals ... // bool hasShortSignal = false; // // END SHORT Signals ... // // // Check Signal Exists regardless of Long or Short ... bool hasSignal = hasLongSignal || hasShortSignal; // // 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; double sl = 0; double risk; double reward; double tp = 0; double r2rRatio = r2r; // datetime time = iTime( _Symbol, _Period, bar_index ); // // Fill Signal Related Variables ... if (hasLongSignal) { // totalLongSignals++; // price = longEntryPrice; priceGap = longPriceGap; // // // // Setting Up SL Based on Prev Candle ... // sl = prevCandleLow; // // Setting Up SL Based on Last Market Lowest ... sl = GetMarketLowestLow( bar_index, marketLen ); // // // // Setting Up SL Based on Prev Candle Less Low Price ... // sl = GetLowLessCandlePrice( // bar_index, // price // ); // // if (isSharpBearishHappens) { // sl = marketLow[1]; // } // risk = price - sl; // // // // here we calculate risk based on candle open ... risk = marketOpen[0] - sl; // reward = risk * r2rRatio; tp = price + reward; // // Check TP Touches before add in Market length // based on Passed Candles ... double passCandleReverseHighestHigh = GetMarketHighestHigh(0, reverseLookupInMarket); if (tp > passCandleReverseHighestHigh) { tp = passCandleReverseHighestHigh + (5 * _Point); } // // if (oscHasLongSignal) { // tp = price + PipsToPrice(1); // } // // Check TP based on Spread ... if (tp < price + priceGap) { tp = tp + priceGap; } } else if (hasShortSignal) { // totalShortSignals++; // price = shortEntryPrice; priceGap = shortPriceGap; // // // // Setting Up SL Based On Prev Candle ... // sl = prevCandleHigh; // // // // Setting Up SL Based on Last Market Highest ... // sl = GetMarketHighestHigh( // bar_index, // marketLen // ); // // Setting Up SL Based on Prev Candle Great High Price ... // sl = GetHighGreatCandlePrice( // bar_index, // price // ); // // Settup SL based On Parabolic SAR ... //sl = xmaStates[0].parabolicSAR; // risk = sl - price; reward = risk * r2r; 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 = 0; // sl; signal.time = time; signal.symbol = _Symbol; signal.entryPrice = price; signal.id = totalLongSignals; // // END Capturing Signal ... // // // Fill Result ... result.hasSignal = hasSignal; result.signal = signal; result.type = signal.type; // // Return Result ... return result; } // // START Signal Verification Functions ... // // // END Signal Verification Functions ... // // // START Market State Functions ... // // // END Market State Functions ... // // // Retrieve Signal Bar Index ... int GetSignalBarIndex(XSignal &signal) { // // Temp Result ... int result = -1; // // Retriev Signal Bar Index ... result = iBarShift( _Symbol, _Period, signal.time ); // return result; } // // Generate a Unique ID for Signal ... string GenerateSignalTAG( const XSignal &signal, const string tag, const string longSignalLabel, const string shortSignalLabel ) { // // Generate Propper Label for Signal ... string label = signal.type == X_LONG ? longSignalLabel : signal.type == X_SHORT ? shortSignalLabel : "UN_KNOWN"; // // Generate Unique String Identifier for Signal ... string result = tag + "_[ID:" + IntegerToString(signal.id) + "]" + "_[" + label + "]" + "_[" + signal.symbol + "]" + "_[Time:" + TimeToStr(signal.time) + "]" + "_[TP:" + DoubleToString(signal.tp) + "]" + "_[SL:" + DoubleToString(signal.sl) + "]"; // return result; } // // Draw Signal Shapes on Chart ... bool DrawSignal( const XSignal &signal, long chartID = 0, int subWindowID = 0, const double positionThresholdFactor = 10, string signalTag = "X-Signal", string longSignalLabel = "X-Long", color longSignalColor = clrAqua, string shortSignalLabel = "X-Short", color shortSignalColor = clrFuchsia ) { // // Generate isLongSignal Var ... bool isLongSignal = signal.type == X_LONG; // // Signal Bar Index ... int bar_index = iBarShift( _Symbol, _Period, signal.time ); // // START Draw Signal Arrow ... // // // Arrow Shape Name ... string arrowName = StringConcatenate(signalTag, "_Arrow_", signal.id); // // Arrow Price ... double arrowPrice = 0; if (isLongSignal) { // arrowPrice = iLow( _Symbol, _Period, bar_index ); // arrowPrice = arrowPrice - (positionThresholdFactor * _Point); } else { // arrowPrice = iHigh( _Symbol, _Period, bar_index ); // arrowPrice = arrowPrice + (positionThresholdFactor * _Point); } // // Arrow Code ... uchar arrowCode = isLongSignal ? SYMBOL_ARROWUP : SYMBOL_ARROWDOWN; // // Arrow Anchor Point ... ENUM_ARROW_ANCHOR arrowAnchorPoint = isLongSignal ? ANCHOR_BOTTOM : ANCHOR_TOP; // // Arrow Color ... color arrowColor = isLongSignal ? longSignalColor : shortSignalColor; // // Draw Signal Arrow Shape ... bool result = DrawArrow( chartID, arrowName, subWindowID, signal.time, arrowPrice, arrowCode, arrowAnchorPoint, arrowColor, STYLE_SOLID, 3, false, false, false, 0 ); // // END Draw Signal Arrow ... // // // START Draw Signal SL/TP ... // string slLineName = StringConcatenate(signalTag, "_SL_", signal.id); string tpLineName = StringConcatenate(signalTag, "_TP_", signal.id); string entryLineName = StringConcatenate(signalTag, "_ENTRY_", signal.id); // color slColor = shortSignalColor; // isLongSignal ? shortSignalColor : longSignalColor; color tpColor = longSignalColor; // isLongSignal ? shortSignalColor : longSignalColor; color entryColor = clrGreen; // datetime time1 = iTime( _Symbol, _Period, bar_index + 1 ); // // Draw Enrty Price ... result = DrawTrendLine( chartID, entryLineName, subWindowID, time1, signal.entryPrice, signal.time, signal.entryPrice, entryColor, STYLE_SOLID, 2 ); // // Draw Signal SL ... if (signal.sl > 0) { // result = DrawTrendLine( chartID, slLineName, subWindowID, time1, signal.sl, signal.time, signal.sl, slColor, STYLE_SOLID, 2 ); } // // Draw Signal TP ... if (signal.tp > 0) { // result = DrawTrendLine( chartID, tpLineName, subWindowID, time1, signal.tp, signal.time, signal.tp, tpColor, STYLE_SOLID, 2 ); } // // END Draw Signal SL/TP ... // // // Start Draw Signal Label ... // // string labelName = StringConcatenate(signalTag, "_Label_", signal.id); // double labelPrice = isLongSignal ? arrowPrice - (positionThresholdFactor * _Point) : arrowPrice + (positionThresholdFactor * _Point); // string labelText = isLongSignal ? longSignalLabel : shortSignalLabel; // result = DrawText( chartID, labelName, subWindowID, signal.time, labelPrice, labelText, "Arial", 10, arrowColor, 0, ANCHOR_CENTER ); // // End Draw Signal Label ... // // return result; } // // Trade on Specific Signal ... bool TradeSignal( XSignal &signal, // string prefix, // double volumePercent, // // Long ... const string longSignalLabel, const color longSignalColor, // // Short ... const string shortSignalLabel, const color shortSignalColor ) { // // Temp Result ... bool result = false; // if (initialBalance == 0) { initialBalance = AccountInfoDouble(ACCOUNT_BALANCE); } // double balance = AccountInfoDouble(ACCOUNT_BALANCE); int openPositions = CountOpenTrades(); double volume = (volumePercent * initialBalance); // if ( signal.type != X_LONG && signal.type != X_SHORT ) { return result; } // bool hasLongSignal = signal.type == X_LONG; // // Check TP and Entry Price ... if ( ( hasLongSignal && signal.entryPrice > signal.tp ) || ( !hasLongSignal && signal.entryPrice < signal.tp ) ) { return result; } // // Order Operation ... int operation = hasLongSignal ? OP_BUY : OP_SELL; // // Detect Trade Color ... color clr = hasLongSignal ? longSignalColor : shortSignalColor; // // Generate Signal Comment ... string label = hasLongSignal ? longSignalLabel : shortSignalLabel; // // Generate Signal Comment ... string comment = StringConcatenate( prefix, "_", signal.id, "_", label ); // // Placing Order ... int orderTicket = OrderSend( _Symbol, operation, volume, signal.entryPrice, 3, signal.sl, signal.tp, comment, signal.id, 0, clr ); // // Draw Signal Shape if Order Opened Successfully ... if (orderTicket >= 0) { // // Here i must to Draw Signal Shapes ... DrawSignal( signal, 0, 0, 50, prefix, // Signal Tag ... longSignalLabel, // Long Signal Label ... longSignalColor, shortSignalLabel, // Short Signal Label ... shortSignalColor ); // // TODO: here we have to check if there are another // open positions which their entry price is bigger // than current signal entry price, for long trades and // their tp is high than current tp, ... // close in profit trades or modify orders tp to current ... // if (CountOpenTrades() > 0) { // // Here we have to // ModifyOpenTradesBasedOnCurrentTrade(signal); } // result = true; } // return result; } // // END Signal Related Functions ... // // // START Orders Functions ... // // // Convert To XSignal Model ... XSignal OrderToSignal() { // // Temp Result ... XSignal result = {}; result.type = X_NONE; // // Here we can get some usefull info based on selected order ... double swap = OrderSwap(); double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); double stopLoss = OrderStopLoss(); double openPrice = OrderOpenPrice(); datetime openTime = OrderOpenTime(); int magicNumber = OrderMagicNumber(); double takeProfit = OrderTakeProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // Conver Position to Signal ... result.sl = stopLoss; result.tp = takeProfit; result.time = openTime; result.symbol = _Symbol; result.id = magicNumber; result.entryPrice = openPrice; result.type = isLongOrder ? X_LONG : X_SHORT; // return result; } // // START Count Orders ... // // // Count Open Positions ... int CountOpenTrades() { // int result = 0; // // Loop through Orders ... for (int i = 0; i < OrdersTotal(); i++) { // // Select indexed Order ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order ... if (OrderSymbol() == _Symbol) { result++; } } } // // Return Result ... return result; } // // Count Open Long Positions ... int CountOpenLongTrades() { // int result = 0; // // Loop through Orders ... for (int i = 0; i < OrdersTotal(); i++) { // // Select indexed Order ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order ... if ( OrderSymbol() == _Symbol && OrderType() == OP_BUY ) { result++; } } } // // Return Result ... return result; } // // Count Open Short Positions ... int CountOpenShortTrades() { // int result = 0; // // Loop through Orders ... for (int i = 0; i < OrdersTotal(); i++) { // // Select indexed Order ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order ... if ( OrderSymbol() == _Symbol && OrderType() == OP_SELL ) { result++; } } } // // Return Result ... return result; } // // END Count Orders ... // // // START Close Orders ... // // // Close All Open Trades ... bool CloseAllTrades() { // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of All Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } // return result; } // // Close All Open Long Trades ... bool CloseAllLongTrades() { // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; if (isLongOrder) { // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of All Long Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close All Open Short Trades ... bool CloseAllShortTrades() { // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; if (!isLongOrder) { // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of All Short Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close All In Profit Trades ... bool CloseAllInProfitTrades() { // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // if (profit > 0) { // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of InProfit Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close All In DrawDown Trades ... bool CloseAllInDrawDownTrades() { // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // if (profit < 0) { // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of InDrawDown Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close Biggest In DrawDown Trades ... bool CloseBiggestDrawDownTrade() { // // Loop through all Positions ... bool result = false; double drawDown = 0; // // Find Biggest In DrawDown ... for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // if ( profit < 0 && MathAbs(profit) > drawDown ) { drawDown = profit; } } } } // // Close Biggest In DrawDown ... for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // if ( profit < 0 && MathAbs(profit) >= drawDown ) { // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of Max InDrawDown Trade Closing issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close All Long Time Trades ... bool CloseAllLongTimeTrades( const int passedCandles ) { // bool result = false; // if (passedCandles <= 0) { return result; } // int currentBarIndex = iBarShift( _Symbol, _Period, TimeCurrent() ); // int openTrades = CountOpenTrades(); // // Loop through all Positions ... for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); datetime openTime = OrderOpenTime(); int openBarIndex = iBarShift( _Symbol, _Period, openTime ); // if ( openBarIndex - currentBarIndex >= passedCandles || ( profit > 0.5 && openBarIndex - currentBarIndex >= passedCandles - (passedCandles / 3) ) ) { // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of Long Time issue ..." ) ); } // result = result || isOrderClosed; } else if ( openTrades > 0 && openBarIndex - currentBarIndex >= passedCandles - (passedCandles / 2) ) { result = CloseAllInProfitTrades() && CloseBiggestDrawDownTrade(); } } } } // return result; } // // Close all trades which passed Maximum Drawdown ... bool CloseAllMaximumDrawDownPassedTrades( const double maxDrDownPercentPerPTrade ) { // if ( initialBalance <= 0 || maxDrDownPercentPerPTrade <= 0 ) { return false; } // // Retrieve Account Balance ... double balance = AccountInfoDouble(ACCOUNT_BALANCE); double maxAllowedDrawDown = -1 * (initialBalance * maxDrDownPercentPerPTrade); // // Loop through all Positions ... bool result = false; for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); // if ( profit < 0 && MathAbs(profit) >= MathAbs(maxAllowedDrawDown) ) { // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of Maximum DarwDown issue ..." ) ); } // result = result || isOrderClosed; } } } } // return result; } // // Close All Trades Which Opens before Specified Length ... bool CloseAllTradesWhichOpenInPastMarketLength( const int marketLen ) { // bool result = false; // if (marketLen <= 0) { return result; } // int currentBarIndex = iBarShift( _Symbol, _Period, TimeCurrent() ); // int openTrades = CountOpenTrades(); // // Loop through all Positions ... for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); datetime openTime = OrderOpenTime(); int openBarIndex = iBarShift( _Symbol, _Period, openTime ); // if (openBarIndex <= currentBarIndex + marketLen) { // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // Since because of equity ... // we have to ckose allpositions ... bool isOrderClosed = OrderClose( ticket, lots, closePrice, clrYellow ); // if (isOrderClosed) { // LogMessage( StringConcatenate( "Order [", ticket, "] Closed because of Market Reverse issue ..." ) ); } // result = result || isOrderClosed; } else if (openTrades > 0) { // // Close all InProfit Trdes and Biggest InDrawDown Trades ... result = CloseAllInProfitTrades() && CloseBiggestDrawDownTrade(); } } } } // return result; } // // END Close Orders ... // // // START Modify Orders ... // // void ModifyAllPriceLesserOpenTrades( const XSignal &signal ) { // // Loop through all Open Trades ... for (int i = OrdersTotal(); i >= 0; i--) { // // Check Order Selected or not ... if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // // Check Order Symbol is same as Current Symbol ... if (OrderSymbol() == _Symbol) { // double lots = OrderLots(); int ticket = OrderTicket(); double profit = OrderProfit(); double stopLoss = OrderStopLoss(); double openPrice = OrderOpenPrice(); datetime openTime = OrderOpenTime(); double takeProfit = OrderTakeProfit(); // // find order type ... bool isLongOrder = OrderType() == OP_BUY; // // find close price ... double closePrice = isLongOrder ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK); // // When new Signal Comming with price less than // currently open trade and tp less than currently // open trade, this means a market change happens ... // here we can Close InProfit Trades or Modify Trades TP ... if ( openPrice < signal.entryPrice && takeProfit > signal.tp ) { bool result = OrderModify( ticket, openPrice, signal.sl, signal.tp, clrYellow ); } } } } } // void ModifyOpenTradesBasedOnCurrentTrade( const XSignal &signal ) { // ModifyAllPriceLesserOpenTrades(signal); } // // END Modify Orders ... // // // END Orders Functions ... //