Используете ли вы CExpert при создании роботов? - страница 25

 
George Merts:
Что-то я не совсем понял, как это поможет не тянуть через весь код переданные ссылки на массивы ?


Домустим, мы можем вызывать эту функцию самостоятельно - значит, на входе этой функции мы должны поставить проверку, кто ее вызвал. То ли терминал, то ли мы сами. Если терминал - мы получаем ссылки на массивы, и ??? Их же надо как-то сохранить ! А вызов этой функции самим экспертом - в чем смысл-то ?

Не понял вопроса совсем.
 
fxsaber:

Работает всегда!

У меня не работало (не всегда) и это было проблемой. Вызов OnCalculate в OnTimer на выходных с ChartRedraw не всегда обновлял данные индикатора
 
fxsaber:
Не понял вопроса совсем.
Мне указатель или ссылки на массивы нужны для того, чтобы не надо было копировать данные, переданные терминалом в OnCalculate(). Я не совсем понял, как мы этого избегаем, если можем вызывать OnCalculate() самостоятельно (очевидно, из самой OnCalculate()) ?
 
Попробовал.  Помогает ChartRedraw(). Работает стабильно. 
 
George Merts:
Мне указатель или ссылки на массивы нужны для того, чтобы не надо было копировать данные, переданные терминалом в OnCalculate(). Я не совсем понял, как мы этого избегаем, если можем вызывать OnCalculate() самостоятельно (очевидно, из самой OnCalculate()) ?
Не для этого. Искал способ как заставить индикатор мгновенно реагировать на самодельный GUI.
 
George Merts:
Мне указатель или ссылки на массивы нужны для того, чтобы не надо было копировать данные, переданные терминалом в OnCalculate(). Я не совсем понял, как мы этого избегаем, если можем вызывать OnCalculate() самостоятельно (очевидно, из самой OnCalculate()) ?

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Используете ли вы CExpert при создании роботов?

fxsaber, 2016.10.03 14:39

Тут "сэкономить" получилось бы, если бы были указатели на глобальном уровне - зло, ИМХО.

Еще один вариант "экономии" разработчики не стали делать по понятным причинам.

struct TIMESERIES_UNIT
{
  const datetime time,     // Time 
  const double open,       // Open 
  const double high,       // High 
  const double low,        // Low 
  const double close,      // Close 
  const long tick_volume,  // Tick Volume 
  const long volume,       // Real Volume 
  const int spread         // Spread 
};

int OnCalculate (const int rates_total,      // размер входных таймсерий 
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const TIMESERIES_UNIT &TimeSeries[] );
Рабочий вариант "экономить"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

#define TIMESERIES_IN     time, open, high, low, close, tick_volume, volume, spread
#define TIMESERIES_DEFINE 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[]

void Func1( TIMESERIES_DEFINE, double d )
{
  Print(time[0]);
}

void Func2( int i, TIMESERIES_DEFINE )
{
  Func1(TIMESERIES_IN, 1.0);
}

int OnCalculate ( const int rates_total, const int prev_calculated, TIMESERIES_DEFINE )
{
  Func2(0, TIMESERIES_IN);

  return(rates_total);
}

 
Комбинатор:
У меня не работало (не всегда) и это было проблемой. Вызов OnCalculate в OnTimer на выходных с ChartRedraw не всегда обновлял данные индикатора

Все ситуации, конечно, не проверял. Вызов OnCalculate в OnTimer - это то же самое, что вызов любой другой функции. Т.е. это фактически изменение индикаторных буферов по событию Timer. Если ChartRedraw в этой ситуации не помогает - Сервисдеск.

В индикаторах буферы могут (допускается архитектурно) быть изменены в любой On-функции по соответствующему событию. 

 

Вот такой вот код попробовал (индикатор):

//+------------------------------------------------------------------+
//|                                                           11.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot Label1
#property indicator_label1  "Label1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- indicator buffers
double         Label1Buffer[];
int rt=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
  
  EventSetTimer(1);
   
//--- indicator buffers mapping
   SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
   
//---
   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[])
  {
//---
   rt=rates_total;
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---

      if(Label1Buffer[0]!=130.32){
         for(int i=0;i<rt;i++){
            Label1Buffer[i]=130.32;
         }
      }
      else{
         for(int i=0;i<rt;i++){
            Label1Buffer[i]=130.42;
         }      
      }
      
      ChartRedraw();
  }

Работает четко даже с отключенным интернетом. Запускать на GBPJPY H1, или заменить числа 130.32 и 130.42

 
fxsaber: Рабочий вариант "экономить"

А... Ну тут вы "тянете" все ссылки через все функции, просто через дефайн заменяете длинный список - одним идентификатором.

А вот представьте, что у вас класс, который работает с таймсериями, производя ряд каких-то вычислений, с глубиной стека в 10 вызовов. При этом непосредственно обращение к значениям - требуется только на самой "глубине".

Лично я в этом случае "наверху" инициализирую этот объект указателем на таймсерии, запоминаю его внутри класса, и потом, при вызове вычислений - происходит последовательный вызов всех функций "вглубь", и в самой "глубокой" функции - запрашиваются данные по сохраненным указателям.

А сейчас - приходится вот так, через все 10 функций "тянуть за собой" ссылки на таймсерии. Да, в вашем случае - с помощью одного дефайна, но когда он совершенно не нужен на всех 9 уровнях - это начинает раздражать.

А самое неприятное получается, когда используется класс-потомок другого класса, который и знать не знает про таймсерии на всех 10 уровнях, просто на самом "глубоком" он обращается к данным с помощью вирутальных функций. То есть, мы взяли этот самый класс-обработчик данных, перегрузили в нем функцию получения значений... а вот передать в нее значения - никак не можем, поскольку класс-обработчик на всех 9 уровнях - не нуждается в данных, и, соответственно, никаких указателей не запоминает.

Получается - надо писать свой класс, который будет тянуть эти ненужные данные через все 9 уровней. Что совсем неприемлемо. Пока что приходится при вызове OnCalculate() копировать данные в массивы, и работать с указателями на них. Что, на мой взгляд, это не есть хорошо. Здесь явно нужны указатели или ссылки на переданные данные. 

 
George Merts:

Подробно расписали - понял! Да, в таких ситуациях MQL5 кричит, что далек от гибкости.

Проблема, как мне видится, не только в отсутствии указателей на таймсерии в OnCalculate, а в отсутствии указателей на массивы любой природы. 

Причина обращения: