My_Custom_Stochastic_Oscillator.mq4

 

Hi, 

I need some help here. 

I want to add stochastic oscillator with these custom levels with MQL4 to MT4. 
I am also changing chart colour and candle stick colours,

When even I attach my custom stochastic indicator, I have to open and close settings manualy before it starts to work. 
Any idea as to what I'm doing wrong?   

#property version   "1.00"
#property strict
#property indicator_separate_window

#property indicator_buffers 2
#property indicator_color1 clrDarkBlue
#property indicator_color2 clrRed
#property indicator_level1 11
#property indicator_level2 23
#property indicator_level3 38.2
#property indicator_level4 50
#property indicator_level5 61.8
#property indicator_level6 77
#property indicator_level7 90

// Buffers for Stochastic Oscillator
double K_Buffer[];
double D_Buffer[];

// Input parameters
input int K_Period = 50;
input int D_Period = 24;
input int Slowing = 1;
input ENUM_MA_METHOD Method = MODE_SMA;
input ENUM_APPLIED_PRICE PriceField = PRICE_CLOSE;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorShortName("Stochastic Oscillator");

   // Bind buffers
   SetIndexBuffer(0, K_Buffer);
   SetIndexBuffer(1, D_Buffer);

   // Set styles
   SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1, clrDarkBlue);
   SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1, clrRed);

   // Add levels manually
   CreateLevel("Level_11", 11);
   CreateLevel("Level_23", 23);
   CreateLevel("Level_38_2", 38.2);
   CreateLevel("Level_50", 50);
   CreateLevel("Level_61_8", 61.8);
   CreateLevel("Level_77", 77);
   CreateLevel("Level_90", 90);

   // Initialize buffers
   ArrayInitialize(K_Buffer, 50.0);
   ArrayInitialize(D_Buffer, 50.0);

   // Set chart properties
   ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrGreen);
   ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrRed);
   // ChartSetInteger(0, CHART_COLOR_BARS_UP, clrGreen); // Property not available in MQL4, remove this line
   // ChartSetInteger(0, CHART_COLOR_BARS_DOWN, clrRed); // Property not available in MQL4, remove this line
   ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite);
   ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack);
   ChartSetInteger(0, CHART_SHOW_GRID, false);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Helper function to create levels                                 |
//+------------------------------------------------------------------+
void CreateLevel(string name, double value)
{
   if (ObjectFind(0, name) == -1)
   {
      ObjectCreate(0, name, OBJ_HLINE, 0, 0, value);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clrSilver);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
   }
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
{
   if (rates_total <= K_Period + D_Period) return(0);

   for (int i = MathMax(prev_calculated - 1, 0); i < rates_total; i++)
   {
      double highestHigh = -DBL_MAX;
      double lowestLow = DBL_MAX;

      for (int j = MathMax(0, i - K_Period + 1); j <= i; j++)
      {
         if (high[j] > highestHigh) highestHigh = high[j];
         if (low[j] < lowestLow) lowestLow = low[j];
      }

      if (highestHigh - lowestLow != 0)
         K_Buffer[i] = 100.0 * (close[i] - lowestLow) / (highestHigh - lowestLow);
      else
         K_Buffer[i] = (i > 0) ? K_Buffer[i - 1] : 50.0;

      D_Buffer[i] = iMAOnArray(K_Buffer, 0, D_Period, 0, Method, i);
   }

   return(rates_total);
}
//+------------------------------------------------------------------+
Documentation on MQL5: Language Basics / Preprocessor / Program Properties (#property)
Documentation on MQL5: Language Basics / Preprocessor / Program Properties (#property)
  • www.mql5.com
Every mql5-program allows to specify additional specific parameters named #property that help client terminal in proper servicing for programs...
 

You are calling ObjectFind() , which checks if the object already exists. If the object already exists, it won't recreate it, but this doesn't refresh the levels if you change the indicator's settings. You could try using ObjectDelete() before creating the levels to ensure they get updated each time.

Something like

void CreateLevel(string name, double value)
{
   if (ObjectFind(0, name) != -1)
      ObjectDelete(name);

   ObjectCreate(0, name, OBJ_HLINE, 0, 0, value);
   ObjectSetInteger(0, name, OBJPROP_COLOR, clrSilver);
   ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
   ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
}

the ChartSetInteger() function should also ideally be placed outside the initialization code

Check behaviour of 

( CHART_COLOR_CANDLE_BULL and CHART_COLOR_CANDLE_BEAR )