Код платформы многовалютного многотаймфреймового советника - страница 4

 
HideYourRichess писал(а) >>

тут отписал https://forum.mql4.com/ru/20351/page2

Движок (платформа, шаблон) мультивалютного советника для работы с ТИКАМИ :

//+------------------------------------------------------------------+
//|                                               MultiSymbolТic.mq4 |
//|                                                 Copyright © 2009 |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
//
int TimeCycle  = 60;   //=== допустимое время обработки цикла в сек.
int TimeCycle2 = 5;    //=== время обработки цикла в сек, превышение которого должно сообщаться.
int countSymbol;       //=== количество торгуемых инструментов (массив Symbol_array[])
//
string Symbol_array[] = {"EURUSD","GBPUSD","AUDUSD","USDJPY","USDCHF","USDCAD","EURJPY","EURGBP","EURCHF"};
datetime ТicTime[9];   //=== время поступления последней котировки для регистрации тиков 
//
int init()   { return(0); }
int deinit() { return(0); }
//
//===== зацикленная функция start() ======================================================================================
int start()             {  
   startustanovki();         // начальные установки
   while(!IsStopped())  {    // До тех пор, пока пользователь не прекратит исполнение программы 
   
      int TC1   = TimeCurrent();   //=== время начала обработки цикла
      RefreshRates();              //=== Обновление данных   
      kontrol();                   //=== контрольные функции               
      //ProcSP();                  //=== процедуры, которые необходимо выполнять оперативно (в цикле обработки), не дожидаясь появления нового бара              
      SymbolТic();                 //=== регистрация появления нового тика на любом инструменте
      
      //====================== ежечасный профилактический перезапуск цикла ========  
      string text   = TimeToStr(TimeCurrent(),TIME_MINUTES);            
      int    index = StringFind(text, ":49", 0);   // разрешение на очередной ежечастный однократный перезапуск эксперта (цикла)
      if     (index==2) {bool perezapusk=true;}       
      index = StringFind(text, ":50", 0);          // профилактический перезапуск цикла делаю за 10 минут до начала нового часа 
      if     ((index==2)&&(perezapusk==true)){
         Print("======================================================");
         Print(" Профилактический, перезапуск цикла обработки ",TimeToStr(TimeCurrent(),TIME_MINUTES));
         Print("======================================================");   perezapusk=false;  break;
      }   
      //====================== ежечасный профилактический перезапуск цикла ========  
      
      Sleep(10);                  // притормози! (замедлитель цикла обработки)  
      
      int TC2 = TimeCurrent();     //=== время окончания обработки цикла               
      int analiz = TC2-TC1;  
      if (analiz>TimeCycle)   {
         Print("=================================================================");
         Print("Превышение допустимого (",TimeCycle,"сек) времени обработки !!!  ",analiz,"сек       Перезапуск цикла обработки.");
         Print("=================================================================");
         break;
      }   
   }      
   return(0);                      // Управление возвращается терминалу
}
//===== зацикленная функция start() ======================================================================================
//
//===== начальные установки ==============================================================================================   
void startustanovki()   {
   countSymbol  = ArraySize(Symbol_array);
   for(int i=0; i<countSymbol; i++)  {      //=== перебор инструментов
      ТicTime[i] = 0;
   }          
}
//===== начальные установки ==============================================================================================   
//
//===== периодический контроль ===========================================================================================   
void kontrol()     {
   if(!IsConnected())       { Print("----- Связь отсутствует!------------------------------------------------------------------"); return(0); }
   if(!IsExpertEnabled())   { Print("----- В клиентском терминале запуск экспертов запрещен! ----------------------------------"); return(0); }
   if(!IsTradeAllowed())    { Print("----- Поток для выполнения торговых операций занят! Эксперту не разрешено торговать! -----"); return(0); }
   if(IsTradeContextBusy()) { Print("----- Торговый поток занят. Подождите ----------------------------------------------------"); return(0); }
}
//===== периодический контроль ===========================================================================================   
//
//===== регистрация появления нового тика на любом инструменте ===========================================================
void SymbolТic()  {
   bool TT      = false;                //=== флаг необходимости замера времени последующей обработки
   bool NewТicS = false;                //=== флаг появления тика
   int  TC1     = TimeCurrent();        //=== время начала обработки 
   
   for(int i=0; i<countSymbol; i++)  {  //=== перебор инструментов
      if (isNewТic(i))  {               //=== появился новый тик по текущему инструменту
         TT      = true;                 
         NewТicS = true;
         ТicSymbol(i);                  //=== процедура, которую целесообразно запускать при появлении каждого тика
      }                                 //=== на любом из инструментов
   } 
   if (NewТicS==true)  { 
      ТicSymbolS();                     //=== процедура, которую целесообразно запускать после окончания сканирования всех инструментов
   }                                    //=== при условии, что за время сканирования появился хотя-бы один тик 
    
   int TC2 = TimeCurrent();                     
   int analiz = TC2-TC1;                //=== замер времени обработки
   if ((TT==true)&&(analiz>TimeCycle2)) {   
      Print("            Время обработки  ",analiz,"сек.");
   }
}      
//===== регистрация появления нового тика/бара по любому инструменту и на любом таймфрейме ===============================
//
//===== возвращает true если появлися новый тик, иначе false =============================================================  
bool isNewТic(int i)  {           //=== i-индекс инструмента
   bool res=false;  
   RefreshRates();
   datetime TT = MarketInfo(Symbol_array[i],MODE_TIME); 
   if ( ТicTime[i] != TT )   { ТicTime[i] = TT ;  res=true; } 
   return(res);
}
//===== возвращает true если появлися новый бар, иначе false =============================================================  
//
void ТicSymbol(int i)      {  
   Print("     ",Symbol_array[i],"     ТicTime=",ТicTime[i]);            
}
//

void ТicSymbolS()      {              
}
 
Vinin писал(а) >>

Незнаю на счет авторитетности. для контроля новых тиков можно использовать MarketInfo(Symbol().MODE_TIME);

MODE_TIME 5 Время поступления последней котировки

Хотя такой контроль никогда не делал.

Как я понимаю - эксперт зацикленый, то RefreshRates() можно делать самой первой в теле цикла.

Все же зависит от потребностей. Для анализа достаточно. Но о тиковой истории лучше не думать.

И контроль открытия нового бара - не уверен что он будет работать корректно. Хотя как это проверить. Вешать на разные инструменты и сравнивать время откртия бара. Может быть. Но подобный советник будет довольно хорошо кушать ресурсы. Надо бы ограничения по количеству инструментов сделать.

Vinin, спасибо еще за одну идею. Я ее использовал в функции isNewТic(i)

 

Исправил мелкие огрехи. Тики ловит на всех инструментах.

//+------------------------------------------------------------------+
//|                                               MultiSymbolТic.mq4 |
//|                                                 Copyright © 2009 |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
//
int TimeCycle  = 60;   //=== допустимое время обработки цикла в сек.
int TimeCycle2 = 5;    //=== время обработки цикла в сек, превышение которого должно сообщаться.
int countSymbol;       //=== количество торгуемых инструментов (массив Symbol_array[])
//
string Symbol_array[] = {"EURUSD","GBPUSD","AUDUSD","USDJPY","USDCHF","USDCAD","EURJPY","EURGBP","EURCHF"};
datetime ТicTime[9];   //=== время поступления последней котировки для регистрации тиков 
//
int init()   { return(0); }
int deinit() { return(0); }
//
//===== зацикленная функция start() ======================================================================================
int start()             {  
   startustanovki();         // начальные установки
   while(!IsStopped())  {    // До тех пор, пока пользователь не прекратит исполнение программы 
   
      if (kontrol()==0)   break;   //=== контрольные функции     
      int TC1   = TimeCurrent();   //=== время начала обработки цикла
      RefreshRates();              //=== Обновление данных                   
      SymbolТic();                 //=== регистрация появления нового тика на любом инструменте
      
      //====================== ежечасный профилактический перезапуск цикла ========  
      string text   = TimeToStr(TimeCurrent(),TIME_MINUTES);            
      int    index = StringFind(text, ":49", 0);   // разрешение на очередной ежечастный однократный перезапуск эксперта (цикла)
      if     (index==2) {bool perezapusk=true;}       
      index = StringFind(text, ":50", 0);          // профилактический перезапуск цикла делаю за 10 минут до начала нового часа 
      if     ((index==2)&&(perezapusk==true)){
         Print("======================================================");
         Print(" Профилактический, перезапуск цикла обработки ",TimeToStr(TimeCurrent(),TIME_MINUTES));
         Print("======================================================");   perezapusk=false;  break;
      }   
      //====================== ежечасный профилактический перезапуск цикла ========  
      
      Sleep(1000);                  // притормози! (замедлитель цикла обработки)  
      
      int TC2 = TimeCurrent();     //=== время окончания обработки цикла               
      int analiz = TC2-TC1;  
      if (analiz>TimeCycle)   {
         Print("=================================================================");
         Print("Превышение допустимого (",TimeCycle,"сек) времени обработки !!!  ",analiz,"сек       Перезапуск цикла обработки.");
         Print("=================================================================");
         break;
      }   
   }      
   return(0);                      // Управление возвращается терминалу
}
//===== зацикленная функция start() ======================================================================================
//
//===== начальные установки ==============================================================================================   
void startustanovki()   {
   countSymbol  = ArraySize(Symbol_array);
   for(int i=0; i<countSymbol; i++)  {      //=== перебор инструментов
      ТicTime[i] = 0;
   }          
}
//===== начальные установки ==============================================================================================   
//
//===== периодический контроль ===========================================================================================   
int kontrol()     {
   if(!IsConnected())       { Print("----- Связь отсутствует!------------------------------------------------------------------"); return(0); }
   if(!IsExpertEnabled())   { Print("----- В клиентском терминале запуск экспертов запрещен! ----------------------------------"); return(0); }
   if(!IsTradeAllowed())    { Print("----- Поток для выполнения торговых операций занят! Эксперту не разрешено торговать! -----"); return(0); }
   if(IsTradeContextBusy()) { Print("----- Торговый поток занят. Подождите ----------------------------------------------------"); return(0); }
   return(1);
}
//===== периодический контроль ===========================================================================================   
//
//===== регистрация появления нового тика на любом инструменте ===========================================================
void SymbolТic()  {
   bool TT      = false;                //=== флаг необходимости замера времени последующей обработки
   bool NewТicS = false;                //=== флаг появления тика
   int  TC1     = TimeCurrent();        //=== время начала обработки 
   
   for(int i=0; i<countSymbol; i++)  {  //=== перебор инструментов
      if (isNewТic(i))  {               //=== появился новый тик по текущему инструменту
         TT      = true;                 
         NewТicS = true;
         ТicSymbol(i);                  //=== процедура, которую целесообразно запускать при появлении каждого тика
      }                                 //=== на любом из инструментов
   } 
   if (NewТicS==true)  { 
      ТicSymbolS();                     //=== процедура, которую целесообразно запускать после окончания сканирования всех инструментов
   }                                    //=== при условии, что за время сканирования появился хотя-бы один тик 
    
   int TC2 = TimeCurrent();                     
   int analiz = TC2-TC1;                //=== замер времени обработки
   if ((TT==true)&&(analiz>TimeCycle2)) {   
      Print("            Время обработки  ",analiz,"сек.");
   }
}      
//===== регистрация появления нового тика на любом инструменте ===========================================================
//
//===== возвращает true если появлися новый тик, иначе false =============================================================  
bool isNewТic(int i)  {           //=== i-индекс инструмента
   bool res=false;  
   RefreshRates();
   datetime TT = MarketInfo(Symbol_array[i],MODE_TIME); 
   if ( ТicTime[i] != TT )   { ТicTime[i] = TT ;  res=true; } 
   return(res);
}
//===== возвращает true если появлися новый бар, иначе false =============================================================  
//
void ТicSymbol(int i)      {  
   double ask   =MarketInfo(Symbol_array[i],MODE_ASK);
   Print("     ",Symbol_array[i],"     ТicTime=",ТicTime[i],"     ask=",ask);            
}
//

void ТicSymbolS()      {              
}
 
mikola2 писал(а) >>

А как наиболее изящно отлавливать момент наличия нового бара на всех валютных парах на одном из таймфреймов?

момент наличия? что это? т.е когда новый бар появится на всех вал.парах, с учетом того, что котировки поступают не одновременно по этим парам?

вы имеете в виду, что надо еще и синхронизировать с текущим временем. Т.е. если, например на М1 появились новые бары по всем парам кроме одной, а по этой последней бар появился на 55-й секунде, то этот момент и считать моментом наличия нового бара на всех валютных парах?

а если на какой-то паре бар не появится? такое тоже быает?

уточните вопрос

 
спасибо.
 
alexfx писал(а) >>

момент наличия? что это? т.е когда новый бар появится на всех вал.парах, с учетом того, что котировки поступают не одновременно по этим парам?

вы имеете в виду, что надо еще и синхронизировать с текущим временем. Т.е. если, например на М1 появились новые бары по всем парам кроме одной, а по этой последней бар появился на 55-й секунде, то этот момент и считать моментом наличия нового бара на всех валютных парах?

а если на какой-то паре бар не появится? такое тоже быает?

Да, именно так. 55-я секунда будет моментом наличия нового бара на всех валютных парах.

Если на какой-то паре бар так и не появился - бар исключается из обработки или обрабатывается по особому алгоритму.

На минутках такое, наверно, бывает (непоявление бара). На старших таймфреймах - врядли.

Это нужно для того, чтобы значения мультивалютных индюков в реалтайме совпадали со значениями, полученными при прогоне по истории.

И потеря одной-двух минут ожидания в пользу получения достоверных данных, мне кажется, себя оправдает. На М15, М30, М60 и т.д.

 
mikola2 писал(а) >>

Да, именно так. 55-я секунда будет моментом наличия нового бара на всех валютных парах.

Если на какой-то паре бар так и не появился - бар исключается из обработки или обрабатывается по особому алгоритму.

На минутках такое, наверно, бывает (непоявление бара). На старших таймфреймах - врядли.

Это нужно для того, чтобы значения мультивалютных индюков в реалтайме совпадали со значениями, полученными при прогоне по истории.

И потеря одной-двух минут ожидания в пользу получения достоверных данных, мне кажется, себя оправдает. На М15, М30, М60 и т.д.

Так в чем проблема? Все, что подчиняется логике - программируемо :)

Правда, вы ищете "наиболее изящный" вариант. Мне пока не известны никакие. Не было в этом надобности. Поэтому наиболее изящный предложить не могу :)

 
alexfx писал(а) >>

Так в чем проблема? Все, что подчиняется логике - программируемо :)

Правда, вы ищете "наиболее изящный" вариант. Мне пока не известны никакие. Не было в этом надобности. Поэтому наиболее изящный предложить не могу :)

Да, я кое-как уже сам накропал. Спасибо большое за идеи и отличный остов!

Причина обращения: