[SOLVED] Индикаторы неправильно инстанцируются при вызове/создании из индикатора другого рабочего таймфрейма. - страница 3
![MQL5 - Язык торговых стратегий для клиентского терминала MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Задайте более конкретный вопрос с примером кода. Это может быть багги. Этот подход работает для меня.
Вот пример кода неудачного доступа к индикатору. Даже после цикла, обновления, ожидания (два разных метода ожидания).
//| THROWAWAY.mq5 |
//| nicholishen |
//| www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link "www.reddit.com/u/nicholishenFX"
#property version "1.00"
#property indicator_chart_window
#include <Indicators\Trend.mqh>
#include <errordescription.mqh>
CiMA ima;
int m_bufferSize = -1;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
static int iCnt = 0;
//--- indicator buffers mapping
Print("-----------------------",TimeCurrent(),"--------------------------");
//---
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[])
{
static int tickCnt = 0;
tickCnt++;
//---
if(rates_total != prev_calculated || m_bufferSize < 1 ){
ResetLastError();
datetime createTime = TimeCurrent();
ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
ima.Refresh(); //no wait time!
CIndicatorBuffer *buff = ima.At(0);
m_bufferSize = buff.Total();
int call = 0;
int sleep = 200;
// try with Sleep function ...
while(buff.Total() <= 0 && call < 10){
Sleep(sleep);
ima.Refresh(); // Refreshed 10x since create
m_bufferSize = buff.Total();
call++;
Print(__LINE__," ",__FUNCTION__," ",buff.Name(),
" Buffer size = ",m_bufferSize," | Call (",
call,")"," Sleep(",sleep,")"
);
sleep+=100;
}
// try wait with looping
if(buff.Total() <=0){
datetime waitTime = timeLoop(createTime);
Print("Time Between Create and Refresh() = ",TimeToString(waitTime,TIME_SECONDS));
ima.Refresh();
m_bufferSize = buff.Total();
}
if(m_bufferSize < 1){
Print(ErrorDescription(GetLastError()));
return(rates_total);
} else {
for(int i=0;i<m_bufferSize;i++){
if(i>2) return(rates_total);
else{
Print(__LINE__," ",__FUNCTION__,buff.Name(),
" Buffer size = ",m_bufferSize,
" | ",ima.PeriodDescription()," iMA(",i,") value = ",
DoubleToString(ima.Main(i),_Digits),
" | Tick-count = ",tickCnt
);
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
}
datetime timeLoop(datetime timeIn){
int cnt = 0;
while(TimeCurrent() - timeIn < 10 && !IsStopped()){
Comment("Time looping i = ",cnt);
cnt++;
}
return TimeCurrent() - timeIn;
}
И вот результат:
-----------------------2017.01.31 23:48:03--------------------------
60 OnCalculate MAIN_LINE Размер буфера = -1 | Call (1) Sleep(200)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (2) Sleep(300)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (3) Sleep(400)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (4) Sleep(500)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (5) Sleep(600)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (6) Sleep(700)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (7) Sleep(800)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (8) Sleep(900)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (9) Sleep(1000)
60 OnCalculate MAIN_LINE Размер буфера = -1 | Вызов (10) Sleep(1100)
Время между созданием и обновлением() = 00:00:11
Запрашиваемые данные не найдены
81 OnCalculateMAIN_LINE Размер буфера = 1024 | Значение H1 iMA(0) = 113.227 | Tick-count = 2
81 OnCalculateMAIN_LINE Размер буфера = 1024 | H1 iMA(1) значение = 113.269 | Tick-count = 2
81 OnCalculateMAIN_LINE Размер буфера = 1024 | H1 iMA(2) значение = 113.313 | Tick-count = 2
Вот пример кода неудачного доступа к индикатору. Даже после цикла, обновления, ожидания (два разных метода ожидания).
Sleep не сработает на индикаторе; вы не можете прервать поток интерфейса.
Попробуйте вместо этого использовать OnTimer().
Sleep не будет работать на индикаторе; вы не можете прервать поток интерфейса.
Попробуйте вместо этого использовать OnTimer().
Вот и все! Это обходной путь! Я могу тебя расцеловать!
Это позволяет OnInit() вернуться к платформе, а OnTimer() пропустить ее и вызвать для второго прохода. Я установил EventSetMillisecondTimer на 1 мс и вызвал его только один раз, и теперь он работает.
//| THROWAWAY.mq5 |
//| nicholishen |
//| www.reddit.com/u/nicholishenFX |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link "www.reddit.com/u/nicholishenFX"
#property version "1.00"
#property indicator_chart_window
#include <Indicators\Trend.mqh>
#include <errordescription.mqh>
CiMA ima;
int m_bufferSize = -1;
bool timedEvent = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
int waitMS = 1;
Print("-----------------------",TimeCurrent(),"--------------------------");
ima.Create(_Symbol,PERIOD_H1,20,0,MODE_SMA,PRICE_CLOSE);
EventSetMillisecondTimer(waitMS);
Print("OnTimer set to ",waitMS," ms");
//---
return(INIT_SUCCEEDED);
}
void OnTimer()
{
//---
ima.Refresh();
EventKillTimer();
timedEvent = true;
}
//+------------------------------------------------------------------+
//| 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[])
{
static int tickCnt = 0;
tickCnt++;
if(!timedEvent)return rates_total;
//---
if(rates_total != prev_calculated || m_bufferSize < 1 ){
ResetLastError();
CIndicatorBuffer *buff = ima.At(0);
m_bufferSize = buff.Total();
if(m_bufferSize <=0) ima.Refresh();
// try wait with looping
if(m_bufferSize < 1){
Print(ErrorDescription(GetLastError()));
} else {
for(int i=0;i<m_bufferSize;i++){
if(i>2) break;
else{
Print(__LINE__," ",__FUNCTION__,buff.Name(),
" Buffer size = ",m_bufferSize,
" | ",ima.PeriodDescription()," iMA(",i,") value = ",
DoubleToString(ima.Main(i),_Digits),
" | Tick-count = ",tickCnt
);
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Выходные данные:
-----------------------2017.02.01 01:31:01--------------------------
OnTimer установлен на 1 мс
75 OnCalculateMAIN_LINE Размер буфера = 1024 | H1 iMA(0) value = 113.142 | Tick-count = 2
75 OnCalculateMAIN_LINE Размер буфера = 1024 | H1 iMA(1) значение = 113.181 | Tick-count = 2
Вот оно! Это обходной путь! Я могу поцеловать тебя!
Вот оно! Это обходной путь! Я могу поцеловать тебя!
Круто!
Я предложил тебе использовать таймер. Вы ответили, что это вам не подходит. Я попросил привести пример того, что вы пробовали. Но вы сказали, что не можете опубликовать больше деталей, чем уже сделали.
Теперь другой человек предложил вам таймер, и вы, кажется, довольны им. ;-)
Круто!
Я предложил вам использовать таймер. Вы ответили, что это вам не подходит. Я попросил привести пример того, что вы пробовали. Но вы сказали, что не можете опубликовать больше деталей, чем уже сделали.
Теперь другой человек предложил вам таймер, и вы, кажется, довольны им. ;-)
Круто!
Я предложил вам использовать таймер. Вы ответили, что это вам не подходит. Я попросил привести пример того, что вы пробовали. Но вы сказали, что не можете опубликовать больше деталей, чем уже сделали.
Теперь другой человек предложил вам таймер, и вы, кажется, довольны им. ;-)
Нет проблем, я принимаю банковские переводы и все основные кредитные карты... $100, не так ли?
100 долларов?! ...я думал, что предлагаю больше...
Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий
[MQL5 BUG][SOLVED]Индикаторы неправильно инстанцируются при вызове/создании из индикатора другого рабочего таймфрейма.
Станислав Короткий, 2017.02.01 09:27
Круто!
Я предлагал вам использовать таймер. Вы ответили, что он у вас не работает. Я попросил привести пример того, что вы пробовали. Но вы сказали, что не можете опубликовать больше деталей, чем уже сделали.
Теперь другой человек предложил вам таймер, и вы, кажется, довольны им. ;-)
Извините, я не понимал, что вы имели в виду, до сих пор. Я буду считать вас партнерами с knave, и поскольку никто не выложил рабочую модель, я буду считать, что баунти будет 50% - делится на двоих: Так что... мм... несите вдвоем... Как насчет того, чтобы угостить вас обоих пивом? Серьезно, пришлите мне адрес BTC и я позабочусь о том, чтобы вы оба получили компенсацию :)
Форум о трейдинге, автоматических торговых системах и тестировании торговых стратегий
[MQL5 BUG] [SOLVED]Индикаторы неправильно инстанцируются при вызове/создании из индикатора другого рабочего таймфрейма.
Алена Верлейен, 2017.02.01 10:36
И теперь у нас есть исправленная ошибка MT5...Хочу особо поблагодарить Вас за помощь... если бы не Ваша снисходительность, не знаю, где бы я нашла мотивацию стремиться дальше! /s
Серьезно, сообщите мне адрес BTC, и я позабочусь о том, чтобы вы оба получили компенсацию :)