Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2561

 
Переделываю свой индикатор из mql4 в mql5. 
В  mql4 у меня был массив 
int Arr_TF_Available[9];

содержащий 
   Arr_TF_Available[0] = PERIOD_M1;    // TF M1
   Arr_TF_Available[1] = PERIOD_M5;    // TF M5
   Arr_TF_Available[2] = PERIOD_M15;   // TF M15
   Arr_TF_Available[3] = PERIOD_M30;   // TF M30
   Arr_TF_Available[4] = PERIOD_H1;    // TF H1
   Arr_TF_Available[5] = PERIOD_H4;    // TF H4
   Arr_TF_Available[6] = PERIOD_D1;    // TF D1
   Arr_TF_Available[7] = PERIOD_W1;    // TF W1
   Arr_TF_Available[8] = PERIOD_MN1;   // TF MN1

Насколько я понял в  mql5 такой номер не пройдет, массив должен быть не int, а 
ENUM_TIMEFRAMES Arr_TF_Available[9];

Если распечатать значение элемента массива то например для PERIOD_H4 выдается 16385. 
Попытался применить:
EnumToString(Arr_TF_Available[5])

Получил ' PERIOD_H4 '. 
Но теперь  ' PERIOD_H4 ' на выходе из  EnumToString  уже не integer, а string. 
Получается что для получения integer необходимо еще одно преобразование - StringToInteger ?

Все так или есть более простой способ, как это было в mql4?

PS В коде выполняется проверка типа 

if(Arr_TF_Available[i]>Period() ) {
, а также значения элементов массива подставляются в качестве входных параметров в функциях.
 
grezky #:
Переделываю свой индикатор из mql4 в mql5. 
Покажите код mql4, лучше файлом
 
Tretyakov Rostyslav #:
Покажите код mql4, лучше файлом

Только что пообщался со СБЕР-овским ИИ, он мне объяснил как преобразовывать ENUM_TIMEFRAMES. 
Например он посоветовал:

int old_style_period_value = PeriodSeconds(PERIOD_H4); // Вернет 240

Правда он забыл что секунды надо делить на 60 чтобы получить минуты, но теперь проблема с этим пунктом решена.

 
Решил проверить чем 'DRAW_HISTOGRAM2' отличается от 'DRAW_HISTOGRAM'.
Взял код из документации, а потом его полностью изменил. 
Ниже то что получилось - все работает, буферами рисуются зеленые и красные тела свечей.

#property description "Индикатор для демонстрации DRAW_HISTOGRAM2"
#property description "Рисует на каждом баре отрезок между Open и Close"

#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   2

#property indicator_label1  "Buffer_1"
#property indicator_type1   DRAW_HISTOGRAM2
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  6

#property indicator_label2  "Buffer_2"
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  6

double    Buffer1[];
double    Buffer2[];
double    Buffer3[];
double    Buffer4[];

int OnInit() {
   SetIndexBuffer(0,Buffer1,INDICATOR_DATA);    //--- indicator buffers mapping
   SetIndexBuffer(1,Buffer2,INDICATOR_DATA);
   SetIndexBuffer(2,Buffer3,INDICATOR_DATA);    //--- indicator buffers mapping
   SetIndexBuffer(3,Buffer4,INDICATOR_DATA);

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);                //--- установим пустое значение
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0);                //--- установим пустое значение
   PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0);                //--- установим пустое значение
   PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0);                //--- установим пустое значение

   return(INIT_SUCCEEDED);
} // int OnInit() {


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[]) {

   for(int i=0; i<rates_total; i++) {
      double Price_Open    = open[i];
      double Price_Close   = close[i];

      if(Price_Close >= Price_Open) {
                   Buffer1[i]        = Price_Open;
                   Buffer2[i]        = Price_Close;
          }
          else {
     if(Price_Close < Price_Open) {
                   Buffer3[i]        = Price_Open;
                   Buffer4[i]        = Price_Close;
          }
          }
   } // for(int i=0; i<rates_total; i++) {

   return(rates_total);//--- вернем значение prev_calculated для следующего вызова функции
} // int OnCalculate(const int rates_total,

Не понятно следующее - фактически тело красной свечи рисуется в:
     if(Price_Close < Price_Open) {
		   Buffer3[i]        = Price_Open;

Но 'должно' (предполагалось) рисоваться Buffer2 (где задается красный цвет):
#property indicator_label2  "Buffer_2"
#property indicator_type2   DRAW_HISTOGRAM2
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  6

Пожалуйста объясните как это работает.
 
grezky #:
Решил проверить чем 'DRAW_HISTOGRAM2' отличается от 'DRAW_HISTOGRAM'.
Взял код из документации, а потом его полностью изменил. 
Ниже то что получилось - все работает, буферами рисуются зеленые и красные тела свечей.


Не понятно следующее - фактически тело красной свечи рисуется в:

Но 'должно' (предполагалось) рисоваться Buffer2 (где задается красный цвет):

Пожалуйста объясните как это работает.

Смотрите DRAW_COLOR_HISTOGRAM2

Документация по MQL5: Пользовательские индикаторы / Стили индикаторов в примерах / DRAW_COLOR_HISTOGRAM2
Документация по MQL5: Пользовательские индикаторы / Стили индикаторов в примерах / DRAW_COLOR_HISTOGRAM2
  • www.mql5.com
Стиль DRAW_COLOR_HISTOGRAM2 рисует заданным гистограмму – вертикальные отрезки по значениям двух индикаторных буферов. Но в отличие от одноцветного...
 
Alexey Viktorov #:
Смотрите DRAW_COLOR_HISTOGRAM2

Попытался упростить и изменить код по Вашему линку, но не получилось, рисует только одним цветом. 
Пожалуйста посмотрите как исправить чтобы бычьи бары были окрашены зеленым цветом, а медвежьи красным.

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   1


//--- plot ColorHistogram_2
#property indicator_label1  "ColorHistogram_2"
#property indicator_type1   DRAW_COLOR_HISTOGRAM2
#property indicator_color1  clrRed, clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3


double   Buffer_Bars1[];        //--- буферы значений
double   Buffer_Bars2[];        //--- буферы значений
double   Buffer_Colors[];       //--- буфер индексов цвета


int OnInit() {
   SetIndexBuffer(0, Buffer_Bars1,  INDICATOR_DATA);
   SetIndexBuffer(1, Buffer_Bars2,  INDICATOR_DATA);
   SetIndexBuffer(2, Buffer_Colors, INDICATOR_COLOR_INDEX);

   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
   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[]) {


   for(int i=0; i<rates_total; i++) {
      double Price_Open    = open[i];
      double Price_Close   = close[i];
      
      if(Price_Close >= Price_Open) {
                   FUNC_ChangeColors(clrGreen, 0);
      }
      else {
      if(Price_Close < Price_Open) {
                   FUNC_ChangeColors(clrRed, 1);
      }
      }

      Buffer_Bars1[i]      = high[i];
      Buffer_Bars2[i]      = low[i];
   } // for(int i=0; i<rates_total; i++) {

   return(rates_total);
} // int OnCalculate(const int rates_total,



void  FUNC_ChangeColors(color  Color_Bar, int Color_Index) {
      //--- установим цвет для каждого индекса как свойство PLOT_LINE_COLOR
      PlotIndexSetInteger(0,                    //  номер графического стиля
                          PLOT_LINE_COLOR,      //  идентификатор свойства
                          Color_Index,          //  индекс цвета, куда запишем цвет
                          Color_Bar);           //  новый цвет
} // void  FUNC_ChangeColors(color  &cols[], int plot_colors) {
 
grezky #:

Попытался упростить и изменить код по Вашему линку, но не получилось, рисует только одним цветом. 
Пожалуйста посмотрите как исправить чтобы бычьи бары были окрашены зеленым цветом, а медвежьи красным.

Читайте внимательней документацию. Там всё описано достаточно подробно и понятно.

Буфер цвета заполняется по условию… Откуда вы нашли такую идиотскую функцию? Там ведь вместо вызова этой функции достаточно написать 

Buffer_Colors = 0;
// или 
Buffer_Colors = 1;

Зачем вам дополнительные переменные 

      double Price_Open    = open[i];
      double Price_Close   = close[i];
 
Здравствуйте! Возник вопрос, а как лучше всего оптимизировать код для торговых утилит в виде советника? Создал утилиту, на обычных графиках работает шикарно, но стоит переключить символ на какой-то необычный, например DOGUSDT, как сразу же начинаются проблемы и сильное замедление работы утилита(Утилита представлена в виде торговой панели)
 
Alexey Viktorov #:

Зачем вам дополнительные переменные 

Просто скопировал готовую часть из похожего индикатора, так и остались.

Alexey Viktorov #:
Buffer_Colors = 0; // или Buffer_Colors = 1;

С этим теперь понятно, индикатор работает.

Попытался по аналогии добавить еще три буфера для тел свечей и colors, но МТ5 их не видит.
Что нужно исправить?

#property indicator_chart_window

#property indicator_buffers 6
#property indicator_plots   6 

#property indicator_label1  "ColorHistogram_1"
#property indicator_type1   DRAW_COLOR_HISTOGRAM2
#property indicator_color1  clrGreen, clrRed 
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3

#property indicator_label4  "ColorHistogram_2"
#property indicator_type4   DRAW_COLOR_HISTOGRAM2
#property indicator_color4  clrGreen, clrRed 
#property indicator_style4  STYLE_SOLID
#property indicator_width4  6

//--- Буферы для хранения значений и индексов цветов
double   Buffer_Wicks1[];
double   Buffer_Wicks2[];
double   Buffer_Colors3[];      // Индексы цветов для каждого бара

double   Buffer_Bodys4[];
double   Buffer_Bodys5[];
double   Buffer_Colors6[];      // Индексы цветов для каждого бара



int OnInit() {
   SetIndexBuffer(0, Buffer_Wicks1, INDICATOR_DATA);
   SetIndexBuffer(1, Buffer_Wicks2, INDICATOR_DATA);
   SetIndexBuffer(2, Buffer_Colors3, INDICATOR_COLOR_INDEX);

   SetIndexBuffer(3, Buffer_Bodys4, INDICATOR_DATA);
   SetIndexBuffer(4, Buffer_Bodys5, INDICATOR_DATA);
   SetIndexBuffer(5, Buffer_Colors6, INDICATOR_COLOR_INDEX);
   
   PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0);
   PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, 0);
   
   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[]) {

   for(int i=0; i<rates_total; i++) {
      if(close[i] >= open[i]) {
         Buffer_Colors3[i] = 0;
         Buffer_Colors6[i] = 0;
      } else {
         Buffer_Colors3[i] = 1;
         Buffer_Colors6[i] = 1;
      }
      
      Buffer_Wicks1[i] = high[i];
      Buffer_Wicks2[i] = low[i];
      Buffer_Bodys4[i] = open[i];
      Buffer_Bodys5[i] = close[i];
   } // for(int i=0; i<rates_total; i++) {
   
   return(rates_total);
}
 
grezky #:

Просто скопировал готовую часть из похожего индикатора, так и остались.

С этим теперь понятно, индикатор работает.

Попытался по аналогии добавить еще три буфера для тел свечей и colors, но МТ5 их не видит.
Что нужно исправить?

Внимательно читайте документацию!!! Кроме гистограмм есть построение свечи…………