///////////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Cycle Channel Oscillator // --------------------------------------------------------- // Name: XCCH // Description: Cycle Channel 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 XCCH Oscillator" #property strict // // START Constants ... // #define ShortName "XCCH" // // Including Models Library ... #include "..\Libraries\x-saherelm.models.lib.mq5" // // END Constants ... // // // START Inputs ... // // input int fastLength = 10; // Fast Length input double fastMultiplier = 1.0; // Fast Multiplier // input int slowLength = 30; // Slow Length input double slowMultiplier = 3.0; // Slow Multiplier // input ENUM_APPLIED_PRICE appliedTo = PRICE_CLOSE; // Source // // END Inputs ... // // // Includes Logging Library ... #include "../Libraries/x-saherelm.log.lib.mq5"; // // Includes Common Library ... #include "../Libraries/x-saherelm.common.lib.mq5"; // // START Buffers ... // #property indicator_separate_window // #property indicator_buffers 6 #property indicator_plots 2 // #define fastBufferIndex 0 #define slowBufferIndex 1 #define fastRMABufferIndex 2 #define slowRMABufferIndex 3 #define fastATRBufferIndex 4 #define slowATRBufferIndex 5 // double fastBuffer[]; double slowBuffer[]; double fastRMABuffer[]; double slowRMABuffer[]; double fastATRBuffer[]; double slowATRBuffer[]; // #property indicator_label1 "XCCH Fast" #property indicator_type1 DRAW_LINE #property indicator_color1 clrAqua #property indicator_style1 STYLE_DOT #property indicator_width1 1 #property indicator_label2 "XCCH Slow" #property indicator_type2 DRAW_LINE #property indicator_color2 clrFuchsia #property indicator_style2 STYLE_DOT #property indicator_width2 1 // // END Buffers ... // // // START Global Definitions: Variables, Properties and etc ... // // int fastRMAHandler = INVALID_HANDLE; int slowRMAHandler = INVALID_HANDLE; int fastATRHandler = INVALID_HANDLE; int slowATRHandler = INVALID_HANDLE; // // END Global Definitions: Variables, Properties and etc ... // // // START Event Handlers ... // // // Initialization ... int OnInit() { // // Validate Inputs ... if (!ValidateInputs()) { return INIT_PARAMETERS_INCORRECT; } // logTag = ShortName; // // Define Index Buffers ... DefineBuffers(); // // Set Indicator ShortName ... SetIndicatorName(); // // Resetting Last Error ... ResetLastError(); // // Initialized Requirements ... // // Fast ATR Handler ... fastATRHandler = iATR( _Symbol, _Period, fastLength / 2); if (fastATRHandler == INVALID_HANDLE) { // LogMessage("ATR Indicator initialization failed: " + (string)GetLastError()); return INIT_FAILED; } // // Slow ATR Handler ... slowATRHandler = iATR( _Symbol, _Period, slowLength / 2); if (slowATRHandler == INVALID_HANDLE) { // LogMessage("ATR Indicator initialization failed: " + (string)GetLastError()); return INIT_FAILED; } // // Fast RMA ... fastRMAHandler = iCustom( _Symbol, _Period, "x-saherelm.xrma.indicator", // // Inputs ... fastLength / 2, appliedTo); if (fastRMAHandler == INVALID_HANDLE) { // LogMessage("XRMA Indicator initialization failed: " + (string)GetLastError()); return INIT_FAILED; } // // Slow RMA ... slowRMAHandler = iCustom( _Symbol, _Period, "x-saherelm.xrma.indicator", // // Inputs ... slowLength / 2, appliedTo); if (fastRMAHandler == INVALID_HANDLE) { // LogMessage("XRMA Indicator initialization failed: " + (string)GetLastError()); return INIT_FAILED; } // // Init Succeed ... return INIT_SUCCEEDED; } // // DeInitialization ... void OnDeinit(const int reason) { // // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function // REASON_REMOVE 1 Program removed from a chart // REASON_RECOMPILE 2 Program recompiled // REASON_CHARTCHANGE 3 A symbol or a chart period is changed // REASON_CHARTCLOSE 4 Chart closed // REASON_PARAMETERS 5 Inputs changed by a user // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings // REASON_TEMPLATE 7 Another chart template applied // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value // REASON_CLOSE 9 Terminal closed // // Here we can handle De Initialization Reasons ... // // ReDraw Chart ... ChartRedraw(); // Comment(""); } // // Calculations ... // // Calculating what we want ... int OnCalculate( // // total Candles on chart ... const int rates_total, // // total calculated Candles on charts ... const int prev_calculated, // // history of Candles Open Time ... const datetime &time[], // // history of Candles Open Price ... const double &open[], // // history of Candles High Price ... const double &high[], // // history of Candles Low Price ... const double &low[], // // history of Candles Close Price ... const double &close[], // // history of Tick Volumes on Candle ... const long &tick_volume[], // // history of Trade Volumes ... const long &volume[], // // history of Candles Spread Price ... const int &spread[]) { // // Prepare Buffers ... ArraySetAsSeries(time, true); ArraySetAsSeries(open, true); ArraySetAsSeries(high, true); ArraySetAsSeries(low, true); ArraySetAsSeries(close, true); ArraySetAsSeries(tick_volume, true); ArraySetAsSeries(volume, true); ArraySetAsSeries(spread, true); // // 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(fastLength, slowLength); maxLength = MathMax(maxLength, 14); // // Get Retrieved Values from indicators ... int fastRMACalculatedBars = BarsCalculated(fastRMAHandler); int slowRMACalculatedBars = BarsCalculated(slowRMAHandler); int fastATRCalculatedBars = BarsCalculated(fastATRHandler); int slowATRCalculatedBars = BarsCalculated(slowATRHandler); // // Check Calculated Bars ... if ( fastRMACalculatedBars < maxLength || slowRMACalculatedBars < maxLength || fastATRCalculatedBars < maxLength || slowATRCalculatedBars < maxLength) { return prev_calculated; } // limit = prev_calculated < maxLength ? rates_total - (maxLength + 1) : rates_total - prev_calculated; // // Copy Buffers from indicators ... int fastRMACopiedItems = CopyBuffer(fastRMAHandler, 0, 0, limit + 1, fastRMABuffer); int slowRMACopiedItems = CopyBuffer(slowRMAHandler, 0, 0, limit + 1, slowRMABuffer); int fastATRCopiedItems = CopyBuffer(fastATRHandler, 0, 0, limit + 1, fastATRBuffer); int slowATRCopiedItems = CopyBuffer(slowATRHandler, 0, 0, limit + 1, slowATRBuffer); // // Check Copied Items Number ... if ( fastRMACopiedItems <= 0 || slowRMACopiedItems <= 0 || fastATRCopiedItems <= 0 || slowATRCopiedItems <= 0) { return prev_calculated; } // // Main Loop ... for (int i = limit; i >= 0 && !IsStopped(); i--) { // CalculateBuffers(i); } // return rates_total; } // // END Event Handlers ... // // // START Functions ... // // // Validate Input Args for Initialization ... bool ValidateInputs() { // bool result = false; // // Validate Args ... if (fastLength >= 4 && slowLength > fastLength) { result = true; } // return result; } // // Define Indexes and Styles ... void DefineBuffers() { // string fastBufferLabel = ShortName + " Fast (" + (string)fastLength + ")"; string slowBufferLabel = ShortName + " Slow (" + (string)slowLength + ")"; // // Fast Buffer ... ArraySetAsSeries(fastBuffer, true); SetIndexBuffer(fastBufferIndex, fastBuffer, INDICATOR_DATA); PlotIndexSetInteger(fastBufferIndex, PLOT_DRAW_BEGIN, fastLength); PlotIndexSetString(fastBufferIndex, PLOT_LABEL, fastBufferLabel); // // Slow Buffer ... ArraySetAsSeries(slowBuffer, true); SetIndexBuffer(slowBufferIndex, slowBuffer, INDICATOR_DATA); PlotIndexSetInteger(slowBufferIndex, PLOT_DRAW_BEGIN, slowLength); PlotIndexSetString(slowBufferIndex, PLOT_LABEL, slowBufferLabel); // // Fast RMA Buffer ... ArraySetAsSeries(fastRMABuffer, true); SetIndexBuffer(fastRMABufferIndex, fastRMABuffer, INDICATOR_CALCULATIONS); // // Slow RMA Buffer ... ArraySetAsSeries(slowRMABuffer, true); SetIndexBuffer(slowRMABufferIndex, slowRMABuffer, INDICATOR_CALCULATIONS); // // Fast ATR Buffer ... ArraySetAsSeries(fastATRBuffer, true); SetIndexBuffer(fastATRBufferIndex, fastATRBuffer, INDICATOR_CALCULATIONS); // // Slow ATR Buffer ... ArraySetAsSeries(slowATRBuffer, true); SetIndexBuffer(slowATRBufferIndex, slowATRBuffer, INDICATOR_CALCULATIONS); } // // Set Indicator Short Name and also we can define Buffers Labels ... void SetIndicatorName() { // string indicatorShortName = ""; StringConcatenate(indicatorShortName, ShortName, ""); // IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName); } // // Calculate Buffers ... void CalculateBuffers(int bar_index) { // // Retrieve RMA Values ... double fastRMA = fastRMABuffer[bar_index]; double slowRMA = slowRMABuffer[bar_index]; // // Calculate Offsetes ... double fastOffset = fastMultiplier * fastATRBuffer[bar_index]; double slowOffset = slowMultiplier * slowATRBuffer[bar_index]; // int hFastLength = fastLength / 2; int hSlowLength = slowLength / 2; int qFastLength = hFastLength / 2; int qSlowLength = hSlowLength / 2; // double price = GetAppliedPrice(bar_index, appliedTo); // // Calculate Fast Top and Bottom ... double fastTOP = (ArraySize(fastRMABuffer) == qFastLength + 1 ? fastRMABuffer[qFastLength] : price) + fastOffset; double fastBOTTOM = (ArraySize(fastRMABuffer) == qFastLength + 1 ? fastRMABuffer[qFastLength] : price) - fastOffset; // // Calculate Slow Top and Bottom ... double slowTOP = (ArraySize(slowRMABuffer) == qSlowLength + 1 ? slowRMABuffer[qSlowLength] : price) + slowOffset; double slowBOTTOM = (ArraySize(slowRMABuffer) == qSlowLength + 1 ? slowRMABuffer[qSlowLength] : price) - slowOffset; // // Fast Average ... double fastAverage = (fastTOP + fastBOTTOM) / 2; // // Calculate Buffer Values ... // // Fast ... double fastValue = (price - slowBOTTOM) / (slowTOP - slowBOTTOM); fastBuffer[bar_index] = fastValue; // // Slow ... double slowValue = (fastAverage - slowBOTTOM) / (slowTOP - slowBOTTOM); slowBuffer[bar_index] = slowValue; } // // END Functions ... //