Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 1362

 
А отдельно 2 файла в Маркете не разместить. Такова политика.
 
Aleksei Stepanenko #:

Вот индикатор:

Вот эксперт:

Вот всё в одном файле:

Четвёрка правда, но в пятёрке также.

У вас скомпилирован только файл Эксперта.

Попробуйте, хотя-бы простым графическим объектом наполнить индикатор, чтобы он вызывался Экспертом. Затем после компиляции, переименуйте или удалите Res_Ind.ex4, как бы отправили на Маркет только файл Эксперта. Клиент получит неработающую программу.

 
Aleksei Stepanenko #:
А отдельно 2 файла в Маркете не разместить. Такова политика.
О чем и речь...
 
Dmitriy VC #:

У вас скомпилирован только файл Эксперта.

Попробуйте, хотя-бы простым графическим объектом наполнить индикатор, чтобы он вызывался Экспертом. Затем после компиляции, переименуйте или удалите Res_Ind.ex4, как бы отправили на Маркет только файл Эксперта. Клиент получит неработающую программу.

Да нельзя-же быть таким упёртым… Сказано, что индикатор подключенный ресурсом включается в исполняемый файл советника, значит так и есть.

А вот тот факт, что ваш индикатор рисует графические объекты, а советник должен их читать, это большая проблема. Графические объекты доступны только при тестировании с визуализацией, а автовалидатор тестирует без оного, соответственно свойств объектов не видит…

 
Alexey Viktorov #:

Сказано, что индикатор подключенный ресурсом включается в исполняемый файл советника, значит так и есть.

Индикатор в отдельном окне

//+------------------------------------------------------------------+
//|                                                          win.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {

   IndicatorSetString(INDICATOR_SHORTNAME,"win");

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Компилируем Индикатор -->  win.ex5.

Эксперт с этим Индикатором в ресурсе

//+------------------------------------------------------------------+
//|                                                          exp.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#resource "\\Indicators\\win.ex5"
char      number    = -1;
int       handle    = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

   if(number<0)
     {
      handle=iCustom(_Symbol,_Period,"win.ex5");
      number=char(ChartGetInteger(0,CHART_WINDOWS_TOTAL));

      if(handle!=INVALID_HANDLE)
        {
         ChartIndicatorAdd(0,number,handle);
        }
     }

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(reason==REASON_REMOVE)
     {
      ChartIndicatorDelete(0,int(ChartWindowFind(0,"win")),"win");
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+

Компилируем Эксперта -->  exp.ex5.

Запускаем Эксперта, на графике есть окно индикатора.

Публикуем в Маркете один файл эксперта exp.ex5 (фактически удаляем файл индикатора win.ex5)

Запускаем Эксперта, на графике нет окна индикатора.

Восстанавливаем удаленный файл win.ex5.

Запускаем Эксперта, на графике есть окно индикатора.


Вывод: код Индикатора не включается в код Эксперта. Для нормальной работы Эксперта с ресурсным Индикатором необходим исполняемый файл Индикатора указанного в ресурсе.


Повторю свой вопрос:

как опубликовать в Маркете, когда имеется Эксперт с кастомным Индикатором, библиотекой, т.е. для нормальной работы Эксперта нужно больше чем один файл?

Файлы:
win.mq5  2 kb
exp.mq5  4 kb
 
Dmitriy VC #:

Индикатор в отдельном окне

Компилируем Индикатор -->  win.ex5.

Эксперт с этим Индикатором в ресурсе

Компилируем Эксперта -->  exp.ex5.

Запускаем Эксперта, на графике есть окно индикатора.

Публикуем в Маркете один файл эксперта exp.ex5 (фактически удаляем файл индикатора win.ex5)

Запускаем Эксперта, на графике нет окна индикатора.

Восстанавливаем удаленный файл win.ex5.

Запускаем Эксперта, на графике есть окно индикатора.


Вывод: код Индикатора не включается в код Эксперта. Для нормальной работы Эксперта с ресурсным Индикатором необходим исполняемый файл Индикатора указанного в ресурсе.


Повторю свой вопрос:

как опубликовать в Маркете, когда имеется Эксперт с кастомным Индикатором, библиотекой, т.е. для нормальной работы Эксперта нужно больше чем один файл?

Сколько раз вам дали ссылку на документацию? Почитать мама не разрешает?

      handle=iCustom(_Symbol,_Period,"win.ex5"); // Это делается не так!!!!

Прочтите наконец-то…

 
Alexey Viktorov #:

Сколько раз вам дали ссылку на документацию? Почитать мама не разрешает?

Прочтите наконец-то…

Алексей, благодарю за прямое указание ошибки.

Читал документацию но было "не по глазам".

Перед всеми извиняюсь - ступил.

Теперь разобрался.

 

Подскажите пожалуйста.

Добавил в класс расчет количества баров(:RatesTotal(void)), не могу разобраться как уложить правильно в структуру. Получилось что то вроде этого. Подскажите пожалуйста как сделать покрасивче.

#include <Arrays\ArrayObj.mqh>
/********************************************************************\
|   Класс Новый бар                                                  |
\********************************************************************/
class CNewBar : public CObject
  {
private:
   string            m_symbol;
   ENUM_TIMEFRAMES   m_timeframe;
   datetime          m_time;
   long              m_rt;
   datetime          Time(void);  
   long              RatesTotal(void);   
   string            Symbol(void)         { return this.m_symbol;    }
public:
   ENUM_TIMEFRAMES   Timeframe(void)      { return this.m_timeframe; }
   datetime          GetTime(void)        { return this.m_time;      } //  Возвращает время последнего обращения
   long              GetRatesTotal(void)     { return this.m_rt; }
   bool              IsNewBar(void);                                   //  Основная функция класса
                     CNewBar(const string symbol,const ENUM_TIMEFRAMES timeframe);
                    ~CNewBar(void) {;}
  };
//+------------------------------------------------------------------+
//|    Конструктор                                                   |
//+------------------------------------------------------------------+
CNewBar::CNewBar(const string symbol,const ENUM_TIMEFRAMES timeframe) : m_time(0)
  {
   this.m_symbol = symbol;
   this.m_timeframe = (timeframe == PERIOD_CURRENT ? Period() : timeframe);
  }

//+------------------------------------------------------------------+
//|  Возвращает количество баров в истории                           |
//+------------------------------------------------------------------+
long CNewBar::RatesTotal(void)
  {
//---- получим количество баров
  long rt=SeriesInfoInteger(this.m_symbol, this.m_timeframe,SERIES_BARS_COUNT);
//---- Проверка количества
   if(rt<1)
      Print("Error "+__FUNCTION__+" Не определенно кол-во баров ",this.m_symbol," ",this.m_timeframe);
//----
   return(rt);
  };
//+------------------------------------------------------------------+
//| CNewBar IsNewBar Основная функция класса                         |
//+------------------------------------------------------------------+
bool CNewBar::IsNewBar(void)
  {
   m_rt=this.RatesTotal();
   datetime tm=this.Time();
   if(tm==0 || m_rt<1)
      return false;
   if(tm!=this.m_time)
     {
      this.m_time = tm;
      return true;
     }
   return false;
  }
 
Dmitriy VC #:

Теперь разобрался.

Не ступил, а не знал. Вообще без проблем :)

 

Сможете подсказать , как организовать аналог расчета prev_calculated, что то не соображу ни как.


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CNewBar::PrevCalculated(void)
  {
   int pc=this.m_rt
   return(pc)
  }
//+------------------------------------------------------------------+
//| CNewBar IsNewBar Основная функция класса                         |
//+------------------------------------------------------------------+
bool CNewBar::IsNewBar(void)
  {
   datetime tm=this.Time();

   if(tm==0 || m_rt<1)
      return false;
   if(tm!=this.m_time)
     {
      //--- определяем время
      this.m_time = tm;
      //--- определяем кол-во
      this.m_rt=this.RatesTotal();
      return true;
     }
   return false;
  }
Причина обращения: