//Version June 21, 2009 Final //+X================================================================X+ //| JLiteSeries().mqh | //| JMA code: Copyright © 1998, Jurik Research | //| http://www.jurikres.com | //| JLiteSeries() MQL4: Copyright © 2006, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+X================================================================X+ /* +------------------------------------- <<< Функция JLiteSeries() >>> -----------------------------------------------+ +-----------------------------------------+ <<< Назначение >>> +----------------------------------------------------+ Функция JLiteSeries() предназначена для использования алгоритма JLite при написании любых индикаторов теханализа и экспертов, для замены расчёта классического усреднения на этот алгоритм. Функция не работает, если параметр nJLite.limit принимает значение, равное нулю! Все индикаторы, сделанные мною для JLiteSeries(), выполнены с учётом этого ограничения. Файл следует положить в папку MetaTrader\experts\include\ Алгоритм функции JLiteSeries() - это полный аналог алгоритма JJMASeries, у которого отсутствует адаптивный код. Поэтому иногда эта функция даёт результаты, слегка запаздывающие по сравнению с JLiteSeries(), но зато затраты компьютерных ресурсов на JLiteSeries() в шесть раз ниже, чем на JJMASeries(). Функцию JLiteSeries() удобно применять для индикаторов с большой глубиной сглаживания типа полос Боллинджера или каналов. В одном индикаторе нельзя одновременно применять JJMASeries и JLiteSeries()!!! Для замены в индикаторе функции JJMASeries на JLiteSeries() достаточно в тексте индикатора заменить строку #include на строку #include . Следует учесть, что если nJLite.bar больше, чем nJLite.MaxBar, то функция JLiteSeries() возвращает значение равное нулю! на этом баре! И, следовательно, такое значение не может присутствовать в знаменателе какой-либо дроби в расчёте индикатора! Эта версия функции JLiteSeries(Exp) поддерживает экспертов при её использовании в пользовательских индикаторах, к которым обращается эксперт. Эта версия функции JLiteSeries() поддерживает экспертов при её использовании в коде индикатора, который полностью помещён в код эксперта с сохранением всех операторов цикла! При написании индикаторов и экспертов с использованием функции JLiteSeries(),не рекомендуется переменным давать имена начинающиеся с nJLite.... или dJLite... Функция JLiteSeries() может быть использована во внутреннем коде других пользовательских функций, но при этом следует учитывать тот факт, что в каждом обращении к такой пользовательской функции у каждого обращения к JLiteSeries() должен быть свой уникальный номер (nJLite.number). +-------------------------------------+ <<< Входные параметры >>> +-------------------------------------------------+ nJLite.number - порядковый номер обращения к функции JLiteSeries. (0, 1, 2, 3 и.т.д....) nJLite.dinJ - параметр, позволяющий изменять параметры nJLite.Length и nJLite.Phase на каждом баре. 0 - запрет изменения параметров, любое другое значение - разрешение. nJLite.MaxBar - Максимальное значение, которое может принимать номер рассчитываемого бара (nJLite.bar). Обычно равно Bars-1-period; Где "period" - это количество баров, на которых исходная величина dJLite.series не рассчитывается; nJLite.limit - Количество ещё не подсчитанных баров плюс один или номер последнего непосчитанного бара. Должно быть обязательно равно Bars-IndicatorCounted()-1; nJLite.Length - глубина сглаживания nJLite.Phase - параметр, изменяющийся в пределах -100 ... +100, влияет на качество переходного процесса; dJLite.series - Входной параметр, по которому производится расчёт функции JLiteSeries(); nJLite.bar - номер рассчитываемого бара, параметр должен изменяться оператором цикла от максимального значения к нулевому. Причём его максимальное значение всегда должно равняться значению параметра nJLite.limit!!! +------------------------------------+ <<< Выходные параметры >>> +-------------------------------------------------+ JJMASeries() - значение функции dJLite.JLite(). При значениях nJLite.bar больше чем nJLite.MaxBar-30 функция JJMASeries() всегда возвращает ноль!!! nJLite.reset - параметр, возвращающий по ссылке значение, отличенное от 0 , если произошла ошибка в расчёте функции, 0, если расчёт прошёл нормально. Этот параметр может быть только переменной, но не значением!!! +-----------------------------------+ <<< Инициализация функции >>> +-----------------------------------------------+ Перед обращениями к функции JLiteSeries() , когда количество уже подсчитанных баров равно 0, (а ещё лучше это сделать в блоке инициализации пользовательского индикатора или эксперта), следует изменить до требуемого размер внутренних буферных переменных функции, для этого необходимо обратиться к функции JLiteSeries() через вспомогательную функцию JJMASeriesResize со следующими параметрами: JJMASeriesResize(MaxJLite.number+1); необходимо сделать параметр nJLite.number(MaxJLite.number) равным количеству обращений к функции JLiteSeries, то есть на единицу больше, чем максимальный nJLite.number. +--------------------------------------+ <<< Индикация ошибок >>> +-------------------------------------------------+ При отладке индикаторов и экспертов их коды могут содержать ошибки, для выяснения причин которых следует смотреть лог файл. Все ошибки функция JLiteSeries() пишет в лог файл в папке \MetaTrader\EXPERTS\LOGS\. Если, перед обращением к функции JLiteSeries() в коде, который предшествовал функции, возникла MQL4 ошибка, то функция запишет в лог файл код ошибки и содержание ошибки. Если при выполнении функции JLiteSeries() в алгоритме JLiteSeries() произошла MQL4 ошибка, то функция также запишет в лог файл код ошибки и содержание ошибки. При неправильном задании номера обращения к функции JLiteSeries() nJLite.number или неверном определении размера буферных переменных nJLiteResize.Size в лог файл будет записаны сообщения о неверном определении этих параметров. Также в лог файл пишется информация при неправильном определении параметра nJLite.limit. Если при выполнении функции инициализации init() произошёл сбой при изменении размеров буферных переменных функции JLiteSeries(), то функция JLiteSeriesResize() запишет в лог файл информацию о неудачном изменении размеров буферных переменных. Если при обращении к функции JLiteSeries() через внешний оператор цикла была нарушена правильная последовательность изменения параметра nJLite.bar, то в логфайл будет записана и эта информация. Следует учесть, что некоторые ошибки программного кода будут порождать дальнейшие ошибки в его исполнении и поэтому, если функция JLiteSeries() пишет в лог файл сразу несколько ошибок, то устранять их следует в порядке времени возникновения. В правильно написанном индикаторе функция JLiteSeries() может делать записи в лог файл только при нарушениях работы операционной системы. Исключение составляет запись изменения размеров буферных переменных при перезагрузке индикатора или эксперта, которая происходит при каждом вызове функции init(). +---------------------------------+ <<< Пример обращения к функции >>> +--------------------------------------------+ //----+ определение функций JLiteSeries() #include //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- определение стиля исполнения графика SetIndexStyle (0,DRAW_LINE); //---- 1 индикаторный буфер использован для счёта SetIndexBuffer(0,Ind_Buffer); //----+ Изменение размеров буферных переменных функции JLiteSeries, nJLite.number=1(Одно обращение к функции JLiteSeries) if (JJMASeriesResize(1)==0)return(-1); return(0); } //+------------------------------------------------------------------+ //| Custom indicator function | //+------------------------------------------------------------------+ int start() { //----+ Введение целых переменных и получение уже подсчитанных баров int reset,bar,MaxBar,limit,counted_bars=IndicatorCounted(); //---- проверка на возможные ошибки if (counted_bars<0)return(-1); //---- последний посчитанный бар должен быть пересчитан //(без этого пересчёта функция JLiteSeries() свой расчёт производить не будет!!!) if (counted_bars>0) counted_bars--; //---- определение номера самого старого бара, //начиная с которого будет произедён пересчёт новых баров int limit=Bars-counted_bars-1; MaxBar=Bars-1; //----+ for(bar=limit;bar>=0;bar--) ( double Series=Close[bar]; //----+ Обращение к функции JLiteSeries() за // номером 0 для расчёта буфера Ind_Buffer[] //параметры nJLite.Phase и nJLite.Length не меняются на каждом баре (nJLite.din=0) double Resalt=JJMASeries(0,0,MaxBar,limit,Phase,Length,Series,bar,reset); if (reset!=0)return(-1); Ind_Buffer[bar]=Resalt; } return(0); } //----+ */ //+X================================================================X+ //| JLiteSeries() function | //+X================================================================X+ //----+ Объявление переменных double dJLite.Kg[1], dJLite.Pf[1], dJLite.f30; double dJLite.fA8m[1], dJLite.fC0[1], dJLite.fC0m[1]; double dJLite.fC8m[1],dJLite.JLite[1], dJLite.JLitem[1]; double dJLite.fB0, dJLite.fD0, dJLite.fA8[1], dJLite.fC8[1]; double dJLite.fB0dJLite.f20, dJLite.f20, JLite.f30, dJLite.f40; //---- int nJLite.Tnew, nJLite.Told, nJLite.size, nJLite.n; int nJLite.TIME[1], nJLite.Resize, nJLite.Error; //----+ <<< Объявление функции JLiteSeries() >>> double JJMASeries (int nJLite.number, int nJLite.din, int nJLite.MaxBar, int nJLite.limit, int nJLite.Phase, int nJLite.Length, double dJLite.series, int nJLite.bar, int& nJLite.reset) //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ { //----+ nJLite.n = nJLite.number; nJLite.reset = 1; //----+ <<< Проверки на ошибки >>> +----------------------------------------+ if (nJLite.bar == nJLite.limit) { //----+ проверка на инициализацию функции JLiteSeries() if (nJLite.Resize < 1) { Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Не было сделано изменение размеров буферных ", "переменных функцией JLiteSeriesResize()")); if (nJLite.Resize == 0) Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Следует дописать обращение к функции ", "JLiteSeriesResize() в блок инициализации")); return(0.0); } //----+ проверка на ошибку в исполнении программного //кода, предшествовавшего функции JJLiteSeries() nJLite.Error = GetLastError(); if (nJLite.Error > 4000) { Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". В коде, предшествующем обращению к функции", " JLiteSeries() number = ", nJLite.n, " ошибка!!!")); Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". ", JLite_ErrDescr(nJLite.Error))); } //----+ проверка на ошибку в задании переменных // nJLite.number и nT3Resize.Number if (ArraySize(dJLite.fC8) < nJLite.n) { Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Ошибка!!! Неправильно задано значение ", "переменной nJLite.number функции JLiteSeries()")); Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Или неправильно задано значение переменной", " nJLiteResize.Size функции JLiteSeriesResize()")); return(0.0); } } //----+ проверка на ошибку в последовательности // изменения переменной nJLite.bar if (nJLite.limit >= nJLite.MaxBar) if (nJLite.bar == 0) if (nJLite.MaxBar > 30) if (nJLite.TIME[nJLite.n] == 0) { Print(StringConcatenate("JLiteSeries number =", nJLite.n, ". Ошибка!!! Нарушена правильная последовательность", " изменения параметра nJLite.bar внешним оператором цикла!!!")); Print(StringConcatenate("Пересчёт баров следует производить", " слева направо, а не наоборот!!!")); } //----+ +----------------------------------------------------------------+ if (nJLite.bar > nJLite.MaxBar) { nJLite.reset = 0; return(0.0); } //----+ Расчёт коэффициентов if (nJLite.bar == nJLite.MaxBar || nJLite.din != 0) { double dJLite.Dr; if (nJLite.Length < 1.0000000002) dJLite.Dr = 0.0000000001; else dJLite.Dr = (nJLite.Length - 1.0) / 2.0; //---- dJLite.Kg[nJLite.n] = 0.9 * dJLite.Dr/(dJLite.Dr + 2.0); //---- if (nJLite.Phase >= -100 && nJLite.Phase <= 100) dJLite.Pf[nJLite.n] = nJLite.Phase / 100.0 + 1.5; //---- if (nJLite.Phase > 100) dJLite.Pf[nJLite.n] = 2.5; //---- if (nJLite.Phase < -100) dJLite.Pf[nJLite.n] = 0.5; //----+ } //----+ <<< Восстановление значений переменных >>> if (nJLite.bar == nJLite.limit && nJLite.limit < nJLite.MaxBar) { //----+ nJLite.Tnew = Time[nJLite.limit+1]; nJLite.Told = nJLite.TIME[nJLite.n]; //---- if (nJLite.Tnew == nJLite.Told) { dJLite.fC0[nJLite.n] = dJLite.fC0m[nJLite.n]; dJLite.fC8 [nJLite.n] = dJLite.fC8m [nJLite.n]; dJLite.fA8[nJLite.n] = dJLite.fA8m[nJLite.n]; dJLite.JLite[nJLite.n] = dJLite.JLitem[nJLite.n]; } //---- проверка на ошибки if (nJLite.Tnew != nJLite.TIME[nJLite.n]) { nJLite.reset = -1; //---- индикация ошибки в расчёте входного параметра nJLite.limit функции JLiteSeries() if (nJLite.Tnew > nJLite.TIME[nJLite.n]) { Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Ошибка!!! Параметр nJLite.limit функции JLiteSeries() меньше, чем необходимо")); } else { int nJLite.LimitERROR = nJLite.limit + 1 - iBarShift(NULL, 0, nJLite.TIME[nJLite.n], TRUE); Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". Ошибка!!! Параметр nJLite.limit функции JLiteSeries() больше, чем необходимо на ", nJLite.LimitERROR)); } //---- Возврат через nJLite.reset= -1; ошибки в расчёте функции JLiteSeries return(0); } } //----+ <<< Сохранение значений переменных >>> if (nJLite.bar == 1 && nJLite.limit != 1) { dJLite.fC0m[nJLite.n] = dJLite.fC0[nJLite.n]; dJLite.fC8m [nJLite.n] = dJLite.fC8 [nJLite.n]; dJLite.fA8m[nJLite.n] = dJLite.fA8[nJLite.n]; dJLite.JLitem[nJLite.n] = dJLite.JLite[nJLite.n]; nJLite.TIME[nJLite.n] = Time[2]; } dJLite.f30 = MathPow(dJLite.Kg[nJLite.n], 1); dJLite.fC0[nJLite.n] = (1.0 - dJLite.f30) * dJLite.series + dJLite.f30 * dJLite.fC0[nJLite.n]; dJLite.fC8[nJLite.n] = (dJLite.series - dJLite.fC0[nJLite.n]) * (1.0 - dJLite.Kg[nJLite.n]) + dJLite.Kg[nJLite.n] * dJLite.fC8[nJLite.n]; dJLite.fD0 = dJLite.Pf[nJLite.n] * dJLite.fC8[nJLite.n] + dJLite.fC0[nJLite.n]; dJLite.f20 = dJLite.f30 *(-2.0); dJLite.f40 = dJLite.f30 * dJLite.f30; dJLite.fB0 = dJLite.f20 + dJLite.f40 + 1.0; dJLite.fA8[nJLite.n] =(dJLite.fD0 - dJLite.JLite[nJLite.n]) * dJLite.fB0 + dJLite.f40 * dJLite.fA8[nJLite.n]; dJLite.JLite[nJLite.n] = dJLite.JLite[nJLite.n] + dJLite.fA8[nJLite.n]; //----+ nJLite.Error = GetLastError(); //----+ проверка на ошибку в исполнении программного кода функции JLiteSeries() if (nJLite.Error > 1) { Print(StringConcatenate("JLiteSeries number = ", nJLite.n, ". При исполнении функции JLiteSeries() произошла ошибка!!!")); Print(StringConcatenate ("JLiteSeries number = ", nJLite.n, ". ", JLite_ErrDescr(nJLite.Error))); } nJLite.reset = 0; if (nJLite.bar >= nJLite.MaxBar - 30) return(0.0); //----+ Завершение вычислений функции JLiteSeries() return(dJLite.JLite[nJLite.n]); } //+X================================================================X+ //| JLiteSeriesResize() function | //+X================================================================X+ // JLiteSeriesResize - Это дополнительная функция для изменения | // размеров и инициализации буферных переменных функции JLiteSeries1.| // Пример обращения: JLiteSeriesResize(5); где 5 - это количество | // обращений к JLiteSeries1() в тексте индикатора. Это обращение к | // функции JLiteSeriesResize следует поместить в блок инициализации | // пользовательского индикатора или эксперта | //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ int JJMASeriesResize(int nJLiteResize.Size) { //----+ if (nJLiteResize.Size < 1) { Print(StringConcatenate("JJMASeriesResize: Ошибка!!! ", "Параметр nJLiteResize.Size не может быть меньше единицы!!!")); nJLite.Resize = -1; return(0); } int nJLiteResize.reset, nJLiteResize.cycle; //---- while(nJLiteResize.cycle == 0) { //----+ <<< изменение размеров буферных переменных >>> +-------------------------------+ if (ArrayResize(dJLite.Kg, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.Pf, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fA8, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fC0, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fC8, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.JLite, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fA8m, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fC0m, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.fC8m, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(dJLite.JLitem, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} if (ArrayResize(nJLite.TIME, nJLiteResize.Size) == 0){nJLiteResize.reset = -1; break;} //+------------------------------------------------------------------------------------+ nJLiteResize.cycle = 1; } //---- if (nJLiteResize.reset == -1) { Print(StringConcatenate("JLiteSeriesResize: Ошибка!!! Не удалось изменить", " размеры буферных переменных функции JLiteSeries().")); int nJLiteResize.Error = GetLastError(); if (nJLiteResize.Error > 4000)Print(StringConcatenate("JJMASeriesResize(): ", JLite_ErrDescr(nJLiteResize.Error))); nJLite.Resize = -2; return(0); } else { Print(StringConcatenate("JLiteSeriesResize: JLiteSeries() size = ",nJLiteResize.Size)); nJLite.Resize = nJLiteResize.Size; return(nJLiteResize.Size); } //----+ } //+X================================================================X+ //| JJMASeriesAlert() function | //+X================================================================X+ /* | JJMASeriesAlert - Это дополнительная функция для индикации | ошибки в задании внешних переменных nJLite. Length и nJLite.Phase | функции JJMASeries(). | ----------------------- входные параметры ------------------------| Number | ExternVar - значение внешней переменной для параметра nJLite.Length | name - имя внешней переменной для параметра nJLite.Phase, если | Number = 0 или nJLite.Phase, если Number = 1. | -------------------------- Пример использования ------------------| int init() | //---- | Здесь какая-то инициализация переменных и буферов | | //---- установка алертов на | //недопустимые значения внешних переменных | JJMASeriesAlert(0, "Length1", Length1); | JJMASeriesAlert(0, "Length2", Length2); | JJMASeriesAlert(1, "Phase1", Phase1); | JJMASeriesAlert(1, "Phase2", Phase2); | //---- завершение инициализации | return(0); | } | //+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+ */ void JJMASeriesAlert(int Number, string name, int ExternVar) { //----+ //---- установка алертов на недопустимые значения входных параметров if (Number == 0) if (ExternVar < 1) Print(StringConcatenate( "Параметр ", name, " должен быть не менее 1", " Вы ввели недопустимое ", ExternVar, " будет использовано 1")); if (Number == 1) { if (ExternVar < -100 || ExternVar > 100) Print(StringConcatenate( "Параметр ", name, " должен быть от -100 до +100", " Вы ввели недопустимое ", ExternVar, " будет использовано -100")); } if (Number != 0) if (Number != 1) Print(StringConcatenate( "Параметр Number может принимать только значения 0 и 1", " Вы ввели недопустимое ", Number, "!!!")); //----+ } // перевод сделан Николаем Косициным 01.12.2006 //+X================================================================X+ //| JLite_ErrDescr_RUS(MQL4).mqh | //| Copyright © 2004, MetaQuotes Software Corp. | //| http://www.metaquotes.net/ | //+X================================================================X+ string JLite_ErrDescr(int error_code) { string error_string; //---- switch(error_code) { //---- MQL4 ошибки case 4000: error_string = StringConcatenate("Код ошибки = ",error_code,". нет ошибки"); break; case 4001: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильный указатель функции"); break; case 4002: error_string = StringConcatenate("Код ошибки = ",error_code,". индекс массива не соответствует его размеру"); break; case 4003: error_string = StringConcatenate("Код ошибки = ",error_code,". Нет памяти для стека функций"); break; case 4004: error_string = StringConcatenate("Код ошибки = ",error_code,". Переполнение стека после рекурсивного вызова"); break; case 4005: error_string = StringConcatenate("Код ошибки = ",error_code,". На стеке нет памяти для передачи параметров"); break; case 4006: error_string = StringConcatenate("Код ошибки = ",error_code,". Нет памяти для строкового параметра"); break; case 4007: error_string = StringConcatenate("Код ошибки = ",error_code,". Нет памяти для временной строки"); break; case 4008: error_string = StringConcatenate("Код ошибки = ",error_code,". Неинициализированная строка"); break; case 4009: error_string = StringConcatenate("Код ошибки = ",error_code,". Неинициализированная строка в массиве"); break; case 4010: error_string = StringConcatenate("Код ошибки = ",error_code,". Нет памяти для строкового массива"); break; case 4011: error_string = StringConcatenate("Код ошибки = ",error_code,". Слишком длинная строка"); break; case 4012: error_string = StringConcatenate("Код ошибки = ",error_code,". Остаток от деления на ноль"); break; case 4013: error_string = StringConcatenate("Код ошибки = ",error_code,". Деление на ноль"); break; case 4014: error_string = StringConcatenate("Код ошибки = ",error_code,". Неизвестная команда"); break; case 4015: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильный переход (never generated error)"); break; case 4016: error_string = StringConcatenate("Код ошибки = ",error_code,". Неинициализированный массив"); break; case 4017: error_string = StringConcatenate("Код ошибки = ",error_code,". Вызовы DLL не разрешены"); break; case 4018: error_string = StringConcatenate("Код ошибки = ",error_code,". Невозможно загрузить библиотеку"); break; case 4019: error_string = StringConcatenate("Код ошибки = ",error_code,". Невозможно вызвать функцию"); break; case 4020: error_string = StringConcatenate("Код ошибки = ",error_code,". Вызовы внешних библиотечных функций не разрешены"); break; case 4021: error_string = StringConcatenate("Код ошибки = ",error_code,". Недостаточно памяти для строки, возвращаемой из функции"); break; case 4022: error_string = StringConcatenate("Код ошибки = ",error_code,". Система занята (never generated error)"); break; case 4050: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильное количество параметров функции"); break; case 4051: error_string = StringConcatenate("Код ошибки = ",error_code,". Недопустимое значение параметра функции"); break; case 4052: error_string = StringConcatenate("Код ошибки = ",error_code,". Внутренняя ошибка строковой функции"); break; case 4053: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка массива"); break; case 4054: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильное использование массива-таймсерии"); break; case 4055: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка пользовательского индикатора"); break; case 4056: error_string = StringConcatenate("Код ошибки = ",error_code,". Массивы несовместимы"); break; case 4057: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка обработки глобальныех переменных"); break; case 4058: error_string = StringConcatenate("Код ошибки = ",error_code,". Глобальная переменная не обнаружена"); break; case 4059: error_string = StringConcatenate("Код ошибки = ",error_code,". Функция не разрешена в тестовом режиме"); break; case 4060: error_string = StringConcatenate("Код ошибки = ",error_code,". Функция не подтверждена"); break; case 4061: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка отправки почты"); break; case 4062: error_string = StringConcatenate("Код ошибки = ",error_code,". Ожидается параметр типа string"); break; case 4063: error_string = StringConcatenate("Код ошибки = ",error_code,". Ожидается параметр типа integer"); break; case 4064: error_string = StringConcatenate("Код ошибки = ",error_code,". Ожидается параметр типа double"); break; case 4065: error_string = StringConcatenate("Код ошибки = ",error_code,". В качестве параметра ожидается массив"); break; case 4066: error_string = StringConcatenate("Код ошибки = ",error_code,". Запрошенные исторические данные в состоянии обновления"); break; case 4067: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка при выполнении торговой операции"); break; case 4099: error_string = StringConcatenate("Код ошибки = ",error_code,". Конец файла"); break; case 4100: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка при работе с файлом"); break; case 4101: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильное имя файла"); break; case 4102: error_string = StringConcatenate("Код ошибки = ",error_code,". Слишком много открытых файлов"); break; case 4103: error_string = StringConcatenate("Код ошибки = ",error_code,". Невозможно открыть файл"); break; case 4104: error_string = StringConcatenate("Код ошибки = ",error_code,". Несовместимый режим доступа к файлу"); break; case 4105: error_string = StringConcatenate("Код ошибки = ",error_code,". Ни один ордер не выбран"); break; case 4106: error_string = StringConcatenate("Код ошибки = ",error_code,". Неизвестный символ"); break; case 4107: error_string = StringConcatenate("Код ошибки = ",error_code,". Неправильный параметр цены для торговой функции"); break; case 4108: error_string = StringConcatenate("Код ошибки = ",error_code,". Неверный номер тикета"); break; case 4109: error_string = StringConcatenate("Код ошибки = ",error_code,". Торговля не разрешена"); break; case 4110: error_string = StringConcatenate("Код ошибки = ",error_code,". Длинные позиции не разрешены"); break; case 4111: error_string = StringConcatenate("Код ошибки = ",error_code,". Короткие позиции не разрешены"); break; case 4200: error_string = StringConcatenate("Код ошибки = ",error_code,". Объект уже существует"); break; case 4201: error_string = StringConcatenate("Код ошибки = ",error_code,". Запрошено неизвестное свойство объекта"); break; case 4202: error_string = StringConcatenate("Код ошибки = ",error_code,". Объект не существует"); break; case 4203: error_string = StringConcatenate("Код ошибки = ",error_code,". Неизвестный тип объекта"); break; case 4204: error_string = StringConcatenate("Код ошибки = ",error_code,". Нет имени объекта"); break; case 4205: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка координат объекта"); break; case 4206: error_string = StringConcatenate("Код ошибки = ",error_code,". Не найдено указанное подокно"); break; case 4207: error_string = StringConcatenate("Код ошибки = ",error_code,". Ошибка при работе с объектом"); break; default: error_string = StringConcatenate("Код ошибки = ",error_code,". неизвестная ошибка"); } //---- return(error_string); } //+------------------------------------------------------------------+