//+------------------------------------------------------------------+
//|                                                         OsMA.mq4 |
//|                   Copyright 2005-2022, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2022, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Moving Averages of Oscillator"
#property strict

#include <MovingAverages.mqh>

//--- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 1
#property  indicator_color1  clrLime
#property  indicator_width1  2
//--- indicator parameters
input int InpFastEMA=12;   // Fast EMA Period
input int InpSlowEMA=26;   // Slow EMA Period
input int InpSignalSMA=9;  // Signal SMA Period


//Forex-Station button template start41; copy and paste
input string             button_note1          = "------------------------------";
input int                btn_Subwindow         = 0;
input ENUM_BASE_CORNER   btn_corner            = CORNER_LEFT_UPPER; 
input string             btn_text              = "OsMA";
input string             btn_Font              = "Arial";
input int                btn_FontSize          = 9;                        
input color              btn_text_ON_color     = clrLime;
input color              btn_text_OFF_color    = clrRed;
input color              btn_background_color  = clrDimGray;
input color              btn_border_color      = clrBlack;
input int                button_x              = 180;                                   
input int                button_y              = 45;                                   
input int                btn_Width             = 80;                                
input int                btn_Height            = 20;
input string             soundBT               = "tick.wav";        // sound file when the button is pressed
input string             UniqueButtonID        = "OsMAbutton";                               
input string             button_note2          = "------------------------------";

bool show_data = true, recalc = true;
string indicatorFileName, IndicatorName, IndicatorObjPrefix,buttonId;
//Forex-Station button template end41; copy and paste


//--- indicator buffers
double ExtOsmaBuffer[], ExtMacdBuffer[], ExtSignalBuffer[];
//--- right input parameters flag
bool   ExtParameters=false;
//+------------------------------------------------------------------------------------------------------------------+
//Forex-Station button template start42; copy and paste
string GenerateIndicatorName(const string target) 
{
   string name = target;
   int try = 2;
   while (WindowFind(name) != -1)
      name = target + " #" + IntegerToString(try++);
   return name;
}
//+------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   IndicatorName = GenerateIndicatorName(btn_text);
   IndicatorObjPrefix = "__" + IndicatorName + "__";
   
   double val;
   if (GlobalVariableGet(IndicatorName + "_visibility", val))
      show_data = val != 0;

   indicatorFileName = WindowExpertName();
   
   ChartSetInteger(ChartID(), CHART_EVENT_MOUSE_MOVE, 1);
   buttonId = IndicatorObjPrefix + UniqueButtonID;
   createButton(buttonId, btn_text, btn_Width, btn_Height, btn_Font, btn_FontSize, btn_background_color, btn_border_color, btn_text_ON_color);
   ObjectSetInteger(ChartID(), buttonId, OBJPROP_YDISTANCE, button_y);
   ObjectSetInteger(ChartID(), buttonId, OBJPROP_XDISTANCE, button_x);
   
// put init() here
   init2();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason) { 
     ObjectsDeleteAll(ChartID(), buttonId);
}
//+------------------------------------------------------------------+
void createButton(string buttonID,string buttonText,int width2,int height,string font,int fontSize,color bgColor,color borderColor,color txtColor)
{
      ObjectDelete    (ChartID(),buttonID);
      ObjectCreate    (ChartID(),buttonID,OBJ_BUTTON,btn_Subwindow,0,0);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_COLOR,txtColor);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_BGCOLOR,bgColor);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_BORDER_COLOR,borderColor);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_BORDER_TYPE,BORDER_RAISED);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_XSIZE,width2);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_YSIZE,height);
      ObjectSetString (ChartID(),buttonID,OBJPROP_FONT,font);
      ObjectSetString (ChartID(),buttonID,OBJPROP_TEXT,buttonText);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_FONTSIZE,fontSize);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_SELECTABLE,0);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_CORNER,btn_corner);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_HIDDEN,1);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_XDISTANCE,9999);
      ObjectSetInteger(ChartID(),buttonID,OBJPROP_YDISTANCE,9999);
}
//+------------------------------------------------------------------+
void handleButtonClicks()
{
   if (ObjectGetInteger(ChartID(), buttonId, OBJPROP_STATE))
   {
      ObjectSetInteger(ChartID(), buttonId, OBJPROP_STATE, false);
      show_data = !show_data;
      GlobalVariableSet(IndicatorName + "_visibility", show_data ? 1.0 : 0.0);
      recalc = true;
   }
}
//+------------------------------------------------------------------------------------------------------------------+
void OnChartEvent(const int id, 
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   handleButtonClicks();
   if (id==CHARTEVENT_OBJECT_CLICK && ObjectGet(sparam,OBJPROP_TYPE)==OBJ_BUTTON)
      if (soundBT!="") PlaySound(soundBT);     

      if (show_data)
         {
          ObjectSetInteger(ChartID(),buttonId,OBJPROP_COLOR,btn_text_ON_color);
          init2();
         }
      else
      {
       ObjectSetInteger(ChartID(),buttonId,OBJPROP_COLOR,btn_text_OFF_color);
       for (int banzai=0; banzai<indicator_buffers; banzai++)
           SetIndexStyle(banzai,DRAW_NONE);
      }
}
//Forex-Station button template end42; copy and paste
//+------------------------------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init2(void)
  {
//--- 2 additional buffers are used for counting.
   IndicatorBuffers(3);
//--- drawing settings
   SetIndexStyle(0,DRAW_HISTOGRAM);
   SetIndexDrawBegin(0,InpSignalSMA);
   IndicatorDigits(Digits+2);

//--- 3 indicator buffers mapping
   SetIndexBuffer(0,ExtOsmaBuffer);
   SetIndexBuffer(1,ExtMacdBuffer);
   SetIndexBuffer(2,ExtSignalBuffer);
//--- name for DataWindow and indicator subwindow label
   IndicatorShortName("OsMA("+IntegerToString(InpFastEMA)+","+IntegerToString(InpSlowEMA)+","+IntegerToString(InpSignalSMA)+")");
//--- check for input parameters
   if(InpFastEMA<=1 || InpSlowEMA<=1 || InpSignalSMA<=1 || InpFastEMA>=InpSlowEMA)
     {
      Print("Wrong input parameters");
      ExtParameters=false;
      return(INIT_FAILED);
     }
   else
      ExtParameters=true;
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Moving Average of Oscillator                                     |
//+------------------------------------------------------------------+
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[])
  {
   int i,limit;
//---
   if(rates_total<=InpSignalSMA || !ExtParameters)
      return(0);
//--- last counted bar will be recounted
   limit=rates_total-prev_calculated;
   if(prev_calculated>0)
      limit++;
//--- macd counted in the 1-st buffer
   for(i=0; i<limit; i++)
      ExtMacdBuffer[i]=iMA(NULL,0,InpFastEMA,0,MODE_EMA,PRICE_CLOSE,i)-
                    iMA(NULL,0,InpSlowEMA,0,MODE_EMA,PRICE_CLOSE,i);
//--- signal line counted in the 2-nd buffer
   SimpleMAOnBuffer(rates_total,prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
//--- main loop
   for(i=0; i<limit; i++)
      ExtOsmaBuffer[i]=ExtMacdBuffer[i]-ExtSignalBuffer[i];
//--- done
   return(0);
  }
//+------------------------------------------------------------------+
