CloseToAlgoTrading
CloseToAlgoTrading личный блог
29 января 2020, 12:04

Наброски торговой платформы использующей IB C++ API.

Всем привет, 

На днях поднималась тема о IB и C++ API. И вот я решил, что пора уж тоже выложить что то на гитхаб :). 

В идеале это должна быть торговая платформа, работающая как под виндой так и под линуксом. Так как весь этот проект развивается параллельно с другим более простым решением, то в нем мало что реализовано. Есть получение данных, возможность выставления различных ордеров и написание своих модулей/роботов которые включают в себя как GUI так и обработку данных (этот пункт на данный момент реализован как то совмем неудачно, думаю его в плагины перенести). В коде есть 'мусорные' модули, это мои эксперементы с qt gui :).

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

https://github.com/CloseToAlgoTrading/IbTradeQtDev

К чему все это. Если вдруг кому интересно, милости прошу :) можно просто брать и довести до ума, можно помочь в разработке, так как сам я еще лет 500 буду это делать )). Все открыто, все бесплатно. По себе знаю, что такие проекты мало кого заинтерисуют, все делают нечто свое, со своим видением, но может найдутся единомышленники.

Ах да, документации на данный момент нет… есть только некоторые наброски. Все в зачаточном состоянии.


13 Комментариев
  • Kapeks
    29 января 2020, 13:32
    У IB нет клиентского API?
  • Николай Маржинов
    29 января 2020, 19:47
    Ах да, документации на данный момент нет… есть только некоторые наброски. Все в зачаточном состоянии.


    Этот факт сильно усложнит погружение в проект. Не понятно чем собирать, какие версии библиотек используются...

  • Andrew Morozov
    30 января 2020, 22:37
    IB Api это говно протокол с кучей косяков. Брокер хороший, вопросов нет. Апи ужасное. Копаю этот вопрос в другом направлении, чем дальше в лес, тем больше удивлён как вообще это все работает, и главное как у тех людей которые внедряли этот код в свои платформы, хватило нервов победить это чудо. Denis, если у вас рейтинга достаточно, напишите в личку, возможно обменяемся какой-то информацией.
  • Andrew Morozov
    31 января 2020, 14:24
    К сожалению, не все так просто.
    Ну вот, это из официального дистрибутива их с++ примера:

    void EClient::reqContractDetails( int reqId, const Contract& contract)
    {
    // not connected?
    if( !isConnected()) {
    m_pEWrapper->error( NO_VALID_ID, NOT_CONNECTED.code(), NOT_CONNECTED.msg());
    return;
    }

    // Not needed anymore validation
    // This feature is only available for versions of TWS >=4
    //if( m_serverVersion < 4) {
    // m_pEWrapper->error( NO_VALID_ID, UPDATE_TWS.code(), UPDATE_TWS.msg());
    // return;
    //}
    if (m_serverVersion < MIN_SERVER_VER_SEC_ID_TYPE) {
    if( !contract.secIdType.empty() || !contract.secId.empty()) {
    m_pEWrapper->error( reqId, UPDATE_TWS.code(), UPDATE_TWS.msg() +
    " It does not support secIdType and secId parameters.");
    return;
    }
    }
    if (m_serverVersion < MIN_SERVER_VER_TRADING_CLASS) {
    if( !contract.tradingClass.empty()) {
    m_pEWrapper->error( reqId, UPDATE_TWS.code(), UPDATE_TWS.msg() +
    " It does not support tradingClass parameter in reqContractDetails.");
    return;
    }
    }
    if (m_serverVersion < MIN_SERVER_VER_LINKING) {
    if (!contract.primaryExchange.empty()) {
    m_pEWrapper->error( reqId, UPDATE_TWS.code(), UPDATE_TWS.msg() +
    " It does not support primaryExchange parameter in reqContractDetails.");
    return;
    }
    }

    std::stringstream msg;
    prepareBuffer( msg);

    const int VERSION = 8;

    // send req mkt data msg
    ENCODE_FIELD( REQ_CONTRACT_DATA);
    ENCODE_FIELD( VERSION);

    if( m_serverVersion >= MIN_SERVER_VER_CONTRACT_DATA_CHAIN)
    {
    ENCODE_FIELD( reqId);
    }

    // send contract fields
    ENCODE_FIELD( contract.conId); // srv v37 and above
    ENCODE_FIELD( contract.symbol);
    ENCODE_FIELD( contract.secType);
    ENCODE_FIELD( contract.lastTradeDateOrContractMonth);
    ENCODE_FIELD( contract.strike);
    ENCODE_FIELD( contract.right);
    ENCODE_FIELD( contract.multiplier); // srv v15 and above

    //Вот здесь чудеса начинаются...
    //Коннестится к ibgateway например NT8..
    // Первым делом клиет (нидзя) передаёт свою версию апи. Это 66.
    // Сервер отвечает что он работае по версии 76, все оки-доки.
    // Теперь внимательно!
    if (m_serverVersion >= MIN_SERVER_VER_PRIMARYEXCH/* == 75 !!!*/)
    {
    ENCODE_FIELD(contract.exchange);
    ENCODE_FIELD(contract.primaryExchange);
    }
    else if (m_serverVersion >= MIN_SERVER_VER_LINKING/* == 70 !!!*/)
    {
    if (!contract.primaryExchange.empty() && (contract.exchange == «BEST» || contract.exchange == «SMART»))
    {
    ENCODE_FIELD( contract.exchange + ":" + contract.primaryExchange);
    }
    else
    {
    ENCODE_FIELD(contract.exchange);
    }
    }

    //Исходя из вышеизложенного, запрос сцукко, ДОЛЖЕН!!! содержать поле contract.primaryExchange,
    //однако по факту зтого поля в текте нет!!!
    //Тем не менее, клиент и сервер прекрасно друг друга понимают, работаем дальше,
    //хотя должна произойти необратимая ошибка и acsess voilation readind location при чтении следующего сообщения..

    ENCODE_FIELD( contract.currency);
    ENCODE_FIELD( contract.localSymbol);

    if( m_serverVersion >= MIN_SERVER_VER_TRADING_CLASS)
    {
    ENCODE_FIELD( contract.tradingClass);
    }

    ENCODE_FIELD( contract.includeExpired); // srv v31 and above

    if( m_serverVersion >= MIN_SERVER_VER_SEC_ID_TYPE)
    {
    ENCODE_FIELD( contract.secIdType);
    ENCODE_FIELD( contract.secId);
    }

    closeAndSend( msg.str());
    }

  • Andrew Morozov
    31 января 2020, 21:08
    Denis, ну, не обязательно исключение, это может быть некое неопределённое поведение и как только ситуация будет обработана на сервере, и он поймёт, что с ним пытаются разговаривать на языке инопланетян будет вызван shut down для данного соединения
  • Andrew Morozov
    01 февраля 2020, 20:23
    Не совсем так. Работа сервера и клиента с разными версиями апи допустима, просто никакой документации кроме этого примера нет. В ситуации выше и я ничего не отправлял, я получил запрос, в котором в середине пропущено поле длиной несколько байт. В полном противоречии с правилами которые видны в коде этой функции.

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн