一个均线指标

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrDodgerBlue
#property indicator_color3 clrDodgerBlue

#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_SOLID
#property indicator_style3 STYLE_DOT


// Input parameters of indicator
extern ENUM_TIMEFRAMES          i_tf                      = PERIOD_D1;                              // Older TF / Старший ТФ
extern uint                     i_maPeriod                = 3;                                      // MA period / Период МА
extern int                      i_maShift                 = 0;                                      // MA shift / Смещение МА
extern ENUM_MA_METHOD           i_maMethod                = MODE_EMA;                               // МА method / Метод МА
extern ENUM_APPLIED_PRICE       i_maPrice                 = PRICE_TYPICAL;                          // MA price / Цена МА
extern int                      i_indBarsCount            = 1000;                                   // Show bars amount / Кол-во баров отображения

// Other global variables of indicator
bool              g_activate;                                                                      // Sign of successful initialization of indicator

string            g_strTF;
       
double g_upEnvelope[];
double g_dnEnvelope[];
double g_mdEnvelope[];


double g_olderTFResValues[];
double g_olderTFSuppValues[];

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   g_activate = false;                                                                             
   
   if (i_tf < (ENUM_TIMEFRAMES)Period())
   {
      Print("индикатор не работает на таймфреймах, не являющимися старшими по отношению к текущему таймфрейму.");
      return INIT_SUCCEEDED;
   }

   if (!IsTuningParametersCorrect())                                                               
      return INIT_FAILED;  
      
   if(!BuffersBind())
      return INIT_FAILED;        
      
   g_strTF = TFToString(i_tf) + "_";
   g_activate = true;                                                                              
   return INIT_SUCCEEDED;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Checking the correctness of input parameters                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTuningParametersCorrect()
{
   string name = MQLInfoString(MQL_PROGRAM_NAME);
  
   if (ArrayResize(g_olderTFResValues, i_maPeriod) < 0)
   {
      Alert(name, ": не удалось распределить память для массива. Индикатор отключен.");
      return false;
   }

   if (ArrayResize(g_olderTFSuppValues, i_maPeriod) < 0)
   {
      Alert(name, ": не удалось распределить память для массива. Индикатор отключен.");
      return false;
   }
   
   ArraySetAsSeries(g_olderTFResValues, true);
   ArraySetAsSeries(g_olderTFSuppValues, true);

   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Bind the arrays with indicators buffers                                                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool BuffersBind()
{
   string name = MQLInfoString(MQL_PROGRAM_NAME);
   bool isRussianLang = (TerminalInfoString(TERMINAL_LANGUAGE) == "Russian");

   if (!SetIndexBuffer(0, g_upEnvelope) ||
       !SetIndexBuffer(1, g_dnEnvelope) ||
       !SetIndexBuffer(2, g_mdEnvelope))
   {
      Alert(name,(isRussianLang)? ": ошибка связывания массивов с буферами индикатора. Ошибка №"+IntegerToString(GetLastError()) :
            ": error of binding of the arrays and the indicator buffers. Error N"+IntegerToString(GetLastError()));
      return false;
   }

   //--- Set the type of indicator's buffer
   for (int i = 0; i < 3; i++)
      SetIndexStyle(i, DRAW_LINE);

   SetIndexLabel(0, "Upper line");      
   SetIndexLabel(1, "Lower line");      
   SetIndexLabel(2, "Middley line");      
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Cast the timeframe value to the string                                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string TFToString(int tf)
{
   switch(tf)
   {
      case PERIOD_M1:      return "M1";
      case PERIOD_M5:      return "M5";
      case PERIOD_M15:     return "M15";
      case PERIOD_M30:     return "M30";
      case PERIOD_H1:      return "H1";
      case PERIOD_H4:      return "H4";
      case PERIOD_D1:      return "D1";
      case PERIOD_W1:      return "W1";
      case PERIOD_MN1:     return "MN1";
   }
   
   if (tf % PERIOD_MN1 == 0)
      return "MN" + IntegerToString(tf / PERIOD_MN1);

   if (tf % PERIOD_W1 == 0)
      return "W" + IntegerToString(tf / PERIOD_W1);

   if (tf % PERIOD_D1 == 0)
      return "D" + IntegerToString(tf / PERIOD_D1);

   if (tf % PERIOD_H1 == 0)
      return "H" + IntegerToString(tf / PERIOD_H1);

   return "M" + IntegerToString(tf / 60);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Support the tf data in actual state                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool IsTFDataReady(ENUM_TIMEFRAMES tf)
{
   iTime(NULL, tf, 1);
   return GetLastError() == ERR_NO_ERROR;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Determination of bar index which needed to recalculate                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex(int& total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - 1;                                                                         
                                                   
   if (i_indBarsCount > 0 && i_indBarsCount < total)
      total = MathMin(i_indBarsCount, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      InitializeBuffers();
      return (total);
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Initialize of all indicator buffers                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void InitializeBuffers()
{
   ArrayInitialize(g_upEnvelope, EMPTY_VALUE);
   ArrayInitialize(g_dnEnvelope, EMPTY_VALUE);
   ArrayInitialize(g_mdEnvelope, EMPTY_VALUE);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Process specified bar index                                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessBar(int barIndex)
{
   int olderTFBarIndex = iBarShift(NULL, i_tf, iTime(NULL, 0, barIndex));
   
   double typeValue = 0.0;
   for (int i = (int)i_maPeriod - 1; i >= 0; i--)
   {
      int tfIndex = i + olderTFBarIndex;
      typeValue = ((iHigh(NULL, i_tf, tfIndex) + iLow(NULL, i_tf, tfIndex) + iClose(NULL, i_tf, tfIndex)) * 2) / 3;
      g_olderTFSuppValues[i] = typeValue - iHigh(NULL, i_tf, tfIndex);
      g_olderTFResValues[i] = typeValue - iLow(NULL, i_tf, tfIndex);      
   }
   
   g_upEnvelope[barIndex] = iMAOnArray(g_olderTFResValues, 0, i_maPeriod, i_maShift, i_maMethod, 0);
   g_mdEnvelope[barIndex] = iMA(NULL, i_tf, i_maPeriod, i_maShift, i_maMethod, i_maPrice, olderTFBarIndex);
   g_dnEnvelope[barIndex] = iMAOnArray(g_olderTFSuppValues, 0, i_maPeriod, i_maShift, i_maMethod, 0);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Displaying of indicators values                                                                                                                                                                   |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool ShowIndicatorData(int limit, int total)
{
   int olderTFBarIndex = iBarShift(NULL, i_tf, iTime(NULL, 0, limit));
   limit = iBarShift(NULL, 0, iTime(NULL, i_tf, olderTFBarIndex));

   // Обработка новых баров
   for (int i = limit; i >= 0; i--)
      ProcessBar(i);
         
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| 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 (!g_activate)                                                                                
      return rates_total; 
      
   if (!IsTFDataReady(i_tf))
      return rates_total;                                

   int total;   
   int limit = GetRecalcIndex(total, rates_total, prev_calculated);                                

   if (!ShowIndicatorData(limit, total))
      g_activate = false;
   
   return rates_total;
}

写法娴熟,可供借鉴


本博客所有文章如无特别注明均为原创。作者:天泓评测
分享到:更多

相关推荐

发表评论

路人甲 表情
Ctrl+Enter快速提交

网友评论(0)