Ошибки, баги, вопросы - страница 3663

 

в чем разница у этих функций?

не могу понять для чего первая понадобилась

SeriesInfoInteger(strSymbolName,etTimeframe,SERIES_BARS_COUNT,lResult)

int  Bars( 
   string           symbol_name,     // имя символа 
   ENUM_TIMEFRAMES  timeframe        // периоду 
   );

на достаточность баров обычно Bars 

если нужно проверить расчет другого индикатора(хендла), то 

int  BarsCalculated(
   int       indicator_handle,     // handle индикатора
   );



Примечание

Функция полезна в тех случаях, когда необходимо получить данные индикатора сразу после его создания (получения хэндла индикатора).

пробелы не убираются
 
Sergey Gridnev #:
В mt5, если мне не изменяет память, так было всегда.
А смысл инициализации - подготовить буферы и, возможно, значения каких-либо переменных.

Вот-вот, и для подготовки, скажем, мне нужны дополнительные буфферы, и если число баров недостаточно - то смысла отображать вобще нет. Я запрашиваю в инициализации бары, а мне выдаётся, что их нет... Соответственно, и инициализироваться нечем. 

Пока обошёл эту проблему, инициализируясь на первом пришедшем тике. Но, по-моему, это неправильно, тем более, что в МТ4 - было всё в порядке в этом плане, в функции Init() все данные подготовлены. 

 
lynxntech #:
если нужно проверить расчет другого индикатора(хендла), то 

А если нужны бары по другому символу? 

Лично я устаревшей Bars() без параметров вобще не пользуюсь, поскольку непонятно внутри кода, к каким барам она относится. 

Ну а с помощью функции SeriesInfoInteger() можно из одного места получить и другие данные.  Как мне кажется, эта функция более разумна внутри класов, поставляющих данные, используя функции доступа к таймсериям. 

 
Georgiy Merts #:

А если нужны бары по другому символу? 

Лично я устаревшей Bars() без параметров вобще не пользуюсь, поскольку непонятно внутри кода, к каким барам она относится. 

Ну а с помощью функции SeriesInfoInteger() можно из одного места получить и другие данные.  Как мне кажется, эта функция более разумна внутри класов, поставляющих данные, используя функции доступа к таймсериям. 

у Bars и есть выбор символа и TF

в штатных индикаторах всегда в OnCalculated идет проверка, только вместо Bars, rates_total

 if(rates_total<3)
      return(0);
Bars(_Symbol,_Period); 
 
Georgiy Merts #:

Вот-вот, и для подготовки, скажем, мне нужны дополнительные буфферы, и если число баров недостаточно - то смысла отображать вобще нет. Я запрашиваю в инициализации бары, а мне выдаётся, что их нет... Соответственно, и инициализироваться нечем. 

Пока обошёл эту проблему, инициализируясь на первом пришедшем тике. Но, по-моему, это неправильно, тем более, что в МТ4 - было всё в порядке в этом плане, в функции Init() все данные подготовлены. 

Если это работает, значит это правильно. Было бы не правильно, оно бы не работало. Логично?

Вот взял первый попавшийся индикатор, перенёс OnInit()  в OnCalculate().

Работает. Значит всё норм)))

#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3
//--- plot ATR
#property indicator_label1  "ATR"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDarkViolet
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot MAOnATR
#property indicator_label2  "MAOnATR"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGold
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot MAOnATR2
#property indicator_label3  "MAOnATR2"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

#include <MovingAverages.mqh>
//--- input parameters
input int                  Inp_ATR_ma_period             = 21;             // ATR: averaging period
input int                  Inp_MA_ma_period              = 55;             // MA1: averaging period
input ENUM_MA_METHOD       Inp_MA_ma_method              = MODE_SMMA;      // MA1: smoothing type
input int                  Inp_MA_ma_period2             = 14;             // MA2: averaging period
input ENUM_MA_METHOD       Inp_MA_ma_method2             = MODE_SMA;       // MA2: smoothing type
//--- indicator buffers
double ATRBuffer[];
double MAOnATRBuffer[];
double MAOnATRBuffer2[], Buffer1[];
int handle_iATR = 0;                         // variable for storing the handle of the iATR indicator
bool start = true;
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
  {
   if(start)
     {
      SetIndexBuffer(0, ATRBuffer, INDICATOR_DATA);
      SetIndexBuffer(1, MAOnATRBuffer, INDICATOR_DATA);
      SetIndexBuffer(2, MAOnATRBuffer2, INDICATOR_DATA);

      PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
      PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
      PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
      IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
      PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, Inp_ATR_ma_period);

      string short_name = StringFormat("MAOnATR(%d; %d; %d)", Inp_ATR_ma_period, Inp_MA_ma_period, Inp_MA_ma_period2);
      IndicatorSetString(INDICATOR_SHORTNAME, short_name);

      handle_iATR = iATR(_Symbol, PERIOD_CURRENT, Inp_ATR_ma_period);
      if(handle_iATR == INVALID_HANDLE)
        {
         Print(StringFormat("Failed to create handle of the iATR indicator for the symbol %s/%s, error code %d",
                            Symbol(), EnumToString(Period()), GetLastError()));
         return(INIT_FAILED);
        }
      start = false;
     }
     
   int to_copy, bar = 1;
   if(prev_calculated > rates_total || prev_calculated <= 0)
     {
      ArrayInitialize(ATRBuffer, 0);
      ArrayInitialize(MAOnATRBuffer, 0);
      ArrayInitialize(MAOnATRBuffer2, 0);
      to_copy = rates_total;
     }
   else
      to_copy = rates_total - prev_calculated + 1;

   if(BarsCalculated(handle_iATR) < rates_total)
      return(0);

   if(CopyBuffer(handle_iATR, 0, 0, to_copy, ATRBuffer) < 0)
     {
      Print(StringFormat("Failed to copy, error code %d", GetLastError()));
      return(0);
     }

   IsMaCalc(Inp_MA_ma_method, rates_total, prev_calculated, Inp_ATR_ma_period - 1,  Inp_MA_ma_period, ATRBuffer, MAOnATRBuffer);
   IsMaCalc(Inp_MA_ma_method2, rates_total, prev_calculated, Inp_ATR_ma_period - 1,  Inp_MA_ma_period2, ATRBuffer, MAOnATRBuffer2);

   return(rates_total);
  }
//+------------------------------------------------------------------+
void IsMaCalc(const int ma_method, const int rates_total, const int prev_calculated, const int begin, const int period, const double& price[], double& buffer[])
  {
   switch(ma_method)
     {
      case  MODE_EMA :
         ExponentialMAOnBuffer(rates_total, prev_calculated, begin, period, price, buffer);
         break;
      case MODE_SMMA :
         SmoothedMAOnBuffer(rates_total, prev_calculated, begin, period, price, buffer);
         break;
      case MODE_LWMA :
         LinearWeightedMAOnBuffer(rates_total, prev_calculated, begin, period, price, buffer);
         break;
      default :
         SimpleMAOnBuffer(rates_total, prev_calculated, begin, period, price, buffer);
     }
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(handle_iATR != INVALID_HANDLE)
      IndicatorRelease(handle_iATR);
  }
//+------------------------------------------------------------------+
 

вырезка из DeepSeek

// Способ 1 - простой
int bars1 = Bars(_Symbol, _Period);

// Способ 2 - через SeriesInfoInteger (эквивалент)
long bars2;
if(SeriesInfoInteger(_Symbol, _Period, SERIES_BARS_COUNT, bars2))
{
    // bars2 будет содержать то же значение, что и bars1
}
Вывод: Для обычных задач используйте Bars(_Symbol, _Period) - это более современный и удобный способ. SeriesInfoInteger() оставьте для специфических случаев.

это должно быть в OnCalculated

Bars можно на rates_total для текущего символа и тф заменить

 
Aleksandr Slavskii #:

Если это работает, значит это правильно. Было бы не правильно, оно бы не работало. Логично?

НЕТ.

Когда заложен нос - люди дышат ртом, и это у них вполне себе получается. Однако, рот человека, всё-таки, не предназначен для дыхания, и дышать им в обычных условиях неправильно. 

Также и тут - начальные проверки и инициализация должны проводиться в Init(). Если при этом таймсерии могут быть недоступны - это должно быть, как минимум, чётко указанно в описании события Init для индикаторов. В справке ничего этого нет сказано. В описании порядка доступа к таймсериям - указано, что бары могут быть несформированы, и для этого надо использовать скрипт с функцией Sleep(), которая не должна вызываться в индикаторах. 

Наконец важно и то, что если индикатор запускается на графике - то всё проходит нормально, и количество баров благополучно выдаётся в функции Init(). Если же терминал перезапущен - то в функции Init() количество баров нулевое. На мой взгляд, тут надо либо привести к общему поведению, когда в функции Init() таймсерии доступны (или недоступны), ну, либо, хотя бы указать в справке - что поведение не определено, и запрашивать число баров в этой функции нельзя. 

Вывод: Для обычных задач используйте Bars(_Symbol, _Period) - это более современный и удобный способ. SeriesInfoInteger() оставьте для специфических случаев.

DeepSeek, конечно, авторитет... Особенно, учитывая, что функция Bars() появилась РАНЬШЕ, чем функция SeriesInfoInteger() (если не ошибаюсь, ещё в МТ3).

lynxntech #:
у Bars и есть выбор символа и TF

Ну, так я ведь и сказал - "без параметров". 

В обычных случаях разницы нет, однако, когда надо в одном месте получать разные данные, и в том числе количество баров - предпочтительнее SeriesInfoInteger(), а не отдельные функции, среди которых будет и Bars()

 
Georgiy Merts #:

НЕТ.

Когда заложен нос - люди дышат ртом, и это у них вполне себе получается. Однако, рот человека, всё-таки, не предназначен для дыхания, и дышать им в обычных условиях неправильно. 

Также и тут - начальные проверки и инициализация должны проводиться в Init(). Если при этом таймсерии могут быть недоступны - это должно быть, как минимум, чётко указанно в описании события Init для индикаторов. В справке ничего этого нет сказано. В описании порядка доступа к таймсериям - указано, что бары могут быть несформированы, и для этого надо использовать скрипт с функцией Sleep(), которая не должна вызываться в индикаторах. 

Наконец важно и то, что если индикатор запускается на графике - то всё проходит нормально, и количество баров благополучно выдаётся в функции Init(). Если же терминал перезапущен - то в функции Init() количество баров нулевое. На мой взгляд, тут надо либо привести к общему поведению, когда в функции Init() таймсерии доступны (или недоступны), ну, либо, хотя бы указать в справке - что поведение не определено, и запрашивать число баров в этой функции нельзя. 

DeepSeek, конечно, авторитет... Особенно, учитывая, что функция Bars() появилась РАНЬШЕ, чем функция SeriesInfoInteger() (если не ошибаюсь, ещё в МТ3).

Ну, так я ведь и сказал - "без параметров". 

В обычных случаях разницы нет, однако, когда надо в одном месте получать разные данные, и в том числе количество баров - предпочтительнее SeriesInfoInteger(), а не отдельные функции, среди которых будет и Bars()

Тоже было. Хотел получить данные баров в онинит) и значения индикаторов на них. В общем пришел к тому, что они и не с первого раза получаются. Пришлось сделать цикл, пока не получены данные. Только так получилось.) и это в онкалкулейт)
 
Georgiy Merts #:

НЕТ.

Ну, собственно, я не спорю. Я просто привёл пример, что ехать можно и без шашечек.

Поведение терминала при старте действительно похоже на баг.

Баги сказано писать сюда.

Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 - Версия MetaTrader 5 расширила поддержку библиотеки линейной алгебры OpenBLAS.
Новая версия платформы MetaTrader 5 build 5200: расширение OpenBLAS и усиление контроля в MQL5 - Версия MetaTrader 5 расширила поддержку библиотеки линейной алгебры OpenBLAS.
  • 2025.07.31
  • www.mql5.com
SylvesterEquationTriangular решает уравнение Сильвестра для вещественных квазитреугольных или комплексных треугольных матриц верхнетреугольные. SylvesterEquationTriangularBlocked решает уравнение Сильвестра для вещественных квазитреугольных или комплексных треугольных матриц верхнетреугольные матрицы
 
Описание возвращаемого значения противоречит примеру: