Блог им. DenisVo

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

Всем привет, 

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

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

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

https://github.com/CloseToAlgoTrading/IbTradeQtDev

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

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


★7
13 комментариев
У IB нет клиентского API?
avatar
Kapeks, что вы имеете ввиду?
у IB есть API и довльно продвинутая платформа. 
Для автоматической торговли нужно писать клиент, можно простой можно с гуи. 
avatar
Ах да, документации на данный момент нет… есть только некоторые наброски. Все в зачаточном состоянии.


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

Николай Маржинов, да действительно, не понятно.  Должно собирается с актульным qt, я сам qtcreator использую но раньше в visual studio собирал. Но qt все ж лучше в креаторе готовить.
avatar
IB Api это говно протокол с кучей косяков. Брокер хороший, вопросов нет. Апи ужасное. Копаю этот вопрос в другом направлении, чем дальше в лес, тем больше удивлён как вообще это все работает, и главное как у тех людей которые внедряли этот код в свои платформы, хватило нервов победить это чудо. Denis, если у вас рейтинга достаточно, напишите в личку, возможно обменяемся какой-то информацией.
avatar
Andrew Morozov, да ну что вы в самом деле… Норм апи… Думаю все сложно от того что они вроде как поддерживают старые версии
avatar
К сожалению, не все так просто.
Ну вот, это из официального дистрибутива их с++ примера:

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());
}

avatar
Andrew Morozov, 

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

 а почему должен произойти эксепшен то? это же запрос к серверу.

а где нет поля?
>>//однако по факту зтого поля в текте нет!!! 

avatar
Andrew Morozov, опишите мне в личку в деталях вашу проблему :), я вот посмотрел код, и все же не могу понять почему эксепшен должен быть.
avatar
Denis, ну, не обязательно исключение, это может быть некое неопределённое поведение и как только ситуация будет обработана на сервере, и он поймёт, что с ним пытаются разговаривать на языке инопланетян будет вызван shut down для данного соединения
avatar
Andrew Morozov, ну судя по тому что выше описано, нинзя шлет старую версию 66, а сервер работает на 76, далее вы заполняете запрос с неверными данными, однако сервер вполне может игнорировать эти данные, если они просто добавляются к концу.
avatar
Не совсем так. Работа сервера и клиента с разными версиями апи допустима, просто никакой документации кроме этого примера нет. В ситуации выше и я ничего не отправлял, я получил запрос, в котором в середине пропущено поле длиной несколько байт. В полном противоречии с правилами которые видны в коде этой функции.
avatar

теги блога CloseToAlgoTrading

....все тэги



UPDONW
Новый дизайн