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

 
Vitaly Muzichenko:

Вроде так в циклах, и можно обойтись без функции

 

Спасибо.

Однако убрал функцию - тормоза остались.... проклятье.

 
Aleksey Vyazmikin:

 

Спасибо.

Однако убрал функцию - тормоза остались.... проклятье.

Я как-то начал переписывать программу с 4=>5, потом в 4-ке заменил все конструкции типа Low[1], Time[0] и прочие на современные, то есть на CopyLowCopyTime, программа даже в 4-ке стала работать быстрее. Сейчас не применяю старые конструкции, а только новые. Таким образом код легко переносим на 5-ю платформу, нужно только сменить торговые функции

 
Vitaly Muzichenko:

Я как-то начал переписывать программу с 4=>5, потом в 4-ке заменил все конструкции типа Low[1], Time[0] и прочие на современные, то есть на CopyLowCopyTime, программа даже в 4-ке стала работать быстрее. Сейчас не применяю старые конструкции, а только новые. Таким образом код легко переносим на 5-ю платформу, нужно только сменить торговые функции

 

Заполнение массива при каждом чихе разве не потребляет ресурсы?

Может, есть смысл копировать информацию в массив при открытии бара и потом уже походу кода оттуда брать её? Торгую по открытию бара.


 
Aleksey Vyazmikin:

Заполнение массива при каждом чихе разве не потребляет ресурсы?

Может, есть смысл копировать информацию в массив при открытии бара и потом уже походу кода оттуда брать её? Торгую по открытию бара.

Массив можно заполнять на новом баре, так меньше уйдёт ресурсов. Если работа например с iLow[1] в нескольких местах, то желательно её один раз занести в переменную, и читать уже переменную, а не массив.

Предположим так

// Инициализация TIME[0] TIME[1]
  ArraySetAsSeries(TM,true);
  if(CopyTime(dSymbol,Period(),0,2,TM)<0) return;
  TIME_0=TM[0];
  TIME_1=TM[1];
Далее работаем с переменной TIME_0 и TIME_1, а не TM[0] и TM[1]
 
Vitaly Muzichenko:

Массив можно заполнять на новом баре, так меньше уйдёт ресурсов. Если работа например с iLow[1] в нескольких местах, то желательно её один раз занести в переменную, и читать уже переменную, а не массив.

Предположим так

 И всё ж таки , MT4 на порядок быстрей получается - я разочарован.

 

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

Ошибки, баги, вопросы

Aleksey Vyazmikin, 2017.07.21 15:07

 

Зачем Вы фантазируете? Я понял Вашу идею, и подтвердил, что она рабочая, и даст эффект, если запрос будет происходить один раз и если известно, сколько понадобиться баров для работы советника.

Или Вы как то по другому предлагали использовать структуру? Тогда прошу пояснить, а не обижаться!


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

Что касается количества для копирования, так это совсем другой вопрос. Может надо сначала посчитать на каком баре есть нужное значение индикатора, а потом только его и копировать??? Если я правильно помню было сказано о неизвестном количестве для копирования. О каких фантазиях речь?

Да и на крайний случай можно копировать по, скажем, 10 баров и среди них искать, если не нашёл копируем ещё 10. Копирование затратная операция, дешевле перебрать массив.

В общем вариантов масса. Всё это невозможно написать в документацию, да и это уже не документация будет. Этому учат на уроках программирования. Но, к сожалению, не все преподаватели это умеют и не все ученики хотят это понять на уроках. А самое, самое начало закладывается на уроках арифметики во 2-5 классах когда учитель требует подробного объяснения к задаче. Но тут те-же проблемы.

 
Alexey Viktorov:

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

Что касается количества для копирования, так это совсем другой вопрос. Может надо сначала посчитать на каком баре есть нужное значение индикатора, а потом только его и копировать??? Если я правильно помню было сказано о неизвестном количестве для копирования. О каких фантазиях речь?

Да и на крайний случай можно копировать по, скажем, 10 баров и среди них искать, если не нашёл копируем ещё 10. Копирование затратная операция, дешевле перебрать массив.

В общем вариантов масса. Всё это невозможно написать в документацию, да и это уже не документация будет. Этому учат на уроках программирования. Но, к сожалению, не все преподаватели это умеют и не все ученики хотят это понять на уроках. А самое, самое начало закладывается на уроках арифметики во 2-5 классах когда учитель требует подробного объяснения к задаче. Но тут те-же проблемы.

 

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

Я прекрасно понимаю Вашу концепцию, и это было заложено в ответе Вам.

Однако, не совсем понял, как Вы предлагаете работать с неизвестным объемом данных - можете привести пример в виде кода?


 

Прошу помощи в аудите и оптимизации индикатора по этой ссылки https://www.mql5.com/ru/code/16805 - беда в том, что индикатор начинает сильно тормозить при появлении большого числа баров - проявляется при тестировании.

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

Donchian Channel MTF
Donchian Channel MTF
  • голосов: 13
  • 2016.12.13
  • Mladen Rakic
  • www.mql5.com
Мультитаймфреймовая версия канала Дончиана.
 
Aleksey Vyazmikin:

 

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

Я прекрасно понимаю Вашу концепцию, и это было заложено в ответе Вам.

Однако, не совсем понял, как Вы предлагаете работать с неизвестным объемом данных - можете привести пример в виде кода?


Ответ был дан до того как...

Alexey Viktorov:

Да и на крайний случай можно копировать по, скажем, 10 баров и среди них искать, если не нашёл копируем ещё 10. Копирование затратная операция, дешевле перебрать массив.

Но лучше не от-фонаря количество, а примерно максимальное чтобы постараться обойтись одним копированием.

Пример кода я писать не буду. Нормальному программисту нужна только подсказка. Вот примерный алгоритм:

  1. Определяем примерное количество баров на расстоянии которых происходит пересечение канала. Пусть будет 15.
  2. Копируем оба буфера индикатора.
  3. Копируем значения баров используя CopyRates()
  4. В цикле начинаем сравнивать значение верхней границы канала и high баров одновременно со сравниванием low баров с нижней границей канала. В случае нахождения одного из пересечений индекс бара запоминаем в переменной и продолжаем искать второе пересечение. Выходим из цикла тогда, когда обе переменные индексов баров пересечения имеют значения.

Таким образом за одно копирование и один цикл можно при необходимости найти два пересечения. Даже нет необходимости в ArraySetAsSeries() поскольку при нахождении пересечения можно и, на мой взгляд, лучше запоминать не номер бара, а его время. Хотя зная время бара нет никакого труда определить его номер.

Внимание вопрос: Что будет быстрей работать, цикл с копированием буфера индикатора по 1 значению и копирование high бара по 1 и сравнивание этих значений, или одноразовое копирование определённого количества и сравнивание значений двух массивов между собой?

 

Вот только вчера написал:

Задача:

на каждом тике получить "InpCountCopy" элементов open, high, low, close и time.

Реализация:

  1. цикл от "0" до "InpCountCopy-1" - в цикле получаем за один раз один open, high, low, close и time.
  2. за один раз получаем в структуру MqlRates "InpCountCopy" элементов и затем уже цикл по структуре.

Возможности:

можно выбирать как проверять: в OnTick или в OnTimer (1 секунда).

//+------------------------------------------------------------------+
//|                                      Copy OHLC vc Copy Rates.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.001"
//--- input parameter
input int InpCountCopy=1000;
input bool OnTickOnTimer=false; // OnTickOnTimer: false -> OnTick, true -> OnTimer 1 second
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(OnTickOnTimer)
      EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(!OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Main function                                                    |
//+------------------------------------------------------------------+
void Testing()
  {
//--- for once one element
   ulong start=GetMicrosecondCount();
   for(int i=0;i<InpCountCopy;i++) // in one operation we get one element.
     {
      double open=iOpen(i);
      double high=iHigh(i);
      double low=iLow(i);
      double close=iClose(i);
      datetime time=iTime(i);
     }
   ulong end=GetMicrosecondCount()-start;
   string text=(OnTickOnTimer)?"OnTimer":"OnTick";
   text=text+"\n"+"OHLC: "+IntegerToString(end);

//--- for one operation we get "InpCountCopy" elements.
   start=GetMicrosecondCount();
   MqlRates Rates[];
   if(!iRates(Rates,0,InpCountCopy))
      return;
   for(int i=0;i<InpCountCopy;i++)
     {
      double open=Rates[i].open;
      double high=Rates[i].high;
      double low=Rates[i].low;
      double close=Rates[i].close;
      datetime time=Rates[i].time;
     }
   end=GetMicrosecondCount()-start;
   text=text+"\n"+"Rates: "+IntegerToString(end);

   Comment(text);
  }
//+------------------------------------------------------------------+ 
//| Get Open for specified bar index                                 | 
//+------------------------------------------------------------------+ 
double iOpen(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Open[1];
   double open=0;
   int copied=CopyOpen(symbol,timeframe,index,1,Open);
   if(copied==1)
      open=Open[0];
   return(open);
  }
//+------------------------------------------------------------------+ 
//| Get the High for specified bar index                             | 
//+------------------------------------------------------------------+ 
double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double High[1];
   double high=0;
   int copied=CopyHigh(symbol,timeframe,index,1,High);
   if(copied==1)
      high=High[0];
   return(high);
  }
//+------------------------------------------------------------------+ 
//| Get Low for specified bar index                                  | 
//+------------------------------------------------------------------+ 
double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Low[1];
   double low=0;
   int copied=CopyLow(symbol,timeframe,index,1,Low);
   if(copied==1)
      low=Low[0];
   return(low);
  }
//+------------------------------------------------------------------+ 
//| Get Close for specified bar index                                | 
//+------------------------------------------------------------------+ 
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Close[1];
   double close=0;
   int copied=CopyClose(symbol,timeframe,index,1,Close);
   if(copied==1)
      close=Close[0];
   return(close);
  }
//+------------------------------------------------------------------+ 
//| Get Time for specified bar index                                 | 
//+------------------------------------------------------------------+ 
datetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   datetime Time[1];
   datetime time=0;
   int copied=CopyTime(symbol,timeframe,index,1,Time);
   if(copied==1)
      time=Time[0];
   return(time);
  }
//+------------------------------------------------------------------+ 
//| Get Rates for specified bar index                                | 
//+------------------------------------------------------------------+ 
bool iRates(MqlRates  &Rates[],const int index,int count,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   int copied=CopyRates(symbol,timeframe,index,count,Rates);
   if(copied!=count)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+


Файлы:
Причина обращения: