Как стать автором
Обновить

Комментарии 15

Как для протокола который призван передавать данные как можно быстрее использовать FIX и FAST мне кажется не самым наилучшим вариантом.
Использование XML в качестве хранения данных для передачи занимает слишком много трафика.
Представим механизм работы протокола:

Новые данные => парсинг XML = > вещание multicast => прием данных => парсинг XML данных => обработка

Тут парсинг XML и количество передаваемых данных слабые места.
Помимо того что CPU парсит текст тегов, он еще преобразует число в текст и обратно.
По мне так это лишние затраты мощностей, и в протоколе никому не нужна читабельность текста, а скорость критически важна, даже если сэкономить микросекунды.
Почему не используют бинарные протоколы?
Если записывать числа побитово без конвертаций в текст то это сэкономит время CPU.
А если в протоколе не использовать текстовых меток вовсе то сэкономит трафик.
В итоге можно получить протокол в котором будет сохранена контрольная сумма, метки данных, тот же функционал но будет использовано меньше трафика и больше экономии CPU.
FAST как раз и хранит в XML только описание полей, сами данные передаются в «сжатом» бинарном виде. XML карта пред загружается в память заранее, и процесс отображения бинарных данных в текстовые (или любые другие виды внутреннего протокола компании) можно свести в идеале до O(N) (обращение по индексу в массиве).
Спасибо itinvest за статью, но хотелось бы увидеть больше подробностей сборки-разборки пакета FAST, так как документация по этой части не очень распространена в интернете, особенно в русскоязычном сегменте. Мне приходилось с ним заниматься, и без четкого описания кодирования, потребовалось длительное время для понимания протокола.
Пока мы хотели в целом рассказать о существующих протоколах, в дальнейшем уже будем в них углубляться, конечно. Спасибо, что читаете)
Единственный вопрос. Зачем нужно это сжатие при ныншней толщине каналов?
CME в свое время внушили себе, что это гениально и всех заставили эту гадость слушать. Бинарные структуры фиксированного формата (типа ITCH, используемый многими рынками) куда как эффективнее.
UDP пакеты (а это основной вид транспорта для FAST) ограничены в пределах MTU, обычно в районе 1500 байт, что довольно не много. Есть способы фрагментации пакетов на уровне сетевого оборудования, но надежность от этого сильно может пострадать. Таким образом, различного вида популярные протоколы (JSON, XML, FIX plain text) могут оказаться не применимы.
Также, у биржи существуют собственные бинарные протоколы: Plaza II (FORTS), MTE Srl (MICEX). Однако, они не являются универсальным мировым решением, что обеспечивает дополнительные затраты на разработку программ. Тогда как FIX и FIX/FAST являются общемировым стандартом обмена финансовой информации с биржей с огромным количеством готовых библиотек и приложений.
Что то, например, NASDAQ не торопится придерживаться данного «общемирового стандарта» и упорно рассылает ITCH сообщения, упакованные в мультикаст пакеты. Каждое сообщение длиной несколько десятков байт.
FAST/FIX испольует CME и его производные.
Московская же биржа как обычно идет своим путем.
То что FIX это стандартный протокол для отправки заявок, с этим никто не спорит. Мы же говорим о фидах и где по вашей ссылке вы видите FastFIx?
Там либо ITCH либо еще какой то их собственный.
Согласно Wiki/Exchanges that have adopted FAST. Есть еще статья.

Тем не менее, вы скорее всего правы, так как отсутствие каких-либо упоминаний в официальной документации, позволяет предположить, что их проект по реализации FAST не завершился (или был отменен).
Спасибо за уточнение.
Однако в ММВБ идет масштабная реструктуризация торговых решений. Возможно, взамен собственных нативных протоколов будет использоваться тот-же ITCH (исключительно предположение)
Каково время хранениня данных для Message Replay на MICEX? Другими словами, через какое максимальное время я могу запросить сообщения пропушенные в Incremental Refresh?
В течении торгового дня при условии, что счетчик сообщений не был сброшен.
>> Для передачи финансовых данных используются UDP-каналы, а по TCP передаются наборы недоставленных данных.
А как определяется что данные не были доставлены? Ведь если мы говорим о высокочастотной торговле, то там нет времени что-то кодировать, сличать контрольные суммы и перепосылать.
При высокочастотной торговли, операции кодирования и вычисления контрольной суммы тоже выполняются. Не только на клиентской части, но и в бирже.
Тем не менее, UDP канал обычно используют для получения данных о «стаканах» и прочей биржевой информации, так как эта информация обычно устаревает раньше, чем будет отправлен запрос на восстановление пропущенных сообщений.
Если отправляется заявка в биржу, то ее подтверждение (или отклонение) присылается обратно клиенту.
Если заявка была отправлена, а ответ потерялся, счетчик сообщений с биржи разойдется с клиентским (у биржи будет больше клиента).
Если заявка не была получена, счетчик сообщений так же разойдется (у клиента будет больше биржи).
У каждого сообщения порядковый номер есть. Если пришел больший чем ождается — значит потерялся.
Сорри, что пишу в старую тему — не нашел на Хабре ничего другого по OpenFAST, а поделиться хотелось: для парсинга сообщений по протоколу FAST есть библиотека openfast.org. Пример ее использования для обработки фидов с биржи:

    public static void main(String[] args) throws IOException {
        InputStream templateSource = new FileInputStream("FIX50SP2-2015-Apr.xml");
        MessageTemplateLoader templateLoader = new XMLMessageTemplateLoader();
        MessageTemplate[] templates = templateLoader.load(templateSource);
        final Context context = new Context();
        Arrays.asList(templates).stream().forEach((t) -> {
            context.registerTemplate(Integer.parseInt(t.getId()), t);
        });

        int port = Integer.parseInt(args[0]);

        NetworkInterface networkInterface = NetworkInterface.getByName("ppp0");
        try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
                .setOption(StandardSocketOptions.SO_REUSEADDR, true)
                .bind(new InetSocketAddress(port))
                .setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface)) {
            InetAddress group = InetAddress.getByName(args[1]);
            InetAddress source = InetAddress.getByName(args[2]);
            MembershipKey key = dc.join(group, networkInterface, source);

            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        while (true) {
                            ByteBuffer buf = ByteBuffer.allocate(4096);
                            dc.receive(buf);
                            //System.out.println(String.format("%d bytes received", buf.position()));
                            buf.position(4);
                            ByteBufferBackedInputStream in = new ByteBufferBackedInputStream(buf);
                            FastDecoder decoder = new FastDecoder(context, in);
                            Message message = decoder.readMessage();
                            if (message != null) {
                                System.out.println(String.format("Message template %s %s", message.getTemplate().getId(), message.getTemplate().getName()));
                            } else {
                                System.out.println("Null message, exiting...");
                                break;
                            }
                        }
                    } catch (IOException ex) {
                        ex.printStackTrace();
                        break;
                    }
                }
            });
            t.start();

            while (t.isAlive()) {
                try {
                    Thread.sleep(10);
                } catch(InterruptedException ignore) {
                    t.interrupt();
                }
            }

            key.drop();
        }
        System.exit(0);
    }


Пример вызова:

[root@vpn tmp]# java -jar FAST-Test-0.1.1.jar 9017 239.192.111.7 10.50.129.200
Message template 2423 X-MSR-FOND
Message template 2423 X-MSR-FOND
...
Зарегистрируйтесь на Хабре , чтобы оставить комментарий