///////////////////////////////////////////////////////////////// // // SaherElm IT Center OSC Indicator // ------------------------------------------------------------- // this indicator provides OSC ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // //////////////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm OSC Indicator" #property strict // // START 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 // // END Inputs ... // // // START Global Definitions: Variables, Properties and etc ... // // // Includes our shared library ... #include "../Libraries/x-saherelm.lib.mq4" // #property indicator_separate_window // // we have 2 buffer in this indicator ... #property indicator_buffers 2 // // also we have 2 line for draw on this indicator ... #property indicator_plots 2 // // Fast OSC ... #property indicator_width1 1 #property indicator_color1 clrAqua #property indicator_type1 DRAW_LINE #property indicator_style1 STYLE_SOLID // // Slow OSC ... #property indicator_width2 1 #property indicator_type2 DRAW_LINE #property indicator_color2 clrFuchsia #property indicator_style2 STYLE_SOLID // // set color of horizontal levels ... #property indicator_levelcolor clrGray // // set style of horizontal levels ... #property indicator_levelstyle STYLE_DOT // // Declare Buffers ... #define fastOSCBufferIndex 0 #define slowOSCBufferIndex 1 // double fastOSCBuffer[]; double slowOSCBuffer[]; // // Used Indicators List ... string rmaIndicatorName = "x-saherelm.rma"; // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Initialize what we want ... // // Validating Input Parameters ... if ( fastOSCLength < 0 || slowOSCLength < 0 || slowOSCLength <= fastOSCLength ) { return INIT_PARAMETERS_INCORRECT; } // // here we specify logging enabled or not ... enableLogging = true; // // this is a Tag which attached to our Logger ... logTag = "XS_OSC"; // // set descriptions of horizontal levels ... SetLevelValue(0, 0.0); IndicatorSetString(INDICATOR_LEVELTEXT,0,""); // // set descriptions of horizontal levels ... SetLevelValue(1, 0.5); IndicatorSetString(INDICATOR_LEVELTEXT,1,""); // // set descriptions of horizontal levels ... SetLevelValue(2, 1); IndicatorSetString(INDICATOR_LEVELTEXT,2,""); // // Fast OSC Buffer ... SetIndexBuffer(fastOSCBufferIndex, fastOSCBuffer); SetIndexLabel(fastOSCBufferIndex, "Fast OSC"); SetIndexDrawBegin(fastOSCBufferIndex, fastOSCLength - 1); // // Slow OSC Buffer ... SetIndexBuffer(slowOSCBufferIndex, slowOSCBuffer); SetIndexLabel(slowOSCBufferIndex, "Slow OSC"); SetIndexDrawBegin(slowOSCBufferIndex, slowOSCLength - 1); // return(INIT_SUCCEEDED); } // // 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(fastOSCLength, slowOSCLength); // // 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 ... // CalculateOscillators(close, i); } // return rates_total; } // // De Initialization ... void OnDeinit(const int reason) { } // // END Event Handlers ... // // // START Functions ... // // void CalculateOscillators( const double &close[], const int &bar_index ) { // // FastOSC ... // Short Cycle Calculations ... int scl = fastOSCLength / 2; int scl2 = scl / 2; double maScl = iCustom(_Symbol, _Period, rmaIndicatorName, scl, 0, bar_index); double scmAtr = iATR(_Symbol, _Period, scl, bar_index); double scmOff = fastOSCMultiplier * scmAtr; double maScl2 = iCustom(_Symbol, _Period, rmaIndicatorName, scl2, 0, bar_index); double sctParam = maScl2 != 0 ? maScl2 : close[bar_index + 1]; double sct = sctParam + scmOff; double scb = sctParam - scmOff; // // SlowOSC ... // Medium Cycle Calculations ... int mcl = slowOSCLength / 2; int mcl2 = mcl / 2; double maMcl = iCustom(_Symbol, _Period, rmaIndicatorName, mcl, 0, bar_index); double mcmAtr = iATR(_Symbol, _Period, mcl, bar_index); double mcmOff = slowOSCMultiplier * mcmAtr; double maMcl2 = iCustom(_Symbol, _Period, rmaIndicatorName, mcl2, 0, bar_index); double mctParam = maMcl2 != 0 ? maMcl2 : close[bar_index + 1]; double mct = mctParam + mcmOff; double mcb = mctParam - mcmOff; // double scMM = (sct + scb) / 2; // double fastOCS = (close[bar_index] - mcb) / (mct - mcb); fastOSCBuffer[bar_index] = fastOCS; // double slowOCS = (scMM - mcb) / (mct - mcb); slowOSCBuffer[bar_index] = slowOCS; } // // END Functions ... //