Начало положено
тут
Продолжение
тут
Вступление
Разработка обертки протокола, только на первый взгляд, кажется простым. Нахрапом такую задачу не взять. Тут, как я уже говорил, важно посидеть с кружкой чая, полистать документацию, построить различные схемы, структуры. На основе этого, разработать логику обертки, иерархию классов и тд. Разберем иерархию команд протокола. Для анализа была взята
документация самой биржи.
Теоретически аспекты. Разложим немного по полочкам.
Все сообщения протокола можно разложить на несколько тем. Я начну с первой группы:
- Сообщения для поддержания связи.
- Logon; Тип=A; Сообщение для инициализации сессии. Грубо говоря для подключения к серверу
- Logout; Тип=5; Сообщение для завершения сессии. Сообщаем серверу о прекращении связи
- Hearbeat; Тип=0; Сообщение для поддержания связи.
- Request; Тип=1; Сообщение для поддержания связи. Запрос второй стороны, жива ли первая
- Reject; Тип=3; Сообщение об ошибке. Получаем его, если мы не правильно оформили свое сообщение
- Resend Request; Тип=2; Повторный запрос сообщений, в случае утери. Задается интервал номеров сообщений.
- Sequence Reset; Тип=4; Используется для сброса номеров сообщений.
На этом наверное буду заканчивать первую часть описания. В нее вошли функции, отвечающие исключительно за связь между клиентом и сервером. Давайте посмотрим теперь немного практики. И еще почертим.
Когда мы устанавливаем подключение к серверу, мы должны передать ему три параметра:
- метод шифрования (0 по умолчанию)
- интервал в секундах. Этот параметр указывает с каким интервалом мы будем обмениваться сообщениями поддержания связи (Hearbeat и Request)
- флаг сброса счетчика сообщений. (Y — сбросит на ноль).
При успешной операции, сервер нам отвечает тем же.
Далее, сервер с указанной периодичностью, начнет слать в наш адрес сообщения запросы подтверждения связи. Я написал быстренько небольшое приложение, которое поможет показать на практике этот процесс. Я сделал таймер, который каждую секунду проверяет, не пришло ли нам что нибудь на сокет.
Тут я моделирую, что мы глухи
А тут, я ему отвечаю на его запросы
В принципе, вот и все общение. Далее, с опытом, придется еще отработать механизмы обрыва связи и механизм потери сообщений.
Боевой кодинг. Начало борьбы за миллисекунды
С получением опыта пришлось существенно доработать классы. Где то появилась избыточность кода. Все идет на минимизацию расчетов.
К примеру. Приведу старые скрины кода из первой части. В каждом классе у меня были 2 метода:
- ToString() — создавал на основе класса строку соответствующего сообщения в формате FIX для передачи на сервер
- GetMessageSize() — подсчет длины строки для формирования заголовка сообщения
И при построении какого либо сообщения для отправки, у меня один и тот же метод использовался минимум 3 раза. То есть, я воспроизводил один и тот же расчет минимум 3 раза. Не проще ли произвести 1 раз и потом использовать его результат?
Для этого я пошел на избыточность. Я создал в каждом классе еще по два поля, которые заполнялись при первом расчете.
И уже стал использовать их при построении сообщения.
Вроде как мелочь, да и переписывать классы пришлось часа 4. Но такой ход позволил скосить в среднем до 10 миллисекунд на операцию и теперь на отправку и получения ответа уходит стабильно менее 90мл сек (раньше было около 100 постоянно и выше). Мелочь, а приятно.
На этом пока все. Теперь предстоит долгий путь создания кода под торговые операции.
10 мс сыкономить на каком-то методе при формировании сообщения??? а вы точно милли- с микро- секундами не путаете?
А мне чет показалось сначала что вы локально к эмулятору какому-то конектитесь...)
Я одно не пойму, зачем вы это делаете, когда есть открытый quickfixn.org/ Не проще ли присоединиться к проекту и его оптимизировать если это потребуется?
Насчет C++, я к сожалению его не знаю так хорошо (а решать поставленную задачу мне нужно именно сейчас), а почему был выбран c#, я ответил в самом начале. Мне доставляет удовольствие, как он работает с классами и коллекциями. Мог бы выбрать еще и Delphi, но паскаль так не справится.
Согласен с выше написанным — сильное сомнение в применимости вышенаписанного в боевых торгах.
Согласитесь, странно это все. Зарегистрированы 2 года назад. Ничего не писали. Теперь начали, и сразу в стиле платных писателей — слов много, смысла мало.
Пишите, конечно. Раз раскрутка сайта идет.
DateTime n1 = DateTime.Now;
int one = 1;
int two = 551;
bool yes = true;
for (int i = 0; i < 10000; i ++)
{
string res = String.Format("{0}={1}\u0001{2}={3}\u0001{4}={5}\u0001",
1,
one.ToString(),
2,
two.ToString(),
3,
yes.ToString()
);
int len = res.Length;
}
TimeSpan n2 = DateTime.Now — n1;
Console.WriteLine(n2.Milliseconds.ToString());
Console.ReadKey();
PS: Самый главный тормоз в твоем коде - String.Format, тебе нужно уйти от него, формируя строку обычными конкатенациями.
прям беда :)
то далеко не быдлокодить на шарпе
ну а джава к шарпу ближе как никто и опля — линукс в работе прям щас :)
ну дык почитай про шедулер виндов и не теряй время зря
экономить мс на винде это как на спининг вместо лески надеть льняную веревку — БЕССМЫСЛЕННО :)
писали такие же кодеры как и ты… вы будете явно рады встрече :)
пс: говорю по-доброму, без издевок. просто треп :)
линукс более предсказуем и имеет какой-то инструментарий для более-менее понятного времени отклика системы.
для более жесткого реал-тайма нужно что-то типа qnx видимо, сам не делал.
просто если уж шагать в пром. программировние, то от джавы и линукса. это хотя бы понятные шаги в правильном напрямку.
иначе получиться всеравно эС-шарп — т.е. ни то ни сё, а времени сожрет кучу. имхо :)
что до работы, то пройдя от джуниора лучше ее искать на западе нынче, а там сильно больше джавы требуется.
имхо-2. :)
всмысле нет разниц с С# почти по сути за редким, а вот кроссплатформеность у джавы сильно лучше.
скорости примерно равны будут на такой задаче.
джава + линукс > вин+шарп // стопудова :)
старт очень простой