Всем привет!
Наткнулся на вот такое - внутренняя ошибка, код 4024 в MQL4.
Задача: при инициализации советника на ведущей паре открыть график дочерней пары
Код:
input string Shablon="Green"; // Шаблон графика
long PairID=-1;
int OnInit()
{
int err;
....
string SlavePair=ChartSymbol(PairID);
Print("В окне ",PairID," открыта пара '",SlavePair+"'");
if (SlavePair != Pair)
{
Print("Нет нужной пары в окне ",PairID, " Открываем новое.");
ResetLastError();
PairID=ChartOpen(Pair,PERIOD_M5);
if ((err=GetLastError())>0) Print("Проблема с открытием окна пары "+Pair+" код ",err);
else
{
Print("Новое окно ",PairID, " Грузим шаблон...");
ResetLastError();
if (ChartApplyTemplate(PairID,Shablon)) Print("Шаблон загружен");
else Print("Проблема загрузки шаблона, код ", GetLastError());
}
}
return(INIT_SUCCEEDED);
}
В результате исполнения в журнале:
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: initialized
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: Проблема с открытием окна пары USDCHF код 4024
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: Нет нужной пары в окне -1 Открываем новое.
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: В окне -1 открыта пара ''
При этом окно с USDCHF открывается. Где у меня косяк в коде, уже с ног сбился?
А зачем такая проверка ошибки? Не лучше-ли проверить что вернула функция ChartOpen()?
Я этим путем ходил. ChartOpen() возвращает значение 0, т.е. не открылось дочернее окно с USDCHF. Но потом чекунд через 15-25 оно появляется. Во какие дела!?
Что не так в коде? Как нужно понимать код ошибки 4024? И как это лечится?
Я этим путем ходил. ChartOpen() возвращает значение 0, т.е. не открылось дочернее окно с USDCHF. Но потом чекунд через 15-25 оно появляется. Во какие дела!?
Что не так в коде? Как нужно понимать код ошибки 4024? И как это лечится?
Ну попробуй перед созданием графика проверить SymbolSelect() и/или после создания Sleep() поставь.
Это предложение имеет второстепенный смысл к той проблеме что я задал.
Повторю еще раз: что такое "внутренняя ошибка" 4024, что является причиной ее возникновения?
Ещё раз вернусь к теме.
К сожалению, таинственная ошибка 4024 возникает при попытке советника открыть новое окно с парой, отличной от той, на которую он брошен, достаточно часто. Никаких сведений в Справке о том, вследствие чего эта ошибка возникает, в чём её суть и как предотвращать её появление, разрабы привести не соизволили. Поэтому пришлось действовать методом наблюдений, проб и ошибок. Если очень коротко, то при возникновении этой ошибки новое окно всегда открывается, но после существенной задержки и, самое главное, оно получает два ID, один - явный, "странный" ID, который не является увеличенным на единицу числом предыдущего графика (на котором висит советник, открывший новое окно), а представляет собой число из совершенно "другой оперы". Другой ID - теневой, "нормальный". При этом явный "странный" ID на самом деле указывает на главное, первое, вызвавшее окно, и, если к этому ID применить функцию ChartClose(), то закрыто будет именно оно, а новое окно так и останется одиноко "висеть" в терминале. Ну, или, как вариант, при подаче команды на открытие нового окна зачем-то создаётся что-то типа указателя на главное окно, и функция ChartNext() в примере ниже возвращает именно его. Но это не более чем моя догадка, в документации, как я уже сказал, об этом ни слова.
В итоге функция открытия советником окна с другой парой приобрела нижеследующий вид:
void RefreshCharts(string Pair,ushort Period_)//подкачка котировок: Pair - пара, Period_ - ТФ графика { const ulong i = ChartFirst(); //"засекаем" ID главного графика Print("ID главного графика - ",i); long j = ChartOpen(Pair,Period_); //даём команду на открытие графика другой пары while (j == 0 || j == -1) //обрабатываем проблемы при открытии { //единственная ошибка, которая возникала у меня здесь за всё время наблюдений - только 4024 if (j == 0) Print("Ошибка открытия графика ",Pair," ",_LastError,", ожидание открытия..."); else Print("График в процессе открытия..."); Sleep(1000); j = ChartNext(i); //когда новое окно, наконец, откроется, берём его ID "обходным" путём. Это будет "странный" ID, который будет } //выдан в журнал в следующей строке Print("ID графика ",Pair," - ",j); long T; while ((!SeriesInfoInteger(Pair,PERIOD_H1,SERIES_LASTBAR_DATE,T) && _Print("Загрузка данных по " + Pair + ", ошибка " + string(_LastError))) || datetime(T) < Time[0]) //проверяем актуальность котировок по открывшейся паре, если надо, подкачиваем новые { RefreshRates(); Sleep(1000); ChartRedraw(j); //принудительно обновляем открывшийся график Print("Данные по графику с ID ",j," обновлены"); } Sleep(1000); //теперь, после обновления данных, нам надо закрыть второй график. И вот тут обнаруживается очень неприятная Print("Закрываем график с ID ",ChartSymbol(j) == Pair ? j : i + 1); //вещь: если просто попытаться закрыть его функцией ChartClose(j), то... будет закрыт ChartClose(ChartSymbol(j) == Pair ? j : i + 1); //главный график вместе с советником! Со всеми вытекающими. И привет. Несмотря на то, } //что аргумент функции ChartClose() - j, а не константа i, в которой хранится ID главного графика! Вот что хотите, то и думайте. Привет Метаквотсам и их //неубиваемым "внутренним ошибкам". Мне пришлось несколько раз пройти через это печальное обстоятельство, хорошо, что хоть на демо-счёте. Поэтому напрямую //мы закрываем новое окно, если оно было открыто без ошибок, и его пара совпадает с заданной при вызове функции. Если же j указывает на главное окно (его //пара не совпадает с обновлённой), то ID закрываемого окна указываем как увеличенный на единицу ID окна главного, хотя, грубо говоря, мы это значение //как бы "взяли с потолка". Ну а что делать, если иначе не получается? Можно, конечно, плюнуть, не пытаться закрыть новое окно автоматом и закрыть его //позже вручную, но это значит сдаться. А сдаваться без крайней необходимости не следует. //+------------------------------------------------------------------+ bool _Print(string Text)//отображение сработавшей ветки длинного условия { Print(Text); return(true); }
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Всем привет!
Наткнулся на вот такое - внутренняя ошибка, код 4024 в MQL4.
Задача: при инициализации советника на ведущей паре открыть график дочерней пары
Код:
input string Shablon="Green"; // Шаблон графика
long PairID=-1;
int OnInit()
{
int err;
....
string SlavePair=ChartSymbol(PairID);
Print("В окне ",PairID," открыта пара '",SlavePair+"'");
if (SlavePair != Pair)
{
Print("Нет нужной пары в окне ",PairID, " Открываем новое.");
ResetLastError();
PairID=ChartOpen(Pair,PERIOD_M5);
if ((err=GetLastError())>0) Print("Проблема с открытием окна пары "+Pair+" код ",err);
else
{
Print("Новое окно ",PairID, " Грузим шаблон...");
ResetLastError();
if (ChartApplyTemplate(PairID,Shablon)) Print("Шаблон загружен");
else Print("Проблема загрузки шаблона, код ", GetLastError());
}
}
return(INIT_SUCCEEDED);
}
В результате исполнения в журнале:
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: initialized
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: Проблема с открытием окна пары USDCHF код 4024
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: Нет нужной пары в окне -1 Открываем новое.
2017.02.16 10:15:51.886 eurusd-usdchf EURUSD,M5: В окне -1 открыта пара ''
При этом окно с USDCHF открывается. Где у меня косяк в коде, уже с ног сбился?