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

 
Так в принципе и было, ошибка наверно была в том что у меня хэндл индикатора создается в функии OnTick и сразу же на этом же тике копируются данные. Ночью до меня дошло, сейчас попробую перенести хэндлы в функцию OnInit.
Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
sss20192:
Так в принципе и было, ошибка наверно была в том что у меня хэндл индикатора создается в функии OnTick и сразу же на этом же тике копируются данные. Ночью до меня дошло, сейчас попробую перенести хэндлы в функцию OnInit.

Не помогло. Вот такой сейчас код


#property version   "1.00"

input int                  InpFastEMA=12;                // Fast EMA period
input int                  InpSlowEMA=26;                // Slow EMA period
input int                  InpSignalMA=9;                // Signal MA period
input ENUM_APPLIED_PRICE   InpAppliedPrice=PRICE_CLOSE;  // Applied price
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int Handle1, Handle2, Handle3;
double MacdArray[];

int OnInit()
  {
//---
  Handle1 = iMACD(_Symbol, PERIOD_M5, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle2 = iMACD(_Symbol, PERIOD_M15, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle3 = iMACD(_Symbol, PERIOD_H1, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
        CopyBuffer(Handle1, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle2, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle3, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
  }
//+------------------------------------------------------------------+

 В журнале выводит такие сообщения

2013.04.13 15:21:31 2010.01.04 00:00:01   6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01   6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01   6.187448020344988e-005 0

И так всегда. Ошибки вроде при копировании нет. 

 
sss20192: Не помогло. Вот такой сейчас код

Но у Вас пока что нет ни проверки на успешность создания хендлов, ни проверки на успешность расчёта индикаторов и проверки копирования. Сама по себе идея перенести инициализацию хендлов в OnInit() - правильная.

Вы ещё вот что сделайте: строчку  Print(MacdArray[0]); поставьте в самом начале тела OnTick() - дабы посмотреть, какое мусорное значение содержится в массиве перед началом копирования буферов.

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

 
Yedelkin:
Но у Вас пока что нет ни проверки на успешность создания хендлов, ни проверки на успешность расчёта индикаторов и проверки копирования. Сама по себе идея перенести инициализацию хендлов в OnInit() - правильная.
Но только в первый раз. Если же в любом другом месте программы выяснится, что какой-нибудь хэндл невалиден, то нужно его попробовать получить снова. Поэтому нельзя сказать, что вынос кода для получения хэндлов в OnInit() решит вопрос полностью и правилен на все 100.  ))
 
Делал проверку на то сколько данных скопировалось функцией CopyBuffer, всегда пишет 1. И ошибки никакой нет, а данные все равно не верные. 
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
Доступ к таймсериям и индикаторам / CopyBuffer - Документация по MQL5
 

tol64

Yedelkin: Сама по себе идея перенести инициализацию хендлов в OnInit() - правильная.

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

Вы хотите сказать, что сама по себе идея перенести инициализацию хендлов в OnInit() из OnTick() - неправильная?
 
sss20192:
Делал проверку на то сколько данных скопировалось функцией CopyBuffer, всегда пишет 1. И ошибки никакой нет, а данные все равно не верные. 

У меня такой результат этого кода в тестере:

 

//---

Единственное, что сделал перед тестом, так просто преобразовал значения индикатора перед выводом в журнал:

Print(DoubleToString(MacdArray[0],Digits())," ",GetLastError());
 
Yedelkin:
Вы хотите сказать, что сама по себе идея перенести инициализацию хендлов в OnInit() из OnTick() - неправильная?
Если только в OnInit() и больше нигде, то да - неправильная. В первый раз пробуем получить хэндл в OnInit(). Далее, перед каждой попыткой получить данные индикатора проверяем, валиден ли хэндл. Если он валиден, то получаем данные, если нет, то пробуем получить хэндл снова.
 
tol64:

У меня такой результат этого кода в тестере:

 

//---

Единственное, что сделал перед тестом, так просто преобразовал значения индикатора перед выводом в журнал:

Ухтыж гениально! Спасибо большое! Третий день проблему решаю)
 
tol64:
Yedelkin: Вы хотите сказать, что сама по себе идея перенести инициализацию хендлов в OnInit() из OnTick() - неправильная?
Если только в OnInit() и больше нигде, то да - неправильная. В первый раз пробуем получить хэндл в OnInit(). Далее, перед каждой попыткой получить данные индикатора проверяем, валиден ли хэндл. Если он валиден, то получаем данные, если нет, то пробуем получить хэндл снова.

 А без "если"? И применительно к данной конкретной ситуации? У человека хэндл индикатора создавался в функции OnTick на каждом тике и сразу же на этом же тике копировались данные. Т.е. без проверки на валидность-невалидность каждый раз заново запрашивался хендл одного и того же индикатора. На этом фоне Вы будете продолжать утверждать, что сама по себе идея перенести инициализацию хендлов в OnInit() из OnTick() - неправильная?

ПС. Судя по всему,  человеку Вы помогли, так что вопрос можно считать исчерпанным.

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