Как использовать OnCalculate в советнике?

 
//+------------------------------------------------------------------+
//|                                                     Demo_iMA.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iMA technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (function type)."
#property description "All other parameters like in the standard Moving Average."

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- the iMA plot
#property indicator_label1  "iMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

int last_position = -1;
CTrade mytrade;
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation                    |
//+------------------------------------------------------------------+
enum Creation
  {
   Call_iMA,               // use iMA
   Call_IndicatorCreate    // use IndicatorCreate
  };

struct trade_order
  {
   string            symbols_name;
   double            take_profit;
   double            stop_loss;
   double            open_price;
   double            volume;
   int               type_terminal;
  };

//--- input parameters
input Creation             type=Call_iMA;                // type of the function
input int                  ma_period=10;                 // period of ma
input int                  ma_shift=0;                   // shift
input ENUM_MA_METHOD       ma_method=MODE_SMA;           // type of smoothing
input ENUM_APPLIED_PRICE   applied_price=PRICE_CLOSE;    // type of price
input string               symbol=" ";                   // symbol
input ENUM_TIMEFRAMES      period=PERIOD_CURRENT;        // timeframe

datetime last_time;
//--- indicator buffer
double         iMABuffer[];
//---переменная для хранения ручки индикатора iMA
int    handle;
//--- переменная для хранения
string name=symbol;
//--- название индикатора на графике
string short_name;
//--- мы сохраним количество значений в индикаторе Скользящей средней
int    bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- назначение массива индикаторному буферу
   SetIndexBuffer(0,iMABuffer,INDICATOR_DATA);
//--- установить сдвиг
   PlotIndexSetInteger(0,PLOT_SHIFT,ma_shift);
//--- определите символ, для которого рисуется индикатор
   name=symbol;
//---удалите пробелы справа и слева
   StringTrimRight(name);
   StringTrimLeft(name);
//--- если это приведет к нулевой длине строки "имя"
   if(StringLen(name)==0)
     {
      //--- возьмите символ графика, к которому прикреплен индикатор
      name=_Symbol;
     }
//--- создайте дескриптор индикатора
   if(type==Call_iMA)
      handle=iMA(name,period,ma_period,ma_shift,ma_method,applied_price);
   else
     {
      //---заполните структуру параметрами индикатора
      MqlParam pars[4];
      //--- период
      pars[0].type=TYPE_INT;
      pars[0].integer_value=ma_period;
      //--- сдвиг
      pars[1].type=TYPE_INT;
      pars[1].integer_value=ma_shift;
      //---тип сглаживания
      pars[2].type=TYPE_INT;
      pars[2].integer_value=ma_method;
      //--- тип цены
      pars[3].type=TYPE_INT;
      pars[3].integer_value=applied_price;
      handle=IndicatorCreate(name,period,IND_MA,4,pars);
     }
//--- если дескриптор не создан
   if(handle==INVALID_HANDLE)
     {
      //--- расскажите о сбое и выведите код ошибки
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  name,
                  EnumToString(period),
                  GetLastError());
      //--- индикатор рано останавливается
      return(INIT_FAILED);
     }
//--- показать символ/таймфрейм, для которого рассчитывается индикатор скользящей средней
   short_name=StringFormat("iMA(%s/%s, %d, %d, %s, %s)",name,EnumToString(period),
                           ma_period, ma_shift,EnumToString(ma_method),EnumToString(applied_price));
   IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- нормальная инициализация индикатора
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Функция итерации пользовательского индикатора                    |
//+------------------------------------------------------------------+
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 size = ArraySize(time)-1;
   if(time[size] > last_time && PositionsTotal() == 0)
     {
      //--- количество значений, скопированных с индикатора iMA
      int values_to_copy;
      //--- определите количество значений, рассчитанных в индикаторе
      int calculated=BarsCalculated(handle);
      if(calculated<=0)
        {
         PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
         return(0);
        }
      //--- если это первый запуск расчета индикатора или если количество значений в индикаторе iMA изменилось
      //---или если необходимо рассчитать индикатор для двух или более баров (это означает, что что-то изменилось в истории цен)
      if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
        {
         //--- если массив iMABuffer больше, чем количество значений в индикаторе iMA для символа/периода, то мы не копируем все
         //--- в противном случае мы копируем меньше, чем размер индикаторных буферов
         if(calculated>rates_total)
            values_to_copy=rates_total;
         else
            values_to_copy=calculated;
        }
      else
        {
         //--- это означает, что это не первый раз расчета индикатора, и с момента последнего вызова OnCalculate()
         //--- для расчета добавляется не более одного бара
         values_to_copy=(rates_total-prev_calculated)+1;
        }
      //---заполните массив iMABuffer значениями индикатора Скользящей средней
      //--- если FillArrayFromBuffer возвращает false, это означает, что информация еще не готова, завершите операцию
      if(!FillArrayFromBuffer(iMABuffer,ma_shift,handle,values_to_copy))
         return(0);
      //--- form the message
      string comm=StringFormat("%s ==>  Updated value in the indicator %s: %d",TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),short_name,values_to_copy);
      //--- отображение служебного сообщения на диаграмме
      Comment(comm);
      //--- запомните количество значений в индикаторе скользящей средней
      bars_calculated=calculated;
      //--- верните значение prev_calculated для следующего вызова
      last_time = time[size];
      Print("Bar closed, high:",high[size-1]," open:",open[size-1]," close: ",close[size-1]," low:",low[size-1]);
      Print("MA ",iMABuffer[size]);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
return(rates_total);
  }
//+------------------------------------------------------------------+
//| Заполнение индикаторных буферов индикатором MA                   |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[],   // индикаторный буфер значений скользящей средней
                         int shift,          // сдвиг
                         int ind_handle,     // ручка индикатора iMA
                         int amount          // количество скопированных значений
                        )
  {
//--- reset error code
   ResetLastError();
//--- заполните часть массива iMABuffer значениями из индикаторного буфера с индексом 0
   if(CopyBuffer(ind_handle,0,-shift,amount,values)<0)
     {
      //--- если копирование завершится неудачно, сообщите код ошибки
      PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
      //---выйти с нулевым результатом - это означает, что показатель считается не рассчитанным
      return(false);
     }
//--- все хорошо
   return(true);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(handle!=INVALID_HANDLE)
      IndicatorRelease(handle);
//--- clear the chart after deleting the indicator
   Comment("");
  }

У меня есть код индикатора, я хочу модифицировать его в советник, но как я понял нельзя использовать OnCalculate в советнике (идиотизм по мне дак) 

Собственно как мне быть? - как преобразовать это в советник? но оставить возможность отрисовки индикатора?

Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
Открой новые возможности в MetaTrader 5 с сообществом и сервисами MQL5
  • www.mql5.com
MQL5: язык торговых стратегий для MetaTrader 5, позволяет писать собственные торговые роботы, технические индикаторы, скрипты и библиотеки функций
 
оставьте индикатор в покое и напишите отдельный советник подгружая данные индикатора через iCustom
 

  OnCalculate , используется только при кодировании индикатора. На ваш индикатор можно ссылаться в советнике с помощью icustom. Эта ссылка может помочь вам понять, как функции индикатора используются в советнике с использованием MetaTrader5. https://www.mql5.com/ru/articles/31.

Создание советников при помощи Expert Advisor Visual Wizard
Создание советников при помощи Expert Advisor Visual Wizard
  • www.mql5.com
Программа Expert Advisor Visual Wizard предоставляет интуитивно понятную графическую среду с полным набором готовых торговых блоков, которые позволят вам за несколько минут создавать советники. Знания программирования и языка MQL5 не требуется. Подход "click, drag and drop" позволяет вам создавать визуальные представления торговых стратегий и сигналов. Эти торговые диаграммы автоматически анализируются генератором MQL5-кода, который преобразует их в готовые к работе советники. Интерактивная графическая среда упрощает процесс проектирования и избавляет от необходимости написания кода на MQL5.
 
Да спасибо разобрался
 
Если у вас возникают вопросы по поводу использования индикатора прямо в советнике - советую вначале изучить принципы ООП и плохого кода. Хотя это не совсем из той оперы, но эти же принципы так же работают и в этом вопросе.
Причина обращения: