CustomXXXX функции

Vladimir Karputov  

Если программно создавать пользовательский символ, каким образом визуально обновлять график?

Вот советник:

//+------------------------------------------------------------------+
//|                                                  Test Custom.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input string      CustomSymbolName="EURUSD.renko";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ResetLastError();
   if(!CustomSymbolCreate(CustomSymbolName))
     {
      if(_LastError!=5304)
        {
         Alert(__FUNCTION__," ERROR CustomSymbolCreate(",CustomSymbolName,") : ",GetLastError());
         return(INIT_FAILED);
        }
     }
   int custom_rates_delete=CustomRatesDelete(CustomSymbolName,0,TimeCurrent()+60*60*24);
   if(custom_rates_delete==-1)
     {
      Alert(__FUNCTION__," ERROR CustomRatesDelete(",CustomSymbolName,") : ",GetLastError());
      return(INIT_FAILED);
     }
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   ArrayResize(rates,6);
   datetime time_current=TimeCurrent();
   for(int i=0;i<6;i++)
     {
      rates[i].time        = time_current-60*i; // время начала периода 
      rates[i].open        = 1.65458-0.00100*i; // цена открытия 
      rates[i].high        = 1.65499-0.00100*i; // наивысшая цена за период 
      rates[i].low         = 1.65401-0.00100*i; // наименьшая цена за период 
      rates[i].close       = 1.65478-0.00100*i; // цена закрытия 
/*rates[i].tick_volume;  // тиковый объем 
      rates[i].spread;       // спред 
      rates[i].real_volume;  // биржевой объем */
     }
   int custom_rates_replace=CustomRatesReplace(CustomSymbolName,0,time_current+60*60*24,rates);
   if(custom_rates_replace==-1)
     {
      Alert(__FUNCTION__," ERROR CustomRatesReplace(",CustomSymbolName,") : ",GetLastError());
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   ArrayResize(rates,9);
   datetime time_current=TimeCurrent();
   double start_price=NormalizeDouble(MathRand()/32767.0+1.0,5);
   for(int i=0;i<9;i++)
     {
      rates[i].time        = time_current-60*i; // время начала периода 
      rates[i].open        = start_price-0.00100*i; // цена открытия 
      rates[i].high        = start_price+0.00040-0.00100*i; // наивысшая цена за период 
      rates[i].low         = start_price-0.00040-0.00100*i; // наименьшая цена за период 
      rates[i].close       = start_price+0.00020-0.00100*i; // цена закрытия 
/*rates[i].tick_volume;  // тиковый объем 
      rates[i].spread;       // спред 
      rates[i].real_volume;  // биржевой объем */
     }
   int custom_rates_replace=CustomRatesReplace(CustomSymbolName,0,time_current+60*60*24,rates);
   if(custom_rates_replace==-1)
     {
      Alert(__FUNCTION__," ERROR CustomRatesReplace(",CustomSymbolName,") : ",GetLastError());
      return;
     }
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---

  }
//+------------------------------------------------------------------+


Пользовательский символ создаётся и перезаписывается. Но график этого пользовательского символа не обновляется.

Файлы:
Rashid Umarov  

А CustomTicksAdd не помогает?

Примечание

Функция CustomTicksAdd работает только для пользовательских символов, открытых в окне MarketWatch (Обзор рынка). Если символ не выбран в MarketWatch, то для вставки тиков необходимо использовать CustomTicksReplace.

Функция CustomTicksAdd позволяет транслировать тики так, как если бы они приходили от сервера брокера. Данные записываются не напрямую в базу тиков, а отправляются в окно "Обзор рынка". И уже из него терминал сохраняет тики в своей базе. При большом объеме данных, передаваемых за один вызов, функция меняет свое поведение для экономии ресурсов. Если передается более 256 тиков, данные делятся на две части. Первая часть (большая) сразу напрямую записывается в базу тиков (как это делает CustomTicksReplace). Вторая часть, состоящая из последних 128 тиков, передается в окно "Обзор рынка" и после этого сохраняется терминалом в базе.

Vladimir Karputov  
Rashid Umarov:

А CustomTicksAdd не помогает?

Пока такой вариант не подходит - не до тиков ещё. Разобраться бы просто с барами.

Rashid Umarov  
Vladimir Karputov:

Пока такой вариант не подходит - не до тиков ещё. Разобраться бы просто с барами.

Текущий бар обновляется с приходом тиков. Все равно будем искать решение в другом месте?

Функция CustomTicksAdd позволяет транслировать тики так, как если бы они приходили от сервера брокера. Данные записываются не напрямую в базу тиков, а отправляются в окно "Обзор рынка".

Vladimir Karputov  

При старте создаю шесть баров.

В OnTick() пытаюсь добавить по одному тику:

//+------------------------------------------------------------------+
//|                                                  Test Custom.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input string      CustomSymbolName="EURUSD.renko";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ResetLastError();
   if(!CustomSymbolCreate(CustomSymbolName))
     {
      if(_LastError!=5304)
        {
         Alert(__FUNCTION__," ERROR CustomSymbolCreate(",CustomSymbolName,") : ",GetLastError());
         return(INIT_FAILED);
        }
     }
   int custom_rates_delete=CustomRatesDelete(CustomSymbolName,0,TimeCurrent()+60*60*24);
   if(custom_rates_delete==-1)
     {
      Alert(__FUNCTION__," ERROR CustomRatesDelete(",CustomSymbolName,") : ",GetLastError());
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   MqlTick tick[1];
   double start_price=NormalizeDouble(MathRand()/32767.0+1.0,5);
   tick[0].time=0;      // Время последнего обновления цен 
   tick[0].bid=start_price;         // Текущая цена Bid 
   tick[0].ask=start_price+0.00010; // Текущая цена Ask 
   tick[0].last=0;                  // Текущая цена последней сделки (Last) 
   tick[0].volume=0;                // Объем для текущей цены Last 
   tick[0].time_msc=0;              // Время последнего обновления цен в миллисекундах 
   tick[0].flags=0;                 // Флаги тиков

   int custom_ticks_add=CustomTicksAdd(CustomSymbolName,tick);
   if(custom_ticks_add==-1)
     {
      Print(__FUNCTION__," ERROR CustomTicksAdd(",CustomSymbolName,") : ",GetLastError());
      return;
     }
  }
//+------------------------------------------------------------------+

При попытке добавить тики получаю

OnTick ERROR CustomTicksAdd(EURUSD.renko) : 5310

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Не упорядоченный по времени массив тиков

Файлы:
Rashid Umarov  
Vladimir Karputov:

При старте создаю шесть баров.

В OnTick() пытаюсь добавить по одному тику:

При попытке добавить тики получаю

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Не упорядоченный по времени массив тиков

И Символ с именем "EURUSD.renko" выбран в обзоре рынка?

Vladimir Karputov  
Rashid Umarov:

И Символ с именем "EURUSD.renko" выбран в обзоре рынка?

Да. Выбран:


Rashid Umarov  
Тогда в Сервисдеск
Vladimir Karputov  
Rashid Umarov:
Тогда в Сервисдеск

ПОнял.

Vladimir Karputov  

Да! Я таки заставил работать!

version   "1.001" - оказывается НУЖНО заполнять в массиве тиков ОБА поля: time и time_msc

Хотя в справке написано, что можно заполнять ИЛИ ИЛИ.

//+------------------------------------------------------------------+
//|                                                  Test Custom.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.001"
//--- input parameters
input string      CustomSymbolName="EURUSD.renko";
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ResetLastError();
   if(!CustomSymbolCreate(CustomSymbolName))
     {
      if(_LastError!=5304)
        {
         Alert(__FUNCTION__," ERROR CustomSymbolCreate(",CustomSymbolName,") : ",GetLastError());
         return(INIT_FAILED);
        }
     }
   int custom_rates_delete=CustomRatesDelete(CustomSymbolName,0,TimeCurrent()+60*60*24);
   if(custom_rates_delete==-1)
     {
      Alert(__FUNCTION__," ERROR CustomRatesDelete(",CustomSymbolName,") : ",GetLastError());
      return(INIT_FAILED);
     }
//---
   MqlRates rates[];
   ArraySetAsSeries(rates,true);
   ArrayResize(rates,6);
   datetime time_current=TimeCurrent();
   for(int i=0;i<6;i++)
     {
      rates[i].time        = time_current-60*i; // время начала периода 
      rates[i].open        = 1.65458-0.00100*i; // цена открытия 
      rates[i].high        = 1.65499-0.00100*i; // наивысшая цена за период 
      rates[i].low         = 1.65401-0.00100*i; // наименьшая цена за период 
      rates[i].close       = 1.65478-0.00100*i; // цена закрытия 
      rates[i].tick_volume = 1;                 // тиковый объем 
      rates[i].spread      = 9;                 // спред 
      rates[i].real_volume = 0;                 // биржевой объем 
     }
   int custom_rates_replace=CustomRatesReplace(CustomSymbolName,0,time_current+60*60*24,rates);
   if(custom_rates_replace==-1)
     {
      Print(__FUNCTION__," ERROR CustomRatesReplace(",CustomSymbolName,") : ",GetLastError());
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   MqlTick tick[1];
   double start_price=NormalizeDouble(MathRand()/32767.0+1.0,5);
   tick[0].time=TimeCurrent();         // Время последнего обновления цен 
   tick[0].bid=start_price;            // Текущая цена Bid 
   tick[0].ask=start_price+0.00010;    // Текущая цена Ask 
   tick[0].last=0;                     // Текущая цена последней сделки (Last) 
   tick[0].volume=0;                   // Объем для текущей цены Last 
   tick[0].time_msc=tick[0].time*1000; // Время последнего обновления цен в миллисекундах 
   tick[0].flags=0;                    // Флаги тиков
/*
int  CustomTicksAdd( 
   const string           symbol,       // имя символа 
   const MqlTick&         ticks[]       // массив с тиковыми данными, которые необходимо применить к пользовательскому инструменту 
   );
Параметры
   symbol
      [in]  Имя пользовательского инструмента.

   ticks[]
      [in]   Массив тиковых данных типа MqlTick, упорядоченных по времени в порядке возрастания, 
      то есть требуется чтобы ticks[k].time_msc <= ticks[n].time_msc, если k<n.
*/
   int custom_ticks_add=CustomTicksAdd(CustomSymbolName,tick);
   if(custom_ticks_add==-1)
      Print(__FUNCTION__," ERROR CustomTicksAdd(",CustomSymbolName,") : ",GetLastError());
  }
//+------------------------------------------------------------------+
Файлы:
Maxim Dmitrievsky  

Владимир, не могли бы вы подумать каклучше подгружать кастомный символ из другого терминала онлайн? т.е. сначала можно создать каст. символ и просто экспортировать архив тиковый вручную, а затем в реалтайме дообновлять символ новыми котировками из другого терминала (должен быть открыт). Такого еще нет в кодбазе

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