/////////////////////////////////////////////////////// // // SaherElm IT Center XMA Indicator // --------------------------------------------- // saherelm implementation of above oscillator ... // // 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 XMA Indicator" #property strict // // START Inputs ... // // // Market Specifications ... input int marketLength = 7; // Market Length input double step = 0.02; // SAR Step input double maximum = 0.2; // SAR Maximum // // Cycle Definitions ... 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 Inputs ... input bool showPSar = true; // Show Parabolic Sar input bool showMarketMiddle = true; // Show Market Middle input bool showShortCycle = true; // Show Short Cycle input bool showShortCycleCrossLines = true; // Show Short Cycle Vertical Lines input bool showMediumCycle = true; // Show Medium Cycle input bool showMediumCycleCrossLines = true; // Show Medium Cycle Vertical Lines input bool showLongCycle = true; // Show Long Cycle input bool showLongCycleCrossLines = true; // 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 // // END Inputs ... // // // START Global Definitions: Variables, Properties and etc ... // #property indicator_chart_window // // define indicator buffers ... #property indicator_buffers 8 #property indicator_plots 8 // // Declare Buffers ... #define scFastBufferIndex 0 #define scSlowBufferIndex 1 #define mcFastBufferIndex 2 #define mcSlowBufferIndex 3 #define lcFastBufferIndex 4 #define lcSlowBufferIndex 5 #define midBufferIndex 6 #define pSarBufferIndex 7 // double scFastBuffer[]; double scSlowBuffer[]; double mcFastBuffer[]; double mcSlowBuffer[]; double lcFastBuffer[]; double lcSlowBuffer[]; double midBuffer[]; double pSarBuffer[]; // int shortCycleFastLength; int shortCycleSlowLength; int mediumCycleFastLength; int mediumCycleSlowLength; int longCycleFastLength; int longCycleSlowLength; // // Includes our shared library ... #include "../Libraries/x-saherelm.lib.mq4" // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Initialize what we want ... // // Validating Input Parameters ... if ( // // Validate Market Length ... marketLength <= 0 // // 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 ) { return INIT_PARAMETERS_INCORRECT; } // // here we specify logging enabled or not ... enableLogging = true; // // this is a Tag which attached to our Logger ... logTag = "XST_XMA"; // // Calculate Cycle Length based on given Multipliers ... shortCycleFastLength = marketLength * shortCycleFastMultiplier; shortCycleSlowLength = marketLength * shortCycleSlowMultiplier; mediumCycleFastLength = marketLength * mediumCycleFastMultiplier; mediumCycleSlowLength = marketLength * mediumCycleSlowMultiplier; longCycleFastLength = marketLength * longCycleFastMultiplier; longCycleSlowLength = marketLength * longCycleSlowMultiplier; // // Short Cycle Fast ... SetIndexLabel(scFastBufferIndex, "SCFast"); SetIndexBuffer(scFastBufferIndex, scFastBuffer); SetIndexDrawBegin(scFastBufferIndex, shortCycleFastLength); SetIndexStyle( scFastBufferIndex, DRAW_LINE, STYLE_DOT, 1, showShortCycle ? shortCycleFastColor : clrNONE ); // // Short Cycle Slow ... SetIndexLabel(scSlowBufferIndex, "SCSLow"); SetIndexBuffer(scSlowBufferIndex, scSlowBuffer); SetIndexDrawBegin(scSlowBufferIndex, shortCycleSlowLength); SetIndexStyle( scSlowBufferIndex, DRAW_LINE, STYLE_DOT, 1, showShortCycle ? shortCycleSlowColor : clrNONE ); // // Medium Cycle Fast ... SetIndexLabel(mcFastBufferIndex, "MCFast"); SetIndexBuffer(mcFastBufferIndex, mcFastBuffer); SetIndexDrawBegin(mcFastBufferIndex, mediumCycleFastLength); SetIndexStyle( mcFastBufferIndex, DRAW_LINE, STYLE_DOT, 1, showMediumCycle ? mediumCycleFastColor : clrNONE ); // // Medium Cycle Slow ... SetIndexLabel(mcSlowBufferIndex, "MCSlow"); SetIndexBuffer(mcSlowBufferIndex, mcSlowBuffer); SetIndexDrawBegin(mcSlowBufferIndex, mediumCycleSlowLength); SetIndexStyle( mcSlowBufferIndex, DRAW_LINE, STYLE_DOT, 1, showMediumCycle ? mediumCycleSlowColor : clrNONE ); // // Long Cycle Fast ... SetIndexLabel(lcFastBufferIndex, "LCFast"); SetIndexBuffer(lcFastBufferIndex, lcFastBuffer); SetIndexDrawBegin(lcFastBufferIndex, longCycleFastLength); SetIndexStyle( lcFastBufferIndex, DRAW_LINE, STYLE_DOT, 1, showLongCycle ? longCycleFastColor : clrNONE ); // // Long Cycle Slow ... SetIndexLabel(lcSlowBufferIndex, "LCSlow"); SetIndexBuffer(lcSlowBufferIndex, lcSlowBuffer); SetIndexDrawBegin(lcSlowBufferIndex, longCycleSlowLength); SetIndexStyle( lcSlowBufferIndex, DRAW_LINE, STYLE_DOT, 1, showLongCycle ? longCycleSlowColor : clrNONE ); // // Market Middleage ... SetIndexBuffer(midBufferIndex, midBuffer); SetIndexDrawBegin(midBufferIndex, marketLength); SetIndexLabel(midBufferIndex, "Market Mid"); // // Parabolic Sar ... SetIndexBuffer(pSarBufferIndex, pSarBuffer); SetIndexLabel(pSarBufferIndex, "P Sar"); SetIndexStyle( pSarBufferIndex, DRAW_LINE, STYLE_DOT, 1, showPSar ? pSarColor : clrNONE ); // // Market Middle ... SetIndexBuffer(midBufferIndex, midBuffer); SetIndexLabel(midBufferIndex, "Mid"); SetIndexStyle( midBufferIndex, DRAW_LINE, STYLE_DOT, 1, showMarketMiddle ? clrAntiqueWhite : clrNONE ); // // initialization done ... return(INIT_SUCCEEDED); } // // DeInitialization ... void OnDeinit(const int reason) { // RemoveDraws(logTag); } // // Do Calculation ... int OnCalculate( const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[] ) { // // this counts Available Bars ... int limit; // // because in some cases we may have more than one input for // calculation and we must prevent any calculation // untill we pass the biggest input length, here we get max Input length // and then wait until pass it ... int maxLength = MathMax(marketLength, longCycleSlowLength); // // input variable, we return 0 means nothing passed ... if (rates_total < maxLength) { return 0; } // // found which candles calculated before ... limit = (prev_calculated == 0) ? rates_total - maxLength - 1 : rates_total - prev_calculated + 1; // // this is the main loop of calculations, for each bar index ... for (int i = limit - 1; i >= 0; i--) { // // Start Calculation here ... // i is bar_index ... // // Calculate Short Cycle ... CalculateShortCycle(i); // // Calculate Medium Cycle ... CalculateMediumCycle(i); // // Calculate Long Cycle ... CalculateLongCycle(i); // // Calculate Market Middleage ... CalculateMarketMiddleage(i); // // Calculate Cross Points ... CalculateCrossPoints(i); // // Calculate Parabolic Sar ... CalculateParabolicSar(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Calculate Short Cycle ... void CalculateShortCycle( const int bar_index ) { // // Fast ... double shortCycleFast = iMA( _Symbol, _Period, shortCycleFastLength, 0, MODE_SMA, PRICE_WEIGHTED, bar_index ); scFastBuffer[bar_index] = shortCycleFast; // // Slow ... double shortCycleSlow = iMA( _Symbol, _Period, shortCycleSlowLength, 0, MODE_SMA, PRICE_WEIGHTED, bar_index ); scSlowBuffer[bar_index] = shortCycleSlow; } // // Calculate Medium Cycle ... void CalculateMediumCycle( const int bar_index ) { // // Fast ... double mediumCycleFast = iMA( _Symbol, _Period, mediumCycleFastLength, 0, MODE_SMA, PRICE_MEDIAN, bar_index ); mcFastBuffer[bar_index] = mediumCycleFast; // // Slow ... double mediumCycleSlow = iMA( _Symbol, _Period, mediumCycleSlowLength, 0, MODE_SMA, PRICE_MEDIAN, bar_index ); mcSlowBuffer[bar_index] = mediumCycleSlow; } // // Calculate Long Cycle ... void CalculateLongCycle( const int bar_index ) { // // Fast ... double longCycleFast = iMA( _Symbol, _Period, longCycleFastLength, 0, MODE_SMA, PRICE_CLOSE, bar_index ); lcFastBuffer[bar_index] = longCycleFast; // // Slow ... double longCycleSlow = iMA( _Symbol, _Period, longCycleSlowLength, 0, MODE_SMA, PRICE_CLOSE, bar_index ); lcSlowBuffer[bar_index] = longCycleSlow; } // // Calculate Market Middleage ... void CalculateMarketMiddleage( const int bar_index ) { // // Mid ... double marketMiddleage = iMA( _Symbol, _Period, (int)(marketLength * 1.5), 0, MODE_EMA, PRICE_MEDIAN, bar_index ); midBuffer[bar_index] = marketMiddleage; } // // Calculate Cross Points and Draw Section Line on theme ... void CalculateCrossPoints( const int bar_index ) { // // START Draw Cross Lines ... // // // Short Cycle ... bool isSCFastCrossOverSlow = scFastBuffer[bar_index] > scSlowBuffer[bar_index] && !(scFastBuffer[bar_index + 1] > scSlowBuffer[bar_index + 1]); // bool isSCFastCrossUnderSlow = scFastBuffer[bar_index] < scSlowBuffer[bar_index] && !(scFastBuffer[bar_index + 1] < scSlowBuffer[bar_index + 1]); // // Medium Cycle ... bool isMCFastCrossOverSlow = mcFastBuffer[bar_index] > mcSlowBuffer[bar_index] && !(mcFastBuffer[bar_index + 1] > mcSlowBuffer[bar_index + 1]); // bool isMCFastCrossUnderSlow = mcFastBuffer[bar_index] < mcSlowBuffer[bar_index] && !(mcFastBuffer[bar_index + 1] < mcSlowBuffer[bar_index + 1]); // // Long Cycle ... bool isLCFastCrossOverSlow = lcFastBuffer[bar_index] > lcSlowBuffer[bar_index] && !(lcFastBuffer[bar_index + 1] > lcSlowBuffer[bar_index + 1]); // bool isLCFastCrossUnderSlow = lcFastBuffer[bar_index] < lcSlowBuffer[bar_index] && !(lcFastBuffer[bar_index + 1] < lcSlowBuffer[bar_index + 1]); // // START Drawing CrossPoints ... // // datetime currentTime = iTime( _Symbol, _Period, bar_index ); // if (showShortCycleCrossLines) { // // Draw Line ... if (isSCFastCrossOverSlow) { // string lbl = StringConcatenate( logTag, "_SC_F_OV_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showShortCycleCrossLines ? shortCycleFastColor : clrNONE ); } // // Draw Line ... if (isSCFastCrossUnderSlow) { // string lbl = StringConcatenate( logTag, "_SC_F_UN_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showShortCycleCrossLines ? shortCycleSlowColor : clrNONE ); } } // if (showMediumCycleCrossLines) { // // Draw Line ... if (isMCFastCrossOverSlow) { // string lbl = StringConcatenate( logTag, "_MC_F_OV_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showMediumCycleCrossLines ? mediumCycleFastColor : clrNONE ); } // // Draw Line ... if (isMCFastCrossUnderSlow) { // string lbl = StringConcatenate( logTag, "_MC_F_UN_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showMediumCycleCrossLines ? mediumCycleSlowColor : clrNONE ); } } // if (showLongCycleCrossLines) { // // Draw Line ... if (isLCFastCrossOverSlow) { // string lbl = StringConcatenate( logTag, "_LC_F_OV_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showLongCycleCrossLines ? longCycleFastColor : clrNONE ); } // // Draw Line ... if (isLCFastCrossUnderSlow) { // string lbl = StringConcatenate( logTag, "_LC_F_UN_S_", currentTime ); // DrawVerticalLine( 0, lbl, 0, currentTime, showLongCycleCrossLines ? longCycleSlowColor : clrNONE ); } } // // END Drawing CrossPoints ... // } void CalculateParabolicSar( const int bar_index ) { // double sarValue = iSAR( NULL, _Period, step, maximum, bar_index ); // pSarBuffer[bar_index] = sarValue; } // // END Functions ... //