//Version  January 7, 2007 Final
//+------------------------------------------------------------------+
//|                                                JLiteSeries().mqh |
//|                 JMA code: Copyright © 1998,       Jurik Research |
//|                                          http://www.jurikres.com | 
//|       JLiteSeries() MQL4: Copyright © 2006,     Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+ 
  /*

  +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS <<< Функция JLiteSeries() >>> SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+

  +-----------------------------------------+ <<< Назначение >>> +----------------------------------------------------+

  Функция  JLiteSeries() предназначена  для использования алгоритма JLite при  написании любых индикаторов теханализа и
  экспертов,  для  замены  расчёта  классического  усреднения  на  этот  алгоритм.  Функция  не работает, если параметр
  nJLite.limit  принимает  значение,  равное нулю! Все индикаторы, сделанные мною для JLiteSeries(), выполнены с учётом
  этого  ограничения.  Файл  следует  положить в папку MetaTrader\experts\include\ Алгоритм функции JLiteSeries() - это
  полный  аналог  алгоритма  JJMASeries,  у  которого  отсутствует  адаптивный  код.  Поэтому  иногда  эта функция даёт
  результаты, слегка запаздывающие по сравнению с JLiteSeries(), но зато затраты компьютерных ресурсов на JLiteSeries()
  в  шесть  раз  ниже,  чем  на JJMASeries(). Функцию JLiteSeries() удобно применять для индикаторов с большой глубиной
  сглаживания  типа  полос  Боллинджера  или  каналов.  В  одном  индикаторе нельзя одновременно применять JJMASeries и
  JLiteSeries()!!!  Для замены в индикаторе функции JJMASeries на JLiteSeries() достаточно в тексте индикатора заменить
  строку  #include  <JJMASeries.mqh> на строку #include <JLiteSeries.mqh> . Следует учесть, что если 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    - номер рассчитываемого бара, параметр  должен  изменяться оператором цикла от максимального значения к 
                  нулевому.   Причём его максимальное значение всегда должно равняться значению параметра nJMA.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() через
  внешний  оператор цикла была нарушена правильная последовательность изменения параметра nJMA.bar, то в лог файл будет
  записана и эта информация. Следует учесть, что некоторые ошибки программного кода будут порождать дальнейшие ошибки в
  его исполнении и поэтому, если функция JLiteSeries() пишет в лог файл сразу несколько ошибок, то устранять их следует
  в  порядке  времени  возникновения. В правильно написанном индикаторе функция JLiteSeries() может делать записи в лог
  файл  только  при  нарушениях  работы  операционной системы. Исключение составляет запись изменения размеров буферных
  переменных  при  перезагрузке  индикатора  или эксперта, которая происходит при каждом вызове функции init(). 
  
  +---------------------------------+ <<< Пример обращения к функции >>> +--------------------------------------------+

//----+ определение функций JLiteSeries() 
#include <JLiteSeries.mqh>
//+------------------------------------------------------------------+
//| 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);
}
//----+ 

  */
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
//+++++++++++++++++++++++++++++++++++++++++++++++++++++ <<< JLiteSeries() >>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++|
//SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+

//----++ <<< Введение и инициализация переменных >>> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
double dJLite.fB0,dJLite.fD0,dJLite.fA8[1],dJLite.fA8m[1],dJLite.fC0[1],dJLite.fC0m[1],dJLite.fC8[1];
double dJLite.fC8m[1],dJLite.Kg[1],dJLite.Pf[1],dJLite.fB0dJLite.f20,dJLite.f20,dJLite.f30,dJLite.f40;
double dJLite.JLite[1],dJLite.JLitem[1];
int    nJLite.TIME[1],nJLite.n,nJLite.Error,nJLite.Tnew,nJLite.Told,nJLite.size,nJLite.Resize;

//----++ <<< Объявление функции JurXSeries() >>> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
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
  )
//----++ +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
{
nJLite.n=nJLite.number;

nJLite.reset=1;
//=====+ <<< Проверки на ошибки >>> ====================================================================================================+
if (nJLite.bar==nJLite.limit)
 {
  //----++ проверка на инициализацию функции JLiteSeries()
  if(nJLite.Resize<1)
   {
    Print("JLiteSeries number ="+nJLite.n+
         ". Не было сделано изменение размеров буферных переменных функцией JLiteSeriesResize()");
    if(nJLite.Resize==0)
          Print("JLiteSeries number ="+nJLite.n+
                ". Следует дописать обращение к функции JLiteSeriesResize() в блок инициализации");
         
    return(0.0);
   }
  //----++ проверка на ошибку в исполнении программного кода, предшествовавшего функции JLiteSeries() 
  nJLite.Error=GetLastError();
  if(nJLite.Error>4000)
   {
    Print("JLiteSeries number ="+nJLite.n+
        ". В коде, предшествующем обращению к функции JLiteSeries() number = "
                                                                    +nJLite.n+" ошибка!!!");
    Print("JLiteSeries number ="+nJLite.n+ ". ",JLite_ErrDescr(nJLite.Error));  
   }

  //----++ проверка на ошибку в задании переменных nJLite.number и nJLiteResize.Size
  nJLite.size=ArraySize(dJLite.fC0);
  if (nJLite.size< nJLite.n) 
   {
    Print("JLiteSeries number ="+nJLite.n+
                ". Ошибка!!! Неправильно задано значение переменной nJLite.number="
                                                          +nJLite.n+" функции JLiteSeries()");
    Print("JLiteSeries number ="+nJLite.n+
                ". Или неправильно задано значение  переменной nJLiteResize.Size="
                                                  +nJLite.size+" функции JJMASeriesResize()");
    return(0.0);
   }
 }
//----++ проверка на ошибку в последовательности изменения переменной nJLite.bar
if((nJLite.limit>=nJLite.MaxBar)&&(nJLite.bar==0))
    if((nJLite.MaxBar>30)&&(nJLite.TIME[nJLite.n]==0))
                  Print("JLiteSeries number ="+nJLite.n+
                        ". Ошибка!!! Нарушена правильная последовательность изменения параметра nJLite.bar внешним оператором цикла!!!");  
//----++ +==============================================================================================================================+  
if (nJLite.bar> nJLite.MaxBar){nJLite.reset=0;return(0.0);}
if((nJLite.bar==nJLite.MaxBar)||(nJLite.din!=0))
  {
   //----++ <<< Расчёт коэффициентов  >>> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
   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;
   //----++SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
  }

//--+
if((nJLite.bar==nJLite.limit)&&(nJLite.limit<nJLite.MaxBar))
  {
   //----+ <<< Восстановление значений переменных >>> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
   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("JLiteSeries number ="+nJLite.n+
              ". Ошибка!!! Параметр nJLite.limit функции JLiteSeries() меньше, чем необходимо");
      }
    else 
      { 
       int nJLite.LimitERROR=nJLite.limit+1-iBarShift(NULL,0,nJLite.TIME[nJLite.n],TRUE);
       Print("JLiteSeries number ="+nJLite.n+
            ". Ошибка!!! Параметр nJLite.limit функции JLiteSeries() больше, чем необходимо на "
                                                                                +nJLite.LimitERROR+"");
      }
    //--+ Возврат через nJLite.reset=-1; ошибки в расчёте функции JLiteSeries
    return(0);
   }
//----+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
  }
if ((nJLite.bar==1)&&( nJLite.limit!=1))
  {
   //--+ <<< Сохранение значений переменных >>> +SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
   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];
   //--+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
  }

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("JLiteSeries number ="+nJLite.n+". При исполнении функции JLiteSeries() произошла ошибка!!!");
   Print("JLiteSeries number ="+nJLite.n+ ". ",JLite_ErrDescr(nJLite.Error));  
   return(0.0);
  }
nJLite.reset=0;
if (nJLite.bar>=nJLite.MaxBar-30-2*nJLite.Length)return(0.0);
else return(dJLite.JLite[nJLite.n]);
//----+  Завершение вычислений функции JLiteSeries() --------------------------+
}
//--+ --------------------------------------------------------------------------------------------+

//+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
// JLiteSeriesReset - Это дополнительная функция для изменения размеров буферных переменных       | 
// функции JLiteSeries. Пример обращения: JLiteSeriesReset(5); где 5 - это количество обращений к | 
// JLiteSeries() в тексте индикатора. Это обращение к функции  JLiteSeriesReset следует поместить |
// в блок инициализации пользовательского индикатора или эксперта                                 |
//+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
int JJMASeriesResize(int nJLiteResize.Size)
 {
//----+
  if(nJLiteResize.Size<1)
   {
    Print("JJMASeriesResize: Ошибка!!! Параметр nJLiteResize.Size не может быть меньше единицы!!!"); 
    nJLite.Resize=-1; 
    return(0);
   }  
  int nJLiteResize.reset,nJLiteResize.cycle;
  //--+
  while(nJLiteResize.cycle==0)
   {
    //----++ <<< изменение размеров буферных переменных >>> +SSSSSSSSSSSSSSSSSSSSSSSS+
    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;}
    //+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
    nJLiteResize.cycle=1;
   }
  //--+
  if(nJLiteResize.reset==-1)
   {
    Print("JLiteSeriesResize: Ошибка!!! Не удалось изменить размеры буферных переменных функции JLiteSeries().");
    int nJLiteResize.Error=GetLastError();
    if(nJLiteResize.Error>4000)Print("JJMASeriesResize(): ",JLite_ErrDescr(nJLiteResize.Error));       
    nJLite.Resize=-2;
    return(0);
   }
  else  
   {
    Print("JLiteSeriesResize: JLiteSeries() size = "+nJLiteResize.Size+"");
    nJLite.Resize=nJLiteResize.Size;
    return(nJLiteResize.Size);
   }  
//----+
 }
//--+ --------------------------------------------------------------------------------------------+
/*
//--+ ---------------------------------------------------------------------------------------------------+
//+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
JJMASeriesAlert - Это дополнительная функция для индикации ошибки в задании внешних переменных           |
функции JLiteSeries.                                                                                     |
  -------------------------- входные параметры  --------------------------                               |
JLiteSeriesAlert.Number                                                                                  |
JLiteSeriesAlert.ExternVar значение внешней переменной для параметра nJLite.Length                       |
JLiteSeriesAlert.name имя внешней переменной для параметра nJLite.Phase, если JLiteSeriesAlert.Number=0  | 
или nJLite.Phase, если JLiteSeriesAlert.Number=1.                                                        |
  -------------------------- Пример использования  -----------------------                               |
  int init()                                                                                             |
//----                                                                                                   |
Здесь какая-то инициализация переменных и буферов                                                        |
                                                                                                         |
//---- установка алертов на недопустимые значения внешних переменных                                     |
JJMASeriesAlert(0,"Length1",Length1);                                                                    |
JJMASeriesAlert(0,"Length2",Length2);                                                                    |
JJMASeriesAlert(1,"Phase1",Phase1);                                                                      |                                                            
JJMASeriesAlert(1,"Phase2",Phase2);                                                                      |                                                          
//---- завершение инициализации                                                                          |
return(0);                                                                                               |
}                                                                                                        |
//+SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS+
*/
void JJMASeriesAlert
 (
  int JLiteSeriesAlert.Number, string JLiteSeriesAlert.name, int JLiteSeriesAlert.ExternVar
 )
 {
  //---- установка алертов на недопустимые значения входных параметров ==========================+ 
  if(JLiteSeriesAlert.Number==0)if(JLiteSeriesAlert.ExternVar<1)
          {Alert("Параметр "+JLiteSeriesAlert.name+" должен быть не менее 1" 
          + " Вы ввели недопустимое " +JLiteSeriesAlert.ExternVar+ " будет использовано  1"  );}
  if(JLiteSeriesAlert.Number==1)
   {
    if(JLiteSeriesAlert.ExternVar<-100)
          {Alert("Параметр "+JLiteSeriesAlert.name+" должен быть от -100 до +100" 
          + " Вы ввели недопустимое "+JLiteSeriesAlert.ExternVar+  " будет использовано -100");}
    if(JLiteSeriesAlert.ExternVar> 100)
          {Alert("Параметр "+JLiteSeriesAlert.name+" должен быть от -100 до +100" 
          + " Вы ввели недопустимое "+JLiteSeriesAlert.ExternVar+  " будет использовано  100");}
   }
 }
//--+ --------------------------------------------------------------------------------------------+

// перевод сделан Николаем Косициным 01.12.2006  
//+------------------------------------------------------------------+
//|                                     JLite_ErrDescr_RUS(MQL4).mqh |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
string JLite_ErrDescr(int error_code)
 {
  string error_string;
//----
  switch(error_code)
    {
     //---- MQL4 ошибки 
     case 4000: error_string="Код ошибки = "+error_code+". нет ошибки";                                                  break;
     case 4001: error_string="Код ошибки = "+error_code+". Неправильный указатель функции";                              break;
     case 4002: error_string="Код ошибки = "+error_code+". индекс массива не соответствует его размеру";                 break;
     case 4003: error_string="Код ошибки = "+error_code+". Нет памяти для стека функций";                                break;
     case 4004: error_string="Код ошибки = "+error_code+". Переполнение стека после рекурсивного вызова";                break;
     case 4005: error_string="Код ошибки = "+error_code+". На стеке нет памяти для передачи параметров";                 break;
     case 4006: error_string="Код ошибки = "+error_code+". Нет памяти для строкового параметра";                         break;
     case 4007: error_string="Код ошибки = "+error_code+". Нет памяти для временной строки";                             break;
     case 4008: error_string="Код ошибки = "+error_code+". Неинициализированная строка";                                 break;
     case 4009: error_string="Код ошибки = "+error_code+". Неинициализированная строка в массиве";                       break;
     case 4010: error_string="Код ошибки = "+error_code+". Нет памяти для строкового массива";                           break;
     case 4011: error_string="Код ошибки = "+error_code+". Слишком длинная строка";                                      break;
     case 4012: error_string="Код ошибки = "+error_code+". Остаток от деления на ноль";                                  break;
     case 4013: error_string="Код ошибки = "+error_code+". Деление на ноль";                                             break;
     case 4014: error_string="Код ошибки = "+error_code+". Неизвестная команда";                                         break;
     case 4015: error_string="Код ошибки = "+error_code+". Неправильный переход (never generated error)";                break;
     case 4016: error_string="Код ошибки = "+error_code+". Неинициализированный массив";                                 break;
     case 4017: error_string="Код ошибки = "+error_code+". Вызовы DLL не разрешены";                                     break;
     case 4018: error_string="Код ошибки = "+error_code+". Невозможно загрузить библиотеку";                             break;
     case 4019: error_string="Код ошибки = "+error_code+". Невозможно вызвать функцию";                                  break;
     case 4020: error_string="Код ошибки = "+error_code+". Вызовы внешних библиотечных функций не разрешены";            break;
     case 4021: error_string="Код ошибки = "+error_code+". Недостаточно памяти для строки, возвращаемой из функции";     break;
     case 4022: error_string="Код ошибки = "+error_code+". Система занята (never generated error)";                      break;
     case 4050: error_string="Код ошибки = "+error_code+". Неправильное количество параметров функции";                  break;
     case 4051: error_string="Код ошибки = "+error_code+". Недопустимое значение параметра функции";                     break;
     case 4052: error_string="Код ошибки = "+error_code+". Внутренняя ошибка строковой функции";                         break;
     case 4053: error_string="Код ошибки = "+error_code+". Ошибка массива";                                              break;
     case 4054: error_string="Код ошибки = "+error_code+". Неправильное использование массива-таймсерии";                break;
     case 4055: error_string="Код ошибки = "+error_code+". Ошибка пользовательского индикатора";                         break;
     case 4056: error_string="Код ошибки = "+error_code+". Массивы несовместимы";                                        break;
     case 4057: error_string="Код ошибки = "+error_code+". Ошибка обработки глобальныех переменных";                     break;
     case 4058: error_string="Код ошибки = "+error_code+". Глобальная переменная не обнаружена";                         break;
     case 4059: error_string="Код ошибки = "+error_code+". Функция не разрешена в тестовом режиме";                      break;
     case 4060: error_string="Код ошибки = "+error_code+". Функция не подтверждена";                                     break;
     case 4061: error_string="Код ошибки = "+error_code+". Ошибка отправки почты";                                       break;
     case 4062: error_string="Код ошибки = "+error_code+". Ожидается параметр типа string";                              break;
     case 4063: error_string="Код ошибки = "+error_code+". Ожидается параметр типа integer";                             break;
     case 4064: error_string="Код ошибки = "+error_code+". Ожидается параметр типа double";                              break;
     case 4065: error_string="Код ошибки = "+error_code+". В качестве параметра ожидается массив";                       break;
     case 4066: error_string="Код ошибки = "+error_code+". Запрошенные исторические данные в состоянии обновления";      break;
     case 4067: error_string="Код ошибки = "+error_code+". Ошибка при выполнении торговой операции";                     break;
     case 4099: error_string="Код ошибки = "+error_code+". Конец файла";                                                 break;
     case 4100: error_string="Код ошибки = "+error_code+". Ошибка при работе с файлом";                                  break;
     case 4101: error_string="Код ошибки = "+error_code+". Неправильное имя файла";                                      break;
     case 4102: error_string="Код ошибки = "+error_code+". Слишком много открытых файлов";                               break;
     case 4103: error_string="Код ошибки = "+error_code+". Невозможно открыть файл";                                     break;
     case 4104: error_string="Код ошибки = "+error_code+". Несовместимый режим доступа к файлу";                         break;
     case 4105: error_string="Код ошибки = "+error_code+". Ни один ордер не выбран";                                     break;
     case 4106: error_string="Код ошибки = "+error_code+". Неизвестный символ";                                          break;
     case 4107: error_string="Код ошибки = "+error_code+". Неправильный параметр цены для торговой функции";             break;
     case 4108: error_string="Код ошибки = "+error_code+". Неверный номер тикета";                                       break;
     case 4109: error_string="Код ошибки = "+error_code+". Торговля не разрешена";                                       break;
     case 4110: error_string="Код ошибки = "+error_code+". Длинные позиции не разрешены";                                break;
     case 4111: error_string="Код ошибки = "+error_code+". Короткие позиции не разрешены";                               break;
     case 4200: error_string="Код ошибки = "+error_code+". Объект уже существует";                                       break;
     case 4201: error_string="Код ошибки = "+error_code+". Запрошено неизвестное свойство объекта";                      break;
     case 4202: error_string="Код ошибки = "+error_code+". Объект не существует";                                        break;
     case 4203: error_string="Код ошибки = "+error_code+". Неизвестный тип объекта";                                     break;
     case 4204: error_string="Код ошибки = "+error_code+". Нет имени объекта";                                           break;
     case 4205: error_string="Код ошибки = "+error_code+". Ошибка координат объекта";                                    break;
     case 4206: error_string="Код ошибки = "+error_code+". Не найдено указанное подокно";                                break;
     case 4207: error_string="Код ошибки = "+error_code+". Ошибка при работе с объектом";                                break;
     default:   error_string="Код ошибки = "+error_code+". неизвестная ошибка";
    }
//----
  return(error_string);
 }
//+------------------------------------------------------------------+


