//+------------------------------------------------------------------+
//|                                                          RVA.mq4 |
//|                                                             `Shu |
//|                                               http://FxVolume.ru |
//|                                                       12.01.2010 |
//+------------------------------------------------------------------+
#property copyright "`Shu"
#property link      "http://FxVolume.ru"
#include <WinUser32.mqh>

#property indicator_separate_window

#property indicator_level1 0

#property indicator_buffers 4

#property indicator_color1 Lime
#property indicator_color2 Red

#property indicator_color3 Lime
#property indicator_color4 Red

#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 2
#property indicator_width4 2

double Buf1[], Buf2[], Buf3[], Buf4[];

// =================================================================
#import "wininet.dll"
int InternetAttemptConnect (int x);

   #define INTERNET_FLAG_PRAGMA_NOCACHE    0x00000100
   #define INTERNET_FLAG_NO_CACHE_WRITE    0x04000000
   #define INTERNET_FLAG_RELOAD            0x80000000

   int InternetOpenA(string sAgent, int lAccessType, 
                    string sProxyName = "", string sProxyBypass = "", 
                    int lFlags = 0);
   int InternetOpenUrlA(int hInternetSession, string sUrl, 
                        string sHeaders = "", int lHeadersLength = 0,
                        int lFlags = 0, int lContext = 0);
   int InternetReadFile(int hFile, int& sBuffer[], int lNumBytesToRead, 
                        int& lNumberOfBytesRead[]);
   int InternetCloseHandle(int hInet);
   bool Post(string lpszAction, string lpszData, string lpszReferer);
   bool Get(string lpszData, string lpszReferer);
#import
// =================================================================
#import "user32.dll"
   int PostMessageA(int hWnd, int Msg, int wParam, int lParam);
#import
// =================================================================

string version = "1.05";
string lang    = "EN";  // {RU;EN}

string pref    = "RVA.";
string font    = "Comic Sans MS";

string file.pref = "";

string sss[];
int    v[][5];   // - оно
int    vt[][5];  // - оно, текусчее
int    vtf[][5]; // - оно, ТФ

string currency;           // - это передаваемый на сервер символ..
int    delta;

// =================================================================
extern string     Login            = "ewef";
extern string     Password         = "ewef";

extern int        ShiftTime        = 2;

extern bool       Prefix           = false;     // - если префикс, то соответствия

extern string     EURUSD           = "EURUSD";
extern string     AUDUSD           = "AUDUSD";
extern string     USDCAD           = "USDCAD";
extern string     USDJPY           = "USDJPY";
extern string     GBPUSD           = "GBPUSD";
extern string     USDCHF           = "USDCHF";
extern string     Futures_6E       = "6EH0";
extern string     Futures_6A       = "6AH0";
extern string     Futures_6C       = "6CH0";
extern string     Futures_6J       = "6JH0";
extern string     Futures_6B       = "6BH0";
extern string     Futures_6S       = "6SH0";
extern string     ES_mini          = "ES";
extern string     GOLD             = "GC";

extern bool       ShowDelta        = false;
extern int        ColorBars        = 0;       
                                    // 0 - "стандартный", на деле бесполезный: в цвет ценовых баров
                                    // 1 - бар объёма больше предыдущего - зелёный, меньше - красный..
                                    // 2 - по дельте

extern int        Refresh.Sec = 15;    // - в секундахЪ
extern int        Refresh.Add = 15;    // - добавить по рэндомайзу секунд жЭ
extern int        Refresh.History = 5; // - в минутах
extern int        History.Days    = 1; // - сколько дней истории закачивать..

// =================================================================

string
         al.1   = "Ошибка: ",
         al.1e  = "Error: ",         
         al.2   = "Ошибка: Необходимо ввести Login/Password",
         al.2e  = "Error: need Login/Password";         

// ---
datetime NextUpdate;             // - Local Time !!!
datetime NextUpdateHistory;      // - Local Time !!!
int win;
datetime LockDo;
datetime dt.check[];

int History.Days.0;

string shu = "(c) `Shu & FxVolume.ru";
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {
   int err;
   string s;

   shu = " [" + version + "] " + shu;

   Print(WindowExpertName() + shu);

   IndicatorDigits(0);

   SetIndexBuffer(0,Buf1);
   SetIndexBuffer(1,Buf2);
   SetIndexBuffer(2,Buf3);
   SetIndexBuffer(3,Buf4);

   if (ShowDelta) {
      SetIndexStyle(0, DRAW_NONE);
      SetIndexStyle(1, DRAW_NONE);
      SetIndexStyle(2, DRAW_HISTOGRAM);
      SetIndexStyle(3, DRAW_HISTOGRAM);
   }
   else {
      SetIndexStyle(0, DRAW_HISTOGRAM);
      SetIndexStyle(1, DRAW_HISTOGRAM);
      SetIndexStyle(2, DRAW_NONE);
      SetIndexStyle(3, DRAW_NONE);
   }

   SetIndexEmptyValue(0, 0);
   SetIndexEmptyValue(1, 0);
   SetIndexEmptyValue(2, 0);
   SetIndexEmptyValue(3, 0);

   file.pref = "RVA\\" + Symbol() + "\\";
   
   if (Refresh.Sec < 5)     Refresh.Sec = 5;
   if (Refresh.Add < 5)     Refresh.Add = 5;
   if (Refresh.History < 5) Refresh.History = 5;
   
   ShiftTime = ShiftTime * PERIOD_H1 * 60;   // - приведём для удобства в секунды

   s = "RVA (© Shu & FxVolume.ru) " + Symbol() + ":" + strPeriod(Period());
   IndicatorShortName.rva(s);

   GetCurrency();

   DoRand();
   
   NextUpdate = 0;
   NextUpdateHistory = 0; // - пущай разок дёрнет ещё..
   
   History.Days.0 = History.Days;
   
   ArrayResize(v, 0);   // для чёткости восприятия ;-)
   
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
   int i, iv;
   int count;
   int bs;
   int limit;
   int err;
   double d;
   double bu[5];
   datetime dt;
   string s;
   bool b;

   if (TimeLocal() < NextUpdate) return;
                            else NextUpdate = TimeLocal() + RandInt(Refresh.Sec, Refresh.Sec + Refresh.Add); // - *** секунда, не чаще.. или другое значени. в секундах..

   if ((Login == "") || (Password == "")) {
      NextUpdate = TimeLocal() + 60 * PERIOD_MN1;
      if (win > 0) SetLabel(pref + "w.err", "RVA: " + al.2, Red, 5, 3, 2, 10, font);
      Alert(al.2);
      return;
   }

   b = false;
   count = 0;
   while (!b) {
      // - ваще не должно быть никада..
      if (count >= 2) {
         NextUpdate = 0;  // - следующий тик
         s = "RVA (© Shu & FxVolume.ru) " + "..update";
         IndicatorShortName.rva(s);
         return;  // - чивота нито
      }
      GetLastError();
      ArrayCopySeries(dt.check, MODE_TIME, Symbol(), Period());
      err = GetLastError();

      if (err != 4066) {
         b = true;
      }
      else {
         Sleep(1000);
      }
      count++;
   }

   s = "RVA (© Shu & FxVolume.ru) " + Symbol() + ":" + strPeriod(Period()) + " " + iifs(ShowDelta, " Delta ", " Volume ");
   IndicatorShortName.rva(s);

   if (TimeLocal() < NextUpdateHistory) {
   }
   else {
      
      for (i = 1; i <= History.Days.0; i++) {
         err = GetHistory(vt, "min-hist-askbid", TimeLocal() - PERIOD_D1 * 60 * i, "." + TimeToStr(TimeLocal() - PERIOD_D1 * 60 * i, TIME_DATE));
         Synx(v, vt);
      }
      
      History.Days.0 = 0;
      
      err = GetHistory(vt, "min-hist-askbid");
      Synx(v, vt);
      
      NextUpdateHistory = TimeLocal() + RandInt(Refresh.History * 60, Refresh.History * 60 * 1.3);
   }

   err = GetHistory(vt, "min-askbid");
   if (err < 0) {
      switch (err) {
         case -1:   
         case -2:
         case -3:
                  NextUpdate = TimeLocal() + 60 * PERIOD_D1;  
                  break;
         default:
                  NextUpdate = TimeLocal() + 60 * 5;  // - 5 минут спим..
                  break;
      }
      
      s = "RVA (© Shu & FxVolume.ru) " + "..error: " + DoubleToStr(err, 0);
      
      IndicatorShortName.rva(s);
      return;  // - чивота нито
   }

   b = Synx(v, vt); // - возврат не используем - сейчас стало всегда тру и гори оно всё огнём

   CalcTF(v, vtf);
   
   limit = PERIOD_D1 / Period() * (History.Days + 1);
   
   limit = iif(Buf1[5] == 0, limit, 5);

   for (i = limit; i >= 0; i--) {
      
      dt = Time[i];
      iv = FindTime(dt, vtf);
      
      if (iv >= 0) {

         Buf1[i] = vtf[iv][1];
         Buf2[i] = vtf[iv][1];
         Buf3[i] = vtf[iv][4];
         Buf4[i] = vtf[iv][4];
         
         switch (ColorBars) {
            case 1:          
                        if (MathMax(Buf1[i], Buf2[i]) < MathMax(Buf1[i+1], Buf2[i+1])) Buf1[i] = 0;
                                                                                  else Buf2[i] = 0;
                        break;
                        
            case 2:          
                        if (vtf[iv][4] < 0) Buf1[i] = 0;
                                       else Buf2[i] = 0;
                        break;
            case 0:     
            default:    
                        if (Close[i] < Open[i]) Buf1[i] = 0;
                                           else Buf2[i] = 0;
                        break;
         }

         if (vtf[iv][4] < 0) Buf3[i] = 0;
                        else Buf4[i] = 0;
      }

      if (i == 0) {
         bu[1] = Buf1[0];
         bu[2] = Buf2[0];
         bu[3] = Buf3[0];
         bu[4] = Buf4[0];
      }
      
      if (ShowDelta) {
         Buf1[i] = 0;
         Buf2[i] = 0;
      }
      else {
         Buf3[i] = 0;
         Buf4[i] = 0;
      }
      
   }

   if (Buf1[1] == 0) Buf1[1] = 0.000001;  // не густо, но и не пусто..
   if (Buf2[1] == 0) Buf2[1] = 0.000001;
   if (Buf3[1] == 0) Buf3[1] = 0.000001;
   if (Buf4[1] == 0) Buf4[1] = 0.000001;

   s = "RVA (© Shu & FxVolume.ru) " + Symbol() + ": " + strPeriod(Period())
     + iifs(ShowDelta, " Delta° ", " Volume° ") 
     + " v…" + is(MathMax(bu[1], bu[2]))
     + " d…" + is(iif(bu[3] == 0, bu[4], bu[3]))
     + " :";
     
   IndicatorShortName.rva(s);

   if (win > 0) {
      DelLabel(win, "SessionDelta", "SessionDelta" + win);
      SetLabel("SessionDelta" + win, "Session Delta: " + is(delta), Red, 10, 18, 0, RandInt(9, 12), "Comic Sans MS");
   }
      
return(0);
}
//+------------------------------------------------------------------+
void CalcTF(int &v[][], int &vtf[][]) {
   int i, ivtf;
   int hd;
   datetime dt0, dt, dt1;
   bool b;
   
   ArrayResize(vtf, 100000);
   
   ivtf = 0;
   
   hd = MathMax(1, History.Days);
   
   dt0 = StartDay(TimeCurrent() - hd * PERIOD_D1 * 60);
   
   dt  = dt0;
   dt1 = dt + Period() * 60;   

   while (true) {
      if (dt1 > TimeCurrent() + Period() * 60) break;      
      vtf[ivtf][0] = dt;
      vtf[ivtf][1] = 0;
      vtf[ivtf][4] = 0;
      for (i = 0; i < ArrayRange(v, 0); i++) {
         if (v[i][0] > dt1) continue;
         if ((v[i][0] >= dt) && (v[i][0] < dt1)) {
            vtf[ivtf][1] = vtf[ivtf][1] + v[i][1];
            vtf[ivtf][4] = vtf[ivtf][4] + v[i][4];
         }
      }
      ivtf++;
      dt  = dt + Period() * 60;
      dt1 = dt + Period() * 60;
   }

   ArrayResize(vtf, ivtf);

   // - расчёт дневной дельты..
   
   delta = 0;
   dt = StartDay(TimeCurrent());
   for (i = 0; i < ArrayRange(v, 0); i++) {
      if (v[i][0] < dt) continue;
      delta = delta + v[i][4];
   }

return;
}
//+------------------------------------------------------------------+
bool Synx(int &v[][], int &vt[][]) {
   bool r;
   int i, j, l, iv, ivt;
   
   iv  = ArrayRange(v,  0);
   ivt = ArrayRange(vt, 0);
   
   for (i = 0; i < ivt; i++) {
      l = FindTime(vt[i][0], v);
      if (l >= 0) {
         v[l][1] = vt[i][1];
         v[l][2] = vt[i][2];
         v[l][3] = vt[i][3];
         v[l][4] = vt[i][4];
      }
      else {
         iv++;
         ArrayResize(v, iv);
         v[iv-1][0] = vt[i][0];
         v[iv-1][1] = vt[i][1];
         v[iv-1][2] = vt[i][2];
         v[iv-1][3] = vt[i][3];
         v[iv-1][4] = vt[i][4];
      }
   }
   
return(true);
}
//+------------------------------------------------------------------+
int FindTime(datetime dt, int &v[][]) {
   int r;
   int i;
   int iv;
   
   iv = ArrayRange(v, 0);
   r = -1;
   for (i = 0; i < iv; i++) {
      if (v[i][0] != dt) continue;
      r = i;
      break;
   }

return(r);
}
//+------------------------------------------------------------------+
int GetHistory(int &v[][], string type = "min-askbid", datetime dt = 0, string suff = "") {
   int err, f, i.sss;
   string url;
   string fn;
   string sdt;
   string class;
   bool b;
   bool file.empty;

   if (dt == 0) {
      dt  = TimeCurrent() + ShiftTime;
   }

   sdt = TimeToStr(dt, TIME_DATE);
   sdt = StrRep(sdt, ".", "");

   fn = type + suff + ".txt";

   file.empty = false;
   b = true;
   if (suff != "") {
      f = FileOpen(file.pref + fn, FILE_CSV|FILE_READ, "*");
      if (f == -1) {
         b = true;   // - надо запрашивать новый..
      }
      else {
         // - открыли, значит надо его читать!! пишем в sss
         ArrayResize(sss, 10000);
         i.sss = 0;
         while(! FileIsEnding(f)) {
            sss[i.sss] =  FileReadString(f);
            if (sss[i.sss] == "") continue;
            i.sss++;
         }
         ArrayResize(sss, i.sss);
         FileClose(f);
         b = false;
         if ((i.sss <= 4) && (TimeDayOfWeek(dt) != 6) && (TimeDayOfWeek(dt) != 0)) b = true;  // - пустые файлики пока перезапрашиваем ПОЛЮБОМУ! (потому что нет "исторических" до 2-3 ночи след.дня)
      }
   }

   if (b) {
      // - надо читать с инета :-(
      class = "root";
   
      url = "http://rva.fxvolume.ru/i3/index.pl?login=" + Login + "&tool=" + currency + "&dt=" + sdt + "&rand=" + TimeLocal() + "&lang=" + lang + "&ver=" + version + "&class=" + class + "&type=" + type;
      if (suff != "") 
      url = "http://i3.fxvolume.ru/fcgi/i3/index.pl?login=" + Login + "&tool=" + currency + "&dt=" + sdt + "&rand=" + TimeLocal() + "&lang=" + lang + "&ver=" + version + "&class=" + class + "&type=" + type;
   
      if (ReadFileUrl(url, fn) < 0) {
         return(-100);
      }

      err = CheckError();   
      if (err < 0) {
         return(err);
      }   
   }

   Kick(v); // первоначальное заполнение
   
return(0);
}
//+------------------------------------------------------------------+
void Kick(int &v[][]) {
   int i, iv;
   string ss[], ss0[], ss1[], ss2[];
   datetime dt;
   string s;
   
   ArrayResize(v, ArraySize(sss));
   
   iv = 0;
   
   for (i = 0; i < ArraySize(sss); i++) {
      if (sss[i] == "\start") continue;
      if (sss[i] == "\end")   break;
      if (sss[i] == "Wait")   continue;
      TossStr(sss[i], ss);
      TossStr(ss[0], ss0, " ");
      TossStr(ss0[0], ss1, ".");
      TossStr(ss0[1], ss2, ":");
      
      v[iv][0] = StrToTime(ss1[2] + "." + ss1[1] + "." + ss1[0] + " " + ss2[0] + ":" + ss2[1]) - ShiftTime;
      v[iv][1] = StrToDouble(ss[1]);
      v[iv][2] = StrToDouble(ss[2]);
      v[iv][3] = StrToDouble(ss[3]);
      v[iv][4] = StrToDouble(ss[4]);
      
      iv++;
   }
   
   ArrayResize(v, iv);

return;
}
//+------------------------------------------------------------------+
int ReadFileUrl(string url, string to.file) {
   int i;
   int rv;
   int hInternetSession;
   int hURL;
   int cBuffer[256];
   int dwBytesRead[1]; 
   string TXT = "";
   string text;
   bool bResult;
   
   to.file = file.pref + to.file;

   if(!IsDllsAllowed()) {
       log("Необходимо в настройках разрешить использование DLL");
       return(-1);
   }

   rv = InternetAttemptConnect(0);
   if(rv != 0) {
      log("Ошибка при вызове InternetAttemptConnect()");
      return(-1);
   }
   
   hInternetSession = InternetOpenA(Password, 0, "", "", 0);
   if (hInternetSession <= 0) {
       log("Ошибка при вызове InternetOpenA()");
       return(-1);         
   }
   
   hURL = InternetOpenUrlA(hInternetSession, url, "", 0, 
								INTERNET_FLAG_NO_CACHE_WRITE | 
								INTERNET_FLAG_PRAGMA_NOCACHE | 
								INTERNET_FLAG_RELOAD, 0);
   
   if(hURL <= 0) {
       log("Ошибка при вызове InternetOpenUrlA()");
       InternetCloseHandle(hInternetSession);
       return(-1);         
   }    
     
   TXT = "";
   
   while(!IsStopped()) {
      
      dwBytesRead[0] = 0;
      for (i = 0; i < 256; i++) cBuffer[i] = 0;
      
      bResult = InternetReadFile(hURL, cBuffer, 1024, dwBytesRead);
      if (!bResult) {
         log("* bResult = false");
      }
               
      if (dwBytesRead[0] == 0) break;

      text = "";   
      
      for (i = 0; i < 256; i++) {
           text = text + CharToStr(cBuffer[i] & 0x000000FF);
        	  if(StringLen(text) == dwBytesRead[0]) break;
        	  text = text + CharToStr(cBuffer[i] >> 8 &  0x000000FF);
        	  if(StringLen(text) == dwBytesRead[0]) break;
           text = text + CharToStr(cBuffer[i] >> 16 & 0x000000FF);
           if(StringLen(text) == dwBytesRead[0]) break;
           text = text + CharToStr(cBuffer[i] >> 24 & 0x000000FF);
           if(StringLen(text) == dwBytesRead[0]) break;
      }
             
      TXT = TXT + text;
      Sleep(1);
   }  
   
   if(TXT != "") {
       int h = FileOpen(to.file, FILE_CSV|FILE_WRITE);
       if(h > 0) {
           FileWrite(h,TXT);
           FileClose(h);
           // - Alert("Готово! См. файл .../experts/files/SavedFromInternet.htm");
       }
       else {
           return(-1);
       }
   }
   else {
       return(-1);
   }
   
   if(TXT != "") {
      // *** попарсём
      Pars(TXT);
   }   
   
   InternetCloseHandle(hInternetSession);

return(0);
}
//+------------------------------------------------------------------+
void Pars(string &s) {
   int p1, p2;
   int sss.i;
   string s1;

   ArrayResize(sss, 10000);
   
   p1 = 0;
   sss.i = 0;
   
   while (true) {
      p2 = StringFind(s, CharToStr(10), p1);
      if (p2 == -1) break;
      s1 = StringSubstr(s, p1, p2 - p1);
      s1 = StrRep(s1, CharToStr(10), "");
      s1 = StrRep(s1, CharToStr(13), "");
      if (s1 != "") {
         sss[sss.i] = s1;
         sss.i++;
      }
      p1 = p2 + 1;
   }
   
   ArrayResize(sss, sss.i);   
   
return;
}
//+------------------------------------------------------------------+
string StrRep(string s, string old, string new) {
   // - символ конечно..
   string r;
   
   int i;
   int iOld, iNew;
   int ii;
  
   string ss;
  
   iOld = StringGetChar(old, 0);
   iNew = StringGetChar(new, 0);   
   
   r = "";
   ss = " ";
   for (i = 0; i < StringLen(s); i++) {
      ii = StringGetChar(s, i);
      if (ii == iOld) {
         ss = StringSetChar(ss, 0, iNew);
      }
      else {
         ss = StringSetChar(ss, 0, ii);
      }
      r = r + ss;
   }

return(r);
}
//+------------------------------------------------------------------+
void GetCurrency() {
   currency = StringSubstr( Symbol(), 0, 2);
   if(currency == "6E" ||currency == "6B" ||currency == "6A" ||currency =="6J" || currency =="6S" || currency =="6C"
      || currency == "ES" || currency == "GC")
   {}
   else
   {if(Prefix ==true)
      {  if( EURUSD==Symbol() )
            currency = "EURUSD";
         else if( AUDUSD==Symbol()) 
            currency = "AUDUSD";
         else if(USDCAD==Symbol()) 
            currency = "USDCAD";
         else if(USDJPY==Symbol()) 
            currency = "USDJPY";
         else if(GBPUSD==Symbol())
            currency = "GBPUSD";
         else if(USDCHF==Symbol()) 
            currency = "USDCHF";
         else if( Futures_6E==Symbol() )
            currency = "6E";
         else if( Futures_6A==Symbol()) 
            currency = "6A";
         else if(Futures_6C==Symbol()) 
            currency = "6C";
         else if(Futures_6J==Symbol()) 
            currency = "6J";
         else if(Futures_6B==Symbol())
            currency = "6B";
         else if(ES_mini==Symbol()) 
            currency = "ES";
         else if(GOLD==Symbol()) 
            currency = "GC";   
       }
      else     
       {currency = Symbol();}
   }

   if ((Symbol() == "Gold") || (Symbol() == "GOLD")) currency = "GC";   

return;
}
//+------------------------------------------------------------------+
// +++ на входе:  строка с разделителями
//     на выходе: массив строк
int TossStr( string s, string& mass[], string Разделитель = ";") {

   int i;
   int Нашли;
   string s1;
   
   ArrayResize(mass, 100);

   Нашли = 0;
   while ( s != "" ) {
      i = StringFind( s, Разделитель, 0);
      if ( i == -1 ) i = 255;
      s1 = StringTrimRight(StringTrimLeft(StringSubstr( s, 0, i ) ) );
      s = StringTrimRight(StringTrimLeft(StringSubstr( s, i+1, 255 ) ));
      mass[Нашли] = s1;
      Нашли++;
   }
   
   ArrayResize(mass, Нашли);

return(Нашли);
}
//+------------------------------------------------------------------+
// * возвращаем время начала дня!
datetime StartDay(datetime dt) {
   datetime r;
   r = dt / (PERIOD_D1 * 60);
   r = r * (PERIOD_D1 * 60);                       // - здесь получили время начала дня
return(r);   
}
//+------------------------------------------------------------------+
// условное назначение DOUBLE (!)
double iif(bool Условие, double ПервоеЗначение, double ВтороеЗначение) {
   if (Условие)      return(ПервоеЗначение);
               else  return(ВтороеЗначение);
}
//+------------------------------------------------------------------+
string iifs( bool Условие, string ПервоеЗначение, string ВтороеЗначение ) {
   if (Условие)      return(ПервоеЗначение);
               else  return(ВтороеЗначение);
}
//+------------------------------------------------------------------+
void SetLabel(string nm, string tx, color cl, int xd, int yd, int cr = 0, int fs = 9, string fo = "Arial") {
  if (ObjectFind(nm) < 0) ObjectCreate(nm, OBJ_LABEL, win, 0, 0);
  ObjectSetText(nm, tx, fs, fo);
  ObjectSet(nm, OBJPROP_COLOR    , cl);
  ObjectSet(nm, OBJPROP_XDISTANCE, xd);
  ObjectSet(nm, OBJPROP_YDISTANCE, yd);
  ObjectSet(nm, OBJPROP_CORNER   , cr);
  ObjectSet(nm, OBJPROP_FONTSIZE , fs);
}
//+------------------------------------------------------------------+
// - возвращает строчный "период"
string strPeriod(int p) {
   double d;
   string r;
   switch (p) {
      case PERIOD_M1:   r = "M1";    break;      
      case PERIOD_M5:   r = "M5";    break;
      case PERIOD_M15:  r = "M15"; /* r = "M15"; */    break;
      case PERIOD_M30:  r = "M30";    break;      
      case PERIOD_H1:   r = "H1";    break;
      case PERIOD_H4:   r = "H4";    break;
      case PERIOD_D1:   r = "Day";    break;
      case PERIOD_W1:   r = "Week";    break;
      case PERIOD_MN1:  r = "Month";    break;
      default:          d = p; 
                        r = DoubleToStr(d, 0);
   }
return(r);
}
//+------------------------------------------------------------------+
datetime RandInt(int from = 0, int to = 1) {
   // - это уже рэндомайзим..
   int i, k, r;
   datetime dt0;
   bool b;

   k = to - from;
   i = MathRand() / (32767 / k) ;   // - возвращает 0...32767
   r = from + i;

return(r);
}

//+------------------------------------------------------------------+
void DoRand() {
   int i, m;
   MathSrand(TimeLocal() - Bid * 1000 );
   
   m = 0;
   
   for (i = 0; i < StringLen(Symbol()); i++) {
      m = m + StringGetChar(Symbol(), i);
   }
   
   for (i = 0; i < m; i++) MathRand();
   
return;   
}
//+------------------------------------------------------------------+
string is(int i) {
   string s;
   s = DoubleToStr(i, 0);
return(s);
}
//+------------------------------------------------------------------+
int CheckError() {
   
   if ((sss[1] == "01") || (sss[1] == "02") || (sss[1] == "03")) {
      Print(al.1 + sss[2] + " !");
      Alert(WindowExpertName() + "> " + sss[2] + " !");
      if (win > 0) SetLabel(pref + "w.err", "RVA: " + sss[2], Red, 10, 10, 2, 10, font);
      return(-StrToInteger(sss[1])); // * значит ашибко
   }
   
   if (win > 0) SetLabel(pref + "w.err", "¤", Lime, 5, 3, 2, 10, font);
   
return(0);
}
//+------------------------------------------------------------------+
void IndicatorShortName.rva(string s) {
   IndicatorShortName(s);
   win = WindowFind(s);
return; 
}
//+------------------------------------------------------------------+
void DelLabel(int win, string s.kill, string s.no = "") {
   int i, iw;
   string s;
   
   for (i = ObjectsTotal()-1; i >= 0; i--) {
      s  = ObjectName(i);
      iw = ObjectFind(s);
      if (iw != win) continue;
      if (StringFind(s, s.kill) == -1) continue;
      if (s == s.no) continue;
      ObjectDelete(s);
   }

return;   
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void log(string s) {
   // cc(s);
   Print(s);
return;
}
//+------------------------------------------------------------------+

