Скачать MetaTrader 5

Обрыв связи в момент постановки ордера

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Пиши статьи и зарабатывай. Мы платим за них 200 USD!
Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.06 02:28 

Добрый день!

Как "искать" результаты команды OrderSend, если request был отправлен на торговый сервер,

а ответа (result) не пришло - ОБРЫВ СВЯЗИ(например на 10 минут)?  

Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.08 18:56  

Добрый день!

Никто не знает? 

o_o
Модератор
23688
o_o 2013.05.08 19:15  
Mikalas:

Добрый день!

Как "искать" результаты команды OrderSend, если request был отправлен на торговый сервер,

а ответа (result) не пришло - ОБРЫВ СВЯЗИ(например на 10 минут)?  

чтоб что то искать - надо сначала знать что искать.

в вашем "обрывочном" мире поможет сохранение всей истории ордеров + текущих позиций в файл, после чего отправка команды OrderSend, и после обрыва - сличать запомненную историю + позы из файла с текущими имеющимися в терминале.

Если обнаружите расхождение считайте - вы нашли то что искали.

Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.08 21:49  

Добрый вечер, sergeev!

Спасибо. Только почему в файл, а не в память? 

А как узнать, что произошел обрыв не используя TerminalInfoInteger( TERMINAL_CONNECTED ),

которая, в случае разрыва связи "тормозит" почти на минуту?

Может быть разработчики планируют ввести что-то типа ConnectionLost()?

 

А пока (если это кого-то заинтересует), можно воспользоваться следующим:

Есть функция, которая работает моментально, но везде есть свои недостатки.

Необходимо вводить адрес реального сайта н-р у меня 'http://www.google.ru' 

BOOL InternetCheckConnection(
  _In_  LPCTSTR lpszUrl,
  _In_  DWORD dwFlags,
  _In_  DWORD dwReserved
);

http://msdn.microsoft.com/en-us/library/windows/desktop/aa384346(v=vs.85).aspx   

Эту функцию помещаем в DLL. Код для 64-битного терминала:

library MQL5_64;


uses
  Winapi.Windows, Wininet;

const
  FLAG_ICC_FORCE_CONNECTION = $00000001;
  Host = 'http://www.google.ru';

{$R *.res}

function CheckConnection(): Boolean; stdcall;
begin
  Result:= InternetCheckConnection( PWideChar( Host ), FLAG_ICC_FORCE_CONNECTION, 0 );
end;

exports
  CheckConnection;

begin

end.

 Код для 32-битного терминала:

library MQL5_32;


uses
  Windows,
  Wininet;

const
  FLAG_ICC_FORCE_CONNECTION = $00000001;
  Host = 'http://www.google.ru';

{$R *.res}

function CheckConnection(): Boolean; stdcall;
begin
  Result:= InternetCheckConnection( PChar( Host ), FLAG_ICC_FORCE_CONNECTION, 0 );
end;


exports
  CheckConnection;


begin

end.

 

Извините за Паскаль, но 64-битный компилятор у меня только на Delphi.

(Если лень делать компиляцию в ZIP лежат обе DLL)

 Далее в советнике помещаем код вызова этой функции и код обработки результатов

(код для 64-битного терминала, отличается от 32-битного только именем DLL) 

#import "MQL5_64.dll"
  bool CheckConnection();
#import
//
enum ENUM_CONNECTION_STATE
{
  CONNECTION_EXIST   = 0,
  CONNECTION_LOST    = 1,
  CONNECTION_RESTORE = 2, 
};
input int             TimerTime      = 200;            //Timer set time (in msec)
input uint            Wait           = 2;              //Time for wait after conn. restore (in min) 

bool                  isBusy;
uint                    time_wait;
uint                    time_real;
ENUM_CONNECTION_STATE isConnected;  
//

//+------------------------------------------------------------------+
//| Expert Check terminal                                            |
//+------------------------------------------------------------------+
bool CheckTerminal()
{
  if ( !TerminalInfoInteger( TERMINAL_CONNECTED ) )
  {
    MessageBox( "Check internet connection!", "Error ", MB_OK );
    return( false );
  }
  return( true );
}
  
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  isBusy      = false;
  time_wait   = 1000 * Wait * 60;
  
//--- Check terminal
  if ( !CheckTerminal() )
  {
    return( -1 );
  }
  
  isConnected = CONNECTION_EXIST;
   
//--- Set timer
  if ( !EventSetMillisecondTimer( TimerTime ) )
  {
    MessageBox( "Timer NOT set!", "Error ", MB_OK );
      
    return( -2 );
  }      
    
  return( 0 );
}
  
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
  EventKillTimer();
  
}
  
//+------------------------------------------------------------------+
//| Expert Tick function                                             |
//+------------------------------------------------------------------+  
void OnTick() 
{
  if ( !isBusy )
  {
  }
}
//+------------------------------------------------------------------+
//| Expert timer function                                            |
//+------------------------------------------------------------------+
void OnTimer()
{
  if ( isConnected == CONNECTION_EXIST )
  {
    if ( !CheckConnection() )
    {
      isConnected = CONNECTION_LOST;
      isBusy = true;
    }
  }
  
  if ( isConnected == CONNECTION_LOST )
  {
    if ( CheckConnection() )
    {
      isConnected = CONNECTION_RESTORE;
      time_real = 0;
    }
  }
  
  if ( isConnected == CONNECTION_RESTORE )
  {
    if ( time_real < time_wait )
    {
      time_real = time_real + TimerTime;
    }
    else
    {
      if ( TerminalInfoInteger( TERMINAL_CONNECTED ) )
      {
        isConnected = CONNECTION_EXIST;
        isBusy = false;
      }
      else
      {
        isConnected = CONNECTION_LOST;
      }
    }
  }
} 
Google
Google
  • www.google.ru
Поиск информации в интернете: веб страницы, картинки, видео и многое другое.
Файлы:
ch_conn.zip 32 kb
o_o
Модератор
23688
o_o 2013.05.09 08:33  
Mikalas:

Добрый вечер, sergeev!

Спасибо. Только почему в файл, а не в память?

принципиально? это суть, конкретику выбирайте вы сами. тем более, что с такими предосторожностями вторым вопросом могло идти - вдруг терминал зависнет или винда слетит. :))

А как узнать, что произошел обрыв не используя TerminalInfoInteger( TERMINAL_CONNECTED ),

которая, в случае разрыва связи "тормозит" почти на минуту?

а если произошел обрыв, то вы сможете еще что то делать с терминалом?
терминал без интернета/связи с брокером - кучка бесполезных окон. какая разница чем определять отсутствие связи.


Может быть разработчики планируют ввести что-то типа ConnectionLost()?

ну... возможно и интересное предложение. ввести функцию события OnConnection(EnConnectonState state).

но есть её альтернатива TERMINAL_CONNECTED, которой вы и так дергать сможете.


Есть функция, которая работает моментально, но везде есть свои недостатки.

Далее в советнике помещаем код вызова этой функции и код обработки результатов

этой функцией вы определяете наличие интернета, а не связь терминала с брокером.
но как еще одну ступень контроля использовать возможно... чтоб убедиться что проблема с брокером, а не интернетом.
Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.09 20:59  

Уважаемый sergeev!

Я понимаю "лёгкую иронию" с Вашей стороны (9292 сообщений, конечно устали), но

позволю себе Вам напомнить, что Ваши пользователи вкладывают СВОИ деньги играя на Бирже,

используя ВАШ терминал, И КОНЕЧНО им (пользователям) ОЧЕНЬ ХОЧЕТСЯ, что бы Ваш продукт был

ИДЕАЛЬНЫМ! Я прекрасно понимаю какой труд Вы и Ваш коллектив вложил в эту работу, и что на

сегодняшний день, Ваш продукт, по моему мнению, лучший на Российском рынке!

Ну, а теперь по делу:

> принципиально? это суть, конкретику выбирайте вы сами. тем более, что с такими предосторожностями вторым вопросом могло идти - вдруг терминал зависнет или винда слетит. :))

Принципиально! Обращение к памяти гораздо быстрее, чем к диску.

> а если произошел обрыв, то вы сможете еще что то делать с терминалом?
терминал без интернета/связи с брокером - кучка бесполезных окон. какая разница чем определять отсутствие связи. 

Могу! И многое могу(ведь терминал не перестал работать)!

В моём советнике я обращаюсь к разным инструментам, а в момент обрыва связи ТЕРМИНАЛ НЕ ОБНУЛЯЕТ стаканы цен и котировки, а

при восстановлении связи они обновляются НЕ МГНОВЕННО!

> но есть её альтернатива TERMINAL_CONNECTED, которой вы и так дергать сможете. 

Конечно "дёргаю"(посмотрите код выше), но в момент обрыва, возвращение функции TERMINAL_CONNECTED идёт с очень большой задержкой, что, например, в моём

советнике - недопустимо. 

o_o
Модератор
23688
o_o 2013.05.09 22:06  

я нисколько не говорю вам про иррациональность вашего вопроса. наоборот, мне важно и интересно сделать правильный вывод.

поэтому патетику пропускаем.

по делу:


Mikalas:

В моём советнике я обращаюсь к разным инструментам, а в момент обрыва связи ТЕРМИНАЛ НЕ ОБНУЛЯЕТ стаканы цен и котировки, а при восстановлении связи они обновляются НЕ МГНОВЕННО!


то есть вы допускаете что устаревшие данные (например связи не было пару часов) помогут вам правильно подготовить ордер на покупку или закрывшаяся поза по стоплосу (факт вы этот не знаете по прчине отсутствия связи) позволит вам правильно оценить риски?

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

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


> но есть её альтернатива TERMINAL_CONNECTED, которой вы и так дергать сможете. 

Конечно "дёргаю"(посмотрите код выше), но в момент обрыва, возвращение функции TERMINAL_CONNECTED идёт с очень большой задержкой, что, например, в моём

советнике - недопустимо. 

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

задржка данной функции вероятно идет по причине синхронного сокета.

Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.09 22:39  

Добрый вечер!

>то есть вы допускаете что устаревшие данные (например связи не было пару часов) помогут вам правильно подготовить ордер на покупку или закрывшаяся поза по стоплосу (факт вы этот не знаете по прчине отсутствия связи) позволит вам правильно оценить риски?

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

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

 

Я не допускаю, а тестирую советника на реальном счёте брокера "Открытие"(демо-счёт не предоставляет котировки по дальним фьючерсам ). И у меня произошел обрыв связи(~ 20 сек. )....

Мой советник "подхватил" одну старую(не обновлённую) котировку, а одну новую(уже обновлённую) и выдал приказ на установку ордеров, тогда

как на самом деле одна из котировок (на торговом сервере) уже была другая(обновлённая)! 

Поэтому мне нужен механизм, который даст мне "относительную" уверенность, что связь есть -> котировки "свежие". 

Кстати, ребята из TSLab это реализовали зачем-то (Интерфейс TSLab.DataSource.IConnectable )

http://www.tslab.ru/docs/1.2/api/ 

Было бы просто ИДЕАЛЬНО, если бы структура

struct MqlBookInfo
  {
   ENUM_BOOK_TYPE   type;       // тип заявки из перечисления ENUM_BOOK_TYPE
   double           price;      // цена
   long             volume;     // объем
  };

Имела бы поле datetime time, как структура MqlTick 

Да и по большому счёту не важно, что был разрыв связи, ВАЖНО то, что происходит

после восстановления соединения. Обрыв связи - это сигнал для того, что нужно

сделать задержку, что бы быть уверенным, что терминал обновил (синхронизировал ) ВСЕ котировки

с торговым сервером. Так что "дёргать" TERMINAL_CONNECTED не имеет никакого смысла,

если произошло событие OnTick() или OnBookEvent(), потому что они совершаются при наличии связи.

Anatoli Kazharski
56795
Anatoli Kazharski 2013.05.09 23:59  
Mikalas:

...

Обрыв связи - это сигнал для того, что нужно

сделать задержку, что бы быть уверенным, что терминал обновил (синхронизировал ) ВСЕ котировки

с торговым сервером.

... 

Эта функция не подходит ? >> SymbolIsSynchronized
Mikhail Filimonov
5931
Mikhail Filimonov 2013.05.10 00:16  

Добрый вечер, tol64!

Из справочника MQL5:

Синхронизация данных терминала и данных сервера

Поскольку mql5-программа может обратиться к данным по любому символу и таймфрейму,

то есть вероятность, что данные требуемой таймсерии еще не сформированы в терминале или

требуемые ценовые данные не синхронизированы с торговым сервером.

В этом случае время ожидания готовности данных сложно прогнозировать.

Алгоритмы с использованием циклов ожидания готовности данных являются не лучшим решением. 

 

Смотрите. Мне нужно обработать 20 символов.

Первый символ сихронизирован, проверяя 19 (ожидая) остальных, в первом символе котировки уже ИЗМЕНИЛИСЬ. 

Anatoli Kazharski
56795
Anatoli Kazharski 2013.05.10 00:42  
Mikalas:

...

Смотрите. Мне нужно обработать 20 символов.

Первый символ сихронизирован, проверяя 19 (ожидая) остальных, в первом символе котировки уже ИЗМЕНИЛИСЬ. 

То есть, на первом символе нельзя совершить торговую операцию пока не проанализированы все символы?

Если нет, то можно сначала совершить торговые операции только по тем символам, которые уже синхронизированы, а на остальных по мере того, как они синхронизируются. Циклы ожидания можно не использовать. Проверка или каждый тик или временной интервал (теперь уже вплоть до миллисекунд).

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Типы торговых операций - Документация по MQL5
123
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий