2016-01-13 5 views
0

Я хотел бы уточнить поведение QuickFIX/J (FIX 4.2) в следующем сценарии. Есть две стороны, участвующие в этой связи: QuickFIX/JПоведение очереди сообщений в QuickFIX/J для отключенных клиентов

  1. клиент инициатор, называемый I.
  2. Наша акцепторная программа нашей фирмы, которая называется A.

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

Обратите внимание, что вся эта отмена-на-разъединитель процедура инициируется и обрабатывается Одна лишь - он получает инициировано onLogout(...) способа А «ы и обрабатывается его нормальными механизмами управления заказами. Одно сообщение 35=F генерируется для каждого открытого ордера I, а ExecutionReport (35=8) генерируется при каждом успешном отмене.

Когда я возвращается живым, эти ExecutionReport s должны быть доставлены в я как-то так, что становится известно все свои предыдущие заказы были отменены. У меня сложилось впечатление, что реализация очереди сообщений QuickFIX/J обрабатывает это без помощи на уровне приложения. Все сообщения QuickFIX предоставляются для доставки контрагентам (http://permalink.gmane.org/gmane.comp.finance.quickfix.devel/169).

Вопреки моему пониманию, однако, не ExecutionReport s были не показаны в QuickFIX бревен «s, или доставлены I когда я Reconnected, в результате я, чтобы не знать, что его предыдущие заказы есть был отменен. Я заметил, что запись не происходит из-за следующий исходный код sendRaw(Message message, int num) метода Session в QuickFIX/J:

/** 
* Send the message 
* 
* @param message is the message to send 
* @param num is the seq num of the message to send, if 0, the next expected sender seqnum is used. 
* @return 
*/ 
private boolean sendRaw(Message message, int num) { 
    ... 
     } else { 
      try { 
       application.toApp(message, sessionID); 
      } catch (final DoNotSend e) { 
       return false; 
      } catch (final Throwable t) { 
       logApplicationException("toApp()", t); 
      } 
      messageString = message.toString(); 
      if (isLoggedOn()) { // happens only if session is connected 
       result = send(messageString); // logging happens within "send" 
      } 
     } 
    ... 
} 

Сеанс не вошедшем в то время как ExecutionReport сообщений были генерируется для отменяет инициирована I-х отключите, и поэтому он никогда не попал в send(messageString);, и никаких протоколов не произошло. Я считаю, что никакое сообщение не попало в очередь (на основании того, что I не получает сообщений, когда он возвращается в живых) по той же причине.

Наша фирма сделала множество реализаций, основанных на убеждении, что QuickFIX/J гарантирует, что все сообщения будут доставлены без потерь, но мое наблюдение за сценарием выше говорит иначе.

Какова очередь сообщений QuickFIX/J в этом сценарии, когда сеанс не вошел в систему? Должен ли он отправлять сообщения в очередь независимо от того, будет ли он отправлен после того, как сеанс снова станет доступным в будущем, или остановите очередь в течение продолжительности, пока сессия не будет работать?

+0

Вы можете попробовать список рассылки QF/j для этого, если никто здесь не отвечает. –

+0

«Однако может возникнуть вопрос, когда я неожиданно разъединяюсь, после чего A решает отправить отмену всех открытых ордеров I [...]». Это звучит ужасно. Просто потому, что есть сетевая проблема, например, в течение 15 минут, вы отменяете все заказы ??? Извините, что так, но это звучит смешно. Что за этим стоит? Какое реальное деловое объяснение существует для этого требования? –

+0

@ GrantBirchmeier Спасибо за отзыв. Фактически мы подтвердили, что «35 = 8» и «150 = 4» пришли к инициатору от акцептора при повторном подключении. Я так и не смог это обнаружить. – ylee

ответ

1

Только в конце метода private boolean sendRaw(Message message, int num) есть этот код:

if (num == 0) { 
    final int msgSeqNum = header.getInt(MsgSeqNum.FIELD); 
    if (persistMessages) { 
     state.set(msgSeqNum, messageString); 
    } 
    state.incrNextSenderMsgSeqNum(); 
} 

state.set(msgSeqNum, messageString) позвонит messageStore.set(sequence, message), который фактически хранит сообщение для последующей доставки, если сеанс не подключен.

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

0

Вот мои 10 центов: Когда QF/J гарантирует доставку сообщений, что для активных сеансов, на основе порядковых номеров, а также разрыв заполняет ...

Если сеанс теряется нет никакого способа, чтобы гарантировать что-либо. Что вам нужно сделать, так это настроить ваш инициатор и акцептор на заполнение пробелов при повторном подключении, как только обнаружено несоответствие порядкового номера. Хм, что говорит ваш флаг ResetOnDisconnect в конфиге? Как насчет ResetOnLogout?

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

Если у вас есть дискотека, вы не можете использовать OnLogout для отправки отчетов о выполнении для отключенного клиента! Прежде всего OnLogout не всегда вызывается на каждой дискотеке, а во-вторых, как вы говорите, мы попадаем в внутренние элементы QF и не можем найти сеанс для отправки сообщения, чтобы оно исключалось. Я бы не ожидал, что внутренняя очередь QF справится с этой ситуацией для меня. Опять же, гарантированная доставка - это когда соединение UP ... Это зависимость. Тем не менее, I будет ожидать, что он будет где-то зарегистрирован. Какая у вас конфигурация регистрации?

Я думаю, вам нужно посмотреть, почему: «Когда/возвращается, эти ExecutionReports должны быть доставлены/как-то так, чтобы стало известно, что все предыдущие заказы были отменены». не процесс больше, что на дискотеке все заказы принимаются, чтобы быть отменены? Зачем это нужно? Это дан, нет? Это может быть что-то, что вам нужно сделать отдельно для базы QF.

+0

CancelOnDisconnect - это флаг, о котором я где-то слышал :) – rupweb

+0

«Зачем это нужно?» Мы считаем, что это было бы полезно для будущих внедрений, когда мы предоставляем нашим клиентам возможность отменить открытые заказы на разъединение (а также не отменять). Кроме того, как правило, безопасно обменивать эти подтверждения, потому что по какой-то причине отмена, возможно, не была должным образом вызвана фирмой. В любом случае, я тогда что-то упустил, и теперь знаю, что '35 = 8' с' 150 = 4' отправляется клиенту при повторном подключении. – ylee

+0

Спасибо за отзыв. – ylee

0

Прочитано this.

Некоторые компании поддерживают тег 35002 (Отмена на Disconnect) в LOGON сообщении, с возможными значениями:

  • 0: Не используйте COD
  • 1: Использование COD только тогда, когда "изящные" выхода из системы отправляется
  • 2: Использование COD на любой "сети" отключения
  • 3: 1 и 2

Fin если ваш контрагент поддерживает это. Я не проверял поддержку QuickFIX, но вы всегда можете добавить тег самостоятельно или настроить свой словарь FIX для поддержки тега.

Видимо, это часто используется высокочастотными трейдерами. Я не знаком с этой отраслью, поэтому вопрос в разделе комментариев.