修改vn.ib下的IB API到最新的9.72版本
This commit is contained in:
parent
8e658868b2
commit
745e716728
85
vn.ib/CMakeLists.txt
Normal file
85
vn.ib/CMakeLists.txt
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(vn_ib_api)
|
||||||
|
|
||||||
|
# 设置使用的编译器
|
||||||
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
|
if (CMAKE_COMPILER_IS_GNUC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++11")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# 设置输出目录
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
# 使用64位编译
|
||||||
|
option(USE_64BITS "comiple 64bits" ON)
|
||||||
|
if (USE_64BITS)
|
||||||
|
add_definitions(-DUSE_64BITS)
|
||||||
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||||
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 设置C++ API源文件的所在目录
|
||||||
|
if (WIN32)
|
||||||
|
set(IBAPI_PATH ibapi)
|
||||||
|
elseif (UNIX)
|
||||||
|
message("Under unix: " ${CMAKE_SIZEOF_VOID_P})
|
||||||
|
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||||
|
set(IBAPI_PATH ibapi)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
include_directories(${IBAPI_PATH})
|
||||||
|
#set(IBAPI_LIBRARY )
|
||||||
|
#find_library(IBAPI_LIBRARY
|
||||||
|
# NAMES thostmduserapi
|
||||||
|
# PATHS ${IBAPI_PATH})
|
||||||
|
#find_library(IBAPI_TD_LIBRARY
|
||||||
|
# NAMES thosttraderapi
|
||||||
|
# PATHS ${IBAPI_PATH})
|
||||||
|
|
||||||
|
|
||||||
|
# 设置编译源文件
|
||||||
|
set (vnib )
|
||||||
|
|
||||||
|
option(BUILD_IB "build ib" ON)
|
||||||
|
if (BUILD_IB)
|
||||||
|
add_definitions(-DBUILD_IB)
|
||||||
|
set(IB_PATH vnib/vnib)
|
||||||
|
include_directories(IB_PATH)
|
||||||
|
set(VN_IB_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/vnib/vnib/vnib.cpp)
|
||||||
|
add_library(vnib SHARED ${VN_IB_SOURCE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 设置Python所在的目录
|
||||||
|
set(PYTHON_LIBRARY )
|
||||||
|
if (WIN32)
|
||||||
|
set(PYTHON_INCLUDE_PATH C:/Python27/include)
|
||||||
|
find_library(PYTHON_LIBRARY
|
||||||
|
NAMES python27
|
||||||
|
PATHS C:/Python27/libs)
|
||||||
|
include_directories(${PYTHON_INCLUDE_PATH})
|
||||||
|
else()
|
||||||
|
set(PYTHON_INCLUDE_PATH /usr/include/python2.7/)
|
||||||
|
find_library(PYTHON_LIBRARY
|
||||||
|
NAMES python2.7
|
||||||
|
PATHS /usr/lib/x86_64-linux-gnu)
|
||||||
|
include_directories(${PYTHON_INCLUDE_PATH})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 链接boost库,anaconda
|
||||||
|
if (WIN32)
|
||||||
|
set(Boost_USE_STATIC_LIBS ON) #链接boost静态库
|
||||||
|
endif()
|
||||||
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
|
find_package(Boost 1.55.0 COMPONENTS python thread date_time system chrono REQUIRED) # 如果boost库没有完全编译,需要将编译的库明确地指出,否者message(${Boost_LIBRARIES})会出错
|
||||||
|
if(Boost_FOUND)
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# 去掉生成的so文件名中前缀的lib
|
||||||
|
set_target_properties(vnib PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
# 链接生成.so文件
|
||||||
|
target_link_libraries(vnib ${Boost_LIBRARIES} ${PYTHON_LIBRARY} ${IBAPI_LIBRARY})
|
||||||
|
|
||||||
|
|
@ -14,8 +14,13 @@
|
|||||||
|
|
||||||
4. vn.ib基于较新的IB官方API(9.72 beta)开发,IbPy则是采用了较老的API(9.70 stable)
|
4. vn.ib基于较新的IB官方API(9.72 beta)开发,IbPy则是采用了较老的API(9.70 stable)
|
||||||
|
|
||||||
|
### 对原生接口的修改部分
|
||||||
|
shared_ptr.h和SoftDollerTier.h中加入了对象比较函数的代码,用于实现其对应vector的自动Python封装。
|
||||||
|
|
||||||
### API版本
|
### API版本
|
||||||
版本:IB API for Windows beta 9.72
|
版本:IB API for Windows beta 9.72.18
|
||||||
|
|
||||||
|
日期:2016-09-14
|
||||||
|
|
||||||
链接:[http://interactivebrokers.github.io/](http://interactivebrokers.github.io/)
|
链接:[http://interactivebrokers.github.io/](http://interactivebrokers.github.io/)
|
||||||
|
|
||||||
|
13
vn.ib/build.sh
Normal file
13
vn.ib/build.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Written by Suzhengchun on 20160213
|
||||||
|
|
||||||
|
set -e
|
||||||
|
BUILDDIR=build
|
||||||
|
rm -rf $BUILDDIR
|
||||||
|
if [ ! -f $BUILDDIR ]; then
|
||||||
|
mkdir -p $BUILDDIR
|
||||||
|
fi
|
||||||
|
pushd $BUILDDIR
|
||||||
|
cmake ..
|
||||||
|
make VERBOSE=1 -j 1
|
||||||
|
popd
|
@ -1,224 +0,0 @@
|
|||||||
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
|
||||||
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef eclient_h__INCLUDED
|
|
||||||
#define eclient_h__INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include "CommonDefs.h"
|
|
||||||
#include "TagValue.h"
|
|
||||||
|
|
||||||
struct Contract;
|
|
||||||
struct Order;
|
|
||||||
struct ExecutionFilter;
|
|
||||||
struct ScannerSubscription;
|
|
||||||
struct ETransport;
|
|
||||||
|
|
||||||
class EWrapper;
|
|
||||||
typedef std::vector<char> BytesVec;
|
|
||||||
|
|
||||||
|
|
||||||
class TWSAPIDLLEXP EClient
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
explicit EClient(EWrapper *ptr, ETransport *pTransport);
|
|
||||||
~EClient();
|
|
||||||
|
|
||||||
virtual void eDisconnect() = 0;
|
|
||||||
|
|
||||||
int clientId() const { return m_clientId; }
|
|
||||||
|
|
||||||
const std::string& optionalCapabilities() const;
|
|
||||||
void setOptionalCapabilities(const std::string& optCapts);
|
|
||||||
|
|
||||||
void setConnectOptions(const std::string& connectOptions);
|
|
||||||
void disableUseV100Plus();
|
|
||||||
bool usingV100Plus();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void eConnectBase();
|
|
||||||
void eDisconnectBase();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum ConnState {
|
|
||||||
CS_DISCONNECTED,
|
|
||||||
CS_CONNECTING,
|
|
||||||
CS_CONNECTED,
|
|
||||||
CS_REDIRECT
|
|
||||||
};
|
|
||||||
|
|
||||||
// connection state
|
|
||||||
ConnState connState() const;
|
|
||||||
bool isConnected() const;
|
|
||||||
|
|
||||||
const std::string& host() const { return m_host; }
|
|
||||||
unsigned port() const { return m_port; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// access to protected variables
|
|
||||||
EWrapper * getWrapper() const;
|
|
||||||
protected:
|
|
||||||
void setClientId( int clientId);
|
|
||||||
void setExtraAuth( bool extraAuth);
|
|
||||||
void setHost( const std::string& host);
|
|
||||||
void setPort( unsigned port);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
bool isInBufferEmpty() const;
|
|
||||||
|
|
||||||
// override virtual funcs from EClient
|
|
||||||
int serverVersion();
|
|
||||||
std::string TwsConnectionTime();
|
|
||||||
void reqMktData(TickerId id, const Contract& contract,
|
|
||||||
const std::string& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions);
|
|
||||||
void cancelMktData(TickerId id);
|
|
||||||
void placeOrder(OrderId id, const Contract& contract, const Order& order);
|
|
||||||
void cancelOrder(OrderId id) ;
|
|
||||||
void reqOpenOrders();
|
|
||||||
void reqAccountUpdates(bool subscribe, const std::string& acctCode);
|
|
||||||
void reqExecutions(int reqId, const ExecutionFilter& filter);
|
|
||||||
void reqIds(int numIds);
|
|
||||||
void reqContractDetails(int reqId, const Contract& contract);
|
|
||||||
void reqMktDepth(TickerId tickerId, const Contract& contract, int numRows, const TagValueListSPtr& mktDepthOptions);
|
|
||||||
void cancelMktDepth(TickerId tickerId);
|
|
||||||
void reqNewsBulletins(bool allMsgs);
|
|
||||||
void cancelNewsBulletins();
|
|
||||||
void setServerLogLevel(int level);
|
|
||||||
void reqAutoOpenOrders(bool bAutoBind);
|
|
||||||
void reqAllOpenOrders();
|
|
||||||
void reqManagedAccts();
|
|
||||||
void requestFA(faDataType pFaDataType);
|
|
||||||
void replaceFA(faDataType pFaDataType, const std::string& cxml);
|
|
||||||
void reqHistoricalData( TickerId id, const Contract& contract,
|
|
||||||
const std::string& endDateTime, const std::string& durationStr,
|
|
||||||
const std::string& barSizeSetting, const std::string& whatToShow,
|
|
||||||
int useRTH, int formatDate, const TagValueListSPtr& chartOptions);
|
|
||||||
void exerciseOptions(TickerId tickerId, const Contract& contract,
|
|
||||||
int exerciseAction, int exerciseQuantity,
|
|
||||||
const std::string& account, int override);
|
|
||||||
void cancelHistoricalData(TickerId tickerId );
|
|
||||||
void reqRealTimeBars(TickerId id, const Contract& contract, int barSize,
|
|
||||||
const std::string& whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions);
|
|
||||||
void cancelRealTimeBars(TickerId tickerId );
|
|
||||||
void cancelScannerSubscription(int tickerId);
|
|
||||||
void reqScannerParameters();
|
|
||||||
void reqScannerSubscription(int tickerId, const ScannerSubscription& subscription, const TagValueListSPtr& scannerSubscriptionOptions);
|
|
||||||
void reqCurrentTime();
|
|
||||||
void reqFundamentalData(TickerId reqId, const Contract&, const std::string& reportType);
|
|
||||||
void cancelFundamentalData(TickerId reqId);
|
|
||||||
void calculateImpliedVolatility(TickerId reqId, const Contract& contract, double optionPrice, double underPrice);
|
|
||||||
void calculateOptionPrice(TickerId reqId, const Contract& contract, double volatility, double underPrice);
|
|
||||||
void cancelCalculateImpliedVolatility(TickerId reqId);
|
|
||||||
void cancelCalculateOptionPrice(TickerId reqId);
|
|
||||||
void reqGlobalCancel();
|
|
||||||
void reqMarketDataType(int marketDataType);
|
|
||||||
void reqPositions();
|
|
||||||
void cancelPositions();
|
|
||||||
void reqAccountSummary( int reqId, const std::string& groupName, const std::string& tags);
|
|
||||||
void cancelAccountSummary( int reqId);
|
|
||||||
void verifyRequest( const std::string& apiName, const std::string& apiVersion);
|
|
||||||
void verifyMessage( const std::string& apiData);
|
|
||||||
void verifyAndAuthRequest( const std::string& apiName, const std::string& apiVersion, const std::string& opaqueIsvKey);
|
|
||||||
void verifyAndAuthMessage( const std::string& apiData, const std::string& xyzResponse);
|
|
||||||
void queryDisplayGroups( int reqId);
|
|
||||||
void subscribeToGroupEvents( int reqId, int groupId);
|
|
||||||
void updateDisplayGroup( int reqId, const std::string& contractInfo);
|
|
||||||
void unsubscribeFromGroupEvents( int reqId);
|
|
||||||
void reqPositionsMulti( int reqId, const std::string& account, const std::string& modelCode);
|
|
||||||
void cancelPositionsMulti( int reqId);
|
|
||||||
void reqAccountUpdatessMulti( int reqId, const std::string& account, const std::string& modelCode, bool ledgerAndNLV);
|
|
||||||
void cancelAccountUpdatesMulti( int reqId);
|
|
||||||
void reqSecDefOptParams(int reqId, const std::string& underlyingSymbol, const std::string& futFopExchange, const std::string& underlyingSecType, int underlyingConId);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
virtual int receive(char* buf, size_t sz) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void prepareBufferImpl(std::ostream&) const = 0;
|
|
||||||
virtual void prepareBuffer(std::ostream&) const = 0;
|
|
||||||
virtual bool closeAndSend(std::string msg, unsigned offset = 0) = 0;
|
|
||||||
virtual int bufferedSend(const std::string& msg);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int bufferedRead();
|
|
||||||
|
|
||||||
// try to process connection request ack
|
|
||||||
private:
|
|
||||||
// try to process single msg
|
|
||||||
int processMsgImpl(const char*& ptr, const char* endPtr);
|
|
||||||
int processMsg(const char*& ptr, const char* endPtr);
|
|
||||||
|
|
||||||
typedef int (EClient::*messageHandler)(const char*& ptr, const char* endPtr);
|
|
||||||
int processOnePrefixedMsg(const char*& ptr, const char* endPtr, messageHandler);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void startApi();
|
|
||||||
|
|
||||||
|
|
||||||
// encoders
|
|
||||||
template<class T> static void EncodeField(std::ostream&, T);
|
|
||||||
|
|
||||||
// "max" encoders
|
|
||||||
static void EncodeFieldMax(std::ostream& os, int);
|
|
||||||
static void EncodeFieldMax(std::ostream& os, double);
|
|
||||||
|
|
||||||
// socket state
|
|
||||||
private:
|
|
||||||
virtual bool isSocketOK() const = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
bool isConnecting() const;
|
|
||||||
int sendConnectRequest();
|
|
||||||
bool extraAuth();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
EWrapper *m_pEWrapper;
|
|
||||||
std::auto_ptr<ETransport> m_transport;
|
|
||||||
|
|
||||||
private:
|
|
||||||
BytesVec m_inBuffer;
|
|
||||||
|
|
||||||
std::string m_host;
|
|
||||||
int m_port;
|
|
||||||
|
|
||||||
int m_clientId;
|
|
||||||
|
|
||||||
ConnState m_connState;
|
|
||||||
bool m_extraAuth;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int m_serverVersion;
|
|
||||||
std::string m_TwsTime;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_optionalCapabilities;
|
|
||||||
|
|
||||||
std::string m_connectOptions;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool m_useV100Plus;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> void EClient::EncodeField<bool>(std::ostream& os, bool);
|
|
||||||
template<> void EClient::EncodeField<double>(std::ostream& os, double);
|
|
||||||
|
|
||||||
#define ENCODE_FIELD(x) EClient::EncodeField(msg, x);
|
|
||||||
#define ENCODE_FIELD_MAX(x) EClient::EncodeFieldMax(msg, x);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
Binary file not shown.
@ -72,5 +72,6 @@ void DefaultEWrapper::accountUpdateMulti( int reqId, const std::string& account,
|
|||||||
void DefaultEWrapper::accountUpdateMultiEnd( int reqId) { }
|
void DefaultEWrapper::accountUpdateMultiEnd( int reqId) { }
|
||||||
void DefaultEWrapper::securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes) { }
|
void DefaultEWrapper::securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes) { }
|
||||||
void DefaultEWrapper::securityDefinitionOptionalParameterEnd(int reqId) { }
|
void DefaultEWrapper::securityDefinitionOptionalParameterEnd(int reqId) { }
|
||||||
|
void DefaultEWrapper::softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers) { }
|
||||||
|
|
||||||
|
|
@ -76,5 +76,6 @@ public:
|
|||||||
virtual void accountUpdateMultiEnd( int reqId);
|
virtual void accountUpdateMultiEnd( int reqId);
|
||||||
virtual void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes);
|
virtual void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes);
|
||||||
virtual void securityDefinitionOptionalParameterEnd(int reqId);
|
virtual void securityDefinitionOptionalParameterEnd(int reqId);
|
||||||
|
virtual void softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers);
|
||||||
};
|
};
|
||||||
|
|
@ -27,157 +27,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
using namespace ibapi::client_constants;
|
||||||
// SOCKET CLIENT VERSION CHANGE LOG : Incremented when the format of incomming
|
|
||||||
// server responses change
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// constants
|
|
||||||
// 6 = Added parentId to orderStatus
|
|
||||||
// 7 = The new execDetails event returned for an order filled status and reqExecDetails
|
|
||||||
// Also added market depth support.
|
|
||||||
// 8 = Added 'lastFillPrice' to orderStatus and 'permId' to execDetails
|
|
||||||
// 9 = Added 'avgCost', 'unrealizedPNL', and 'unrealizedPNL' to updatePortfolio event
|
|
||||||
// 10 = Added 'serverId' to the 'open order' & 'order status' events.
|
|
||||||
// We send back all the API open orders upon connection.
|
|
||||||
// Added new methods reqAllOpenOrders, reqAutoOpenOrders()
|
|
||||||
// Added FA support - reqExecution has filter.
|
|
||||||
// - reqAccountUpdates takes acct code.
|
|
||||||
// 11 = Added permId to openOrder event.
|
|
||||||
// 12 = Added IgnoreRth, hidden, and discretionaryAmt
|
|
||||||
// 13 = Added GoodAfterTime
|
|
||||||
// 14 = always send size on bid/ask/last tick
|
|
||||||
// 15 = send allocation string with open order
|
|
||||||
// 16 = can receive account name in account and portfolio updates, and fa params in openOrder
|
|
||||||
// 17 = can receive liquidation field in exec reports, and notAutoAvailable field in mkt data
|
|
||||||
// 18 = can receive good till date field in open order messages, and send backfill requests
|
|
||||||
// 19 = can receive new extended order attributes in OPEN_ORDER
|
|
||||||
// 20 = expects TWS time string on connection after server version >= 20, and parentId in open order
|
|
||||||
// 21 = can receive bond contract details.
|
|
||||||
// 22 = can receive price magnifier in contract details
|
|
||||||
// 23 = support for scanner
|
|
||||||
// 24 = can receive volatility order parameters in open order messages
|
|
||||||
// 25 = can receive HMDS query start and end times
|
|
||||||
// 26 = can receive option vols in option market data messages
|
|
||||||
// 27 = can receive delta neutral order type and delta neutral aux price
|
|
||||||
// 28 = can receive option model computation ticks
|
|
||||||
// 29 = can receive trail stop limit price in open order and can place them: API 8.91
|
|
||||||
// 30 = can receive extended bond contract def, new ticks, and trade count in bars
|
|
||||||
// 31 = can receive EFP extensions to scanner and market data, and combo legs on open orders
|
|
||||||
// ; can receive RT bars
|
|
||||||
// 32 = can receive TickType.LAST_TIMESTAMP
|
|
||||||
// 33 = can receive ScaleNumComponents and ScaleComponentSize is open order messages
|
|
||||||
// 34 = can receive whatIf orders / order state
|
|
||||||
// 35 = can receive contId field for Contract objects
|
|
||||||
// 36 = can receive outsideRth field for Order objects
|
|
||||||
// 37 = can receive clearingAccount and clearingIntent for Order objects
|
|
||||||
// 38 = can receive multipier and primaryExchange in portfolio updates
|
|
||||||
// ; can receive cumQty and avgPrice in execution
|
|
||||||
// ; can receive fundamental data
|
|
||||||
// ; can receive underComp for Contract objects
|
|
||||||
// ; can receive reqId and end marker in contractDetails/bondContractDetails
|
|
||||||
// ; can receive ScaleInitComponentSize and ScaleSubsComponentSize for Order objects
|
|
||||||
// 39 = can receive underConId in contractDetails
|
|
||||||
// 40 = can receive algoStrategy/algoParams in openOrder
|
|
||||||
// 41 = can receive end marker for openOrder
|
|
||||||
// ; can receive end marker for account download
|
|
||||||
// ; can receive end marker for executions download
|
|
||||||
// 42 = can receive deltaNeutralValidation
|
|
||||||
// 43 = can receive longName(companyName)
|
|
||||||
// ; can receive listingExchange
|
|
||||||
// ; can receive RTVolume tick
|
|
||||||
// 44 = can receive end market for ticker snapshot
|
|
||||||
// 45 = can receive notHeld field in openOrder
|
|
||||||
// 46 = can receive contractMonth, industry, category, subcategory fields in contractDetails
|
|
||||||
// ; can receive timeZoneId, tradingHours, liquidHours fields in contractDetails
|
|
||||||
// 47 = can receive gamma, vega, theta, undPrice fields in TICK_OPTION_COMPUTATION
|
|
||||||
// 48 = can receive exemptCode in openOrder
|
|
||||||
// 49 = can receive hedgeType and hedgeParam in openOrder
|
|
||||||
// 50 = can receive optOutSmartRouting field in openOrder
|
|
||||||
// 51 = can receive smartComboRoutingParams in openOrder
|
|
||||||
// 52 = can receive deltaNeutralConId, deltaNeutralSettlingFirm, deltaNeutralClearingAccount and deltaNeutralClearingIntent in openOrder
|
|
||||||
// 53 = can receive orderRef in execution
|
|
||||||
// 54 = can receive scale order fields (PriceAdjustValue, PriceAdjustInterval, ProfitOffset, AutoReset,
|
|
||||||
// InitPosition, InitFillQty and RandomPercent) in openOrder
|
|
||||||
// 55 = can receive orderComboLegs (price) in openOrder
|
|
||||||
// 56 = can receive trailingPercent in openOrder
|
|
||||||
// 57 = can receive commissionReport message
|
|
||||||
// 58 = can receive CUSIP/ISIN/etc. in contractDescription/bondContractDescription
|
|
||||||
// 59 = can receive evRule, evMultiplier in contractDescription/bondContractDescription/executionDetails
|
|
||||||
// can receive multiplier in executionDetails
|
|
||||||
// 60 = can receive deltaNeutralOpenClose, deltaNeutralShortSale, deltaNeutralShortSaleSlot
|
|
||||||
// and deltaNeutralDesignatedLocation in openOrder
|
|
||||||
// can receive position, positionEnd, accountSummary and accountSummaryEnd
|
|
||||||
// 61 = can receive multiplier in openOrder
|
|
||||||
// can receive tradingClass in openOrder, updatePortfolio, execDetails and position
|
|
||||||
// 62 = can receive avgCost in position message
|
|
||||||
// 63 = can receive verifyMessageAPI, verifyCompleted, displayGroupList and displayGroupUpdated messages
|
|
||||||
// 64 = can receive solicited attrib in openOrder message
|
|
||||||
// 65 = can receive verifyAndAuthMessageAPI and verifyAndAuthCompleted messages
|
|
||||||
// 66 = can receive randomize size and randomize price order fields
|
|
||||||
|
|
||||||
const int CLIENT_VERSION = 66;
|
|
||||||
|
|
||||||
|
|
||||||
// outgoing msg id's
|
|
||||||
const int REQ_MKT_DATA = 1;
|
|
||||||
const int CANCEL_MKT_DATA = 2;
|
|
||||||
const int PLACE_ORDER = 3;
|
|
||||||
const int CANCEL_ORDER = 4;
|
|
||||||
const int REQ_OPEN_ORDERS = 5;
|
|
||||||
const int REQ_ACCT_DATA = 6;
|
|
||||||
const int REQ_EXECUTIONS = 7;
|
|
||||||
const int REQ_IDS = 8;
|
|
||||||
const int REQ_CONTRACT_DATA = 9;
|
|
||||||
const int REQ_MKT_DEPTH = 10;
|
|
||||||
const int CANCEL_MKT_DEPTH = 11;
|
|
||||||
const int REQ_NEWS_BULLETINS = 12;
|
|
||||||
const int CANCEL_NEWS_BULLETINS = 13;
|
|
||||||
const int SET_SERVER_LOGLEVEL = 14;
|
|
||||||
const int REQ_AUTO_OPEN_ORDERS = 15;
|
|
||||||
const int REQ_ALL_OPEN_ORDERS = 16;
|
|
||||||
const int REQ_MANAGED_ACCTS = 17;
|
|
||||||
const int REQ_FA = 18;
|
|
||||||
const int REPLACE_FA = 19;
|
|
||||||
const int REQ_HISTORICAL_DATA = 20;
|
|
||||||
const int EXERCISE_OPTIONS = 21;
|
|
||||||
const int REQ_SCANNER_SUBSCRIPTION = 22;
|
|
||||||
const int CANCEL_SCANNER_SUBSCRIPTION = 23;
|
|
||||||
const int REQ_SCANNER_PARAMETERS = 24;
|
|
||||||
const int CANCEL_HISTORICAL_DATA = 25;
|
|
||||||
const int REQ_CURRENT_TIME = 49;
|
|
||||||
const int REQ_REAL_TIME_BARS = 50;
|
|
||||||
const int CANCEL_REAL_TIME_BARS = 51;
|
|
||||||
const int REQ_FUNDAMENTAL_DATA = 52;
|
|
||||||
const int CANCEL_FUNDAMENTAL_DATA = 53;
|
|
||||||
const int REQ_CALC_IMPLIED_VOLAT = 54;
|
|
||||||
const int REQ_CALC_OPTION_PRICE = 55;
|
|
||||||
const int CANCEL_CALC_IMPLIED_VOLAT = 56;
|
|
||||||
const int CANCEL_CALC_OPTION_PRICE = 57;
|
|
||||||
const int REQ_GLOBAL_CANCEL = 58;
|
|
||||||
const int REQ_MARKET_DATA_TYPE = 59;
|
|
||||||
const int REQ_POSITIONS = 61;
|
|
||||||
const int REQ_ACCOUNT_SUMMARY = 62;
|
|
||||||
const int CANCEL_ACCOUNT_SUMMARY = 63;
|
|
||||||
const int CANCEL_POSITIONS = 64;
|
|
||||||
const int VERIFY_REQUEST = 65;
|
|
||||||
const int VERIFY_MESSAGE = 66;
|
|
||||||
const int QUERY_DISPLAY_GROUPS = 67;
|
|
||||||
const int SUBSCRIBE_TO_GROUP_EVENTS = 68;
|
|
||||||
const int UPDATE_DISPLAY_GROUP = 69;
|
|
||||||
const int UNSUBSCRIBE_FROM_GROUP_EVENTS = 70;
|
|
||||||
const int START_API = 71;
|
|
||||||
const int VERIFY_AND_AUTH_REQUEST = 72;
|
|
||||||
const int VERIFY_AND_AUTH_MESSAGE = 73;
|
|
||||||
const int REQ_POSITIONS_MULTI = 74;
|
|
||||||
const int CANCEL_POSITIONS_MULTI = 75;
|
|
||||||
const int REQ_ACCOUNT_UPDATES_MULTI = 76;
|
|
||||||
const int CANCEL_ACCOUNT_UPDATES_MULTI = 77;
|
|
||||||
const int REQ_SEC_DEF_OPT_PARAMS = 78;
|
|
||||||
|
|
||||||
// TWS New Bulletins constants
|
|
||||||
const int NEWS_MSG = 1; // standard IB news bulleting message
|
|
||||||
const int EXCHANGE_AVAIL_MSG = 2; // control message specifing that an exchange is available for trading
|
|
||||||
const int EXCHANGE_UNAVAIL_MSG = 3; // control message specifing that an exchange is unavailable for trading
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// encoders
|
// encoders
|
||||||
@ -1507,6 +1357,17 @@ void EClient::placeOrder( OrderId id, const Contract& contract, const Order& ord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_serverVersion < MIN_SERVER_VER_SOFT_DOLLAR_TIER)
|
||||||
|
{
|
||||||
|
if (!order.softDollarTier.name().empty() || !order.softDollarTier.val().empty())
|
||||||
|
{
|
||||||
|
m_pEWrapper->error( id, UPDATE_TWS.code(), UPDATE_TWS.msg() +
|
||||||
|
" It does not support soft dollar tier");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
prepareBuffer( msg);
|
prepareBuffer( msg);
|
||||||
|
|
||||||
@ -1896,6 +1757,11 @@ void EClient::placeOrder( OrderId id, const Contract& contract, const Order& ord
|
|||||||
ENCODE_FIELD( order.extOperator);
|
ENCODE_FIELD( order.extOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_serverVersion >= MIN_SERVER_VER_SOFT_DOLLAR_TIER) {
|
||||||
|
ENCODE_FIELD(order.softDollarTier.name());
|
||||||
|
ENCODE_FIELD(order.softDollarTier.val());
|
||||||
|
}
|
||||||
|
|
||||||
closeAndSend( msg.str());
|
closeAndSend( msg.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2820,6 +2686,23 @@ void EClient::reqSecDefOptParams(int reqId, const std::string& underlyingSymbol,
|
|||||||
closeAndSend(msg.str());
|
closeAndSend(msg.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EClient::reqSoftDollarTiers(int reqId)
|
||||||
|
{
|
||||||
|
if( !isConnected()) {
|
||||||
|
m_pEWrapper->error( NO_VALID_ID, NOT_CONNECTED.code(), NOT_CONNECTED.msg());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream msg;
|
||||||
|
prepareBuffer(msg);
|
||||||
|
|
||||||
|
|
||||||
|
ENCODE_FIELD(REQ_SOFT_DOLLAR_TIERS);
|
||||||
|
ENCODE_FIELD(reqId);
|
||||||
|
|
||||||
|
closeAndSend(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
int EClient::processMsgImpl(const char*& beginPtr, const char* endPtr)
|
int EClient::processMsgImpl(const char*& beginPtr, const char* endPtr)
|
||||||
{
|
{
|
||||||
EDecoder decoder(serverVersion(), m_pEWrapper);
|
EDecoder decoder(serverVersion(), m_pEWrapper);
|
384
vn.ib/ibapi/linux/client/EClient.h
Normal file
384
vn.ib/ibapi/linux/client/EClient.h
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef eclient_h__INCLUDED
|
||||||
|
#define eclient_h__INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include "CommonDefs.h"
|
||||||
|
#include "TagValue.h"
|
||||||
|
|
||||||
|
namespace ibapi {
|
||||||
|
namespace client_constants {
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SOCKET CLIENT VERSION CHANGE LOG : Incremented when the format of incomming
|
||||||
|
// server responses change
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// constants
|
||||||
|
// 6 = Added parentId to orderStatus
|
||||||
|
// 7 = The new execDetails event returned for an order filled status and reqExecDetails
|
||||||
|
// Also added market depth support.
|
||||||
|
// 8 = Added 'lastFillPrice' to orderStatus and 'permId' to execDetails
|
||||||
|
// 9 = Added 'avgCost', 'unrealizedPNL', and 'unrealizedPNL' to updatePortfolio event
|
||||||
|
// 10 = Added 'serverId' to the 'open order' & 'order status' events.
|
||||||
|
// We send back all the API open orders upon connection.
|
||||||
|
// Added new methods reqAllOpenOrders, reqAutoOpenOrders()
|
||||||
|
// Added FA support - reqExecution has filter.
|
||||||
|
// - reqAccountUpdates takes acct code.
|
||||||
|
// 11 = Added permId to openOrder event.
|
||||||
|
// 12 = Added IgnoreRth, hidden, and discretionaryAmt
|
||||||
|
// 13 = Added GoodAfterTime
|
||||||
|
// 14 = always send size on bid/ask/last tick
|
||||||
|
// 15 = send allocation string with open order
|
||||||
|
// 16 = can receive account name in account and portfolio updates, and fa params in openOrder
|
||||||
|
// 17 = can receive liquidation field in exec reports, and notAutoAvailable field in mkt data
|
||||||
|
// 18 = can receive good till date field in open order messages, and send backfill requests
|
||||||
|
// 19 = can receive new extended order attributes in OPEN_ORDER
|
||||||
|
// 20 = expects TWS time string on connection after server version >= 20, and parentId in open order
|
||||||
|
// 21 = can receive bond contract details.
|
||||||
|
// 22 = can receive price magnifier in contract details
|
||||||
|
// 23 = support for scanner
|
||||||
|
// 24 = can receive volatility order parameters in open order messages
|
||||||
|
// 25 = can receive HMDS query start and end times
|
||||||
|
// 26 = can receive option vols in option market data messages
|
||||||
|
// 27 = can receive delta neutral order type and delta neutral aux price
|
||||||
|
// 28 = can receive option model computation ticks
|
||||||
|
// 29 = can receive trail stop limit price in open order and can place them: API 8.91
|
||||||
|
// 30 = can receive extended bond contract def, new ticks, and trade count in bars
|
||||||
|
// 31 = can receive EFP extensions to scanner and market data, and combo legs on open orders
|
||||||
|
// ; can receive RT bars
|
||||||
|
// 32 = can receive TickType.LAST_TIMESTAMP
|
||||||
|
// 33 = can receive ScaleNumComponents and ScaleComponentSize is open order messages
|
||||||
|
// 34 = can receive whatIf orders / order state
|
||||||
|
// 35 = can receive contId field for Contract objects
|
||||||
|
// 36 = can receive outsideRth field for Order objects
|
||||||
|
// 37 = can receive clearingAccount and clearingIntent for Order objects
|
||||||
|
// 38 = can receive multipier and primaryExchange in portfolio updates
|
||||||
|
// ; can receive cumQty and avgPrice in execution
|
||||||
|
// ; can receive fundamental data
|
||||||
|
// ; can receive underComp for Contract objects
|
||||||
|
// ; can receive reqId and end marker in contractDetails/bondContractDetails
|
||||||
|
// ; can receive ScaleInitComponentSize and ScaleSubsComponentSize for Order objects
|
||||||
|
// 39 = can receive underConId in contractDetails
|
||||||
|
// 40 = can receive algoStrategy/algoParams in openOrder
|
||||||
|
// 41 = can receive end marker for openOrder
|
||||||
|
// ; can receive end marker for account download
|
||||||
|
// ; can receive end marker for executions download
|
||||||
|
// 42 = can receive deltaNeutralValidation
|
||||||
|
// 43 = can receive longName(companyName)
|
||||||
|
// ; can receive listingExchange
|
||||||
|
// ; can receive RTVolume tick
|
||||||
|
// 44 = can receive end market for ticker snapshot
|
||||||
|
// 45 = can receive notHeld field in openOrder
|
||||||
|
// 46 = can receive contractMonth, industry, category, subcategory fields in contractDetails
|
||||||
|
// ; can receive timeZoneId, tradingHours, liquidHours fields in contractDetails
|
||||||
|
// 47 = can receive gamma, vega, theta, undPrice fields in TICK_OPTION_COMPUTATION
|
||||||
|
// 48 = can receive exemptCode in openOrder
|
||||||
|
// 49 = can receive hedgeType and hedgeParam in openOrder
|
||||||
|
// 50 = can receive optOutSmartRouting field in openOrder
|
||||||
|
// 51 = can receive smartComboRoutingParams in openOrder
|
||||||
|
// 52 = can receive deltaNeutralConId, deltaNeutralSettlingFirm, deltaNeutralClearingAccount and deltaNeutralClearingIntent in openOrder
|
||||||
|
// 53 = can receive orderRef in execution
|
||||||
|
// 54 = can receive scale order fields (PriceAdjustValue, PriceAdjustInterval, ProfitOffset, AutoReset,
|
||||||
|
// InitPosition, InitFillQty and RandomPercent) in openOrder
|
||||||
|
// 55 = can receive orderComboLegs (price) in openOrder
|
||||||
|
// 56 = can receive trailingPercent in openOrder
|
||||||
|
// 57 = can receive commissionReport message
|
||||||
|
// 58 = can receive CUSIP/ISIN/etc. in contractDescription/bondContractDescription
|
||||||
|
// 59 = can receive evRule, evMultiplier in contractDescription/bondContractDescription/executionDetails
|
||||||
|
// can receive multiplier in executionDetails
|
||||||
|
// 60 = can receive deltaNeutralOpenClose, deltaNeutralShortSale, deltaNeutralShortSaleSlot
|
||||||
|
// and deltaNeutralDesignatedLocation in openOrder
|
||||||
|
// can receive position, positionEnd, accountSummary and accountSummaryEnd
|
||||||
|
// 61 = can receive multiplier in openOrder
|
||||||
|
// can receive tradingClass in openOrder, updatePortfolio, execDetails and position
|
||||||
|
// 62 = can receive avgCost in position message
|
||||||
|
// 63 = can receive verifyMessageAPI, verifyCompleted, displayGroupList and displayGroupUpdated messages
|
||||||
|
// 64 = can receive solicited attrib in openOrder message
|
||||||
|
// 65 = can receive verifyAndAuthMessageAPI and verifyAndAuthCompleted messages
|
||||||
|
// 66 = can receive randomize size and randomize price order fields
|
||||||
|
|
||||||
|
const int CLIENT_VERSION = 66;
|
||||||
|
|
||||||
|
|
||||||
|
// outgoing msg id's
|
||||||
|
const int REQ_MKT_DATA = 1;
|
||||||
|
const int CANCEL_MKT_DATA = 2;
|
||||||
|
const int PLACE_ORDER = 3;
|
||||||
|
const int CANCEL_ORDER = 4;
|
||||||
|
const int REQ_OPEN_ORDERS = 5;
|
||||||
|
const int REQ_ACCT_DATA = 6;
|
||||||
|
const int REQ_EXECUTIONS = 7;
|
||||||
|
const int REQ_IDS = 8;
|
||||||
|
const int REQ_CONTRACT_DATA = 9;
|
||||||
|
const int REQ_MKT_DEPTH = 10;
|
||||||
|
const int CANCEL_MKT_DEPTH = 11;
|
||||||
|
const int REQ_NEWS_BULLETINS = 12;
|
||||||
|
const int CANCEL_NEWS_BULLETINS = 13;
|
||||||
|
const int SET_SERVER_LOGLEVEL = 14;
|
||||||
|
const int REQ_AUTO_OPEN_ORDERS = 15;
|
||||||
|
const int REQ_ALL_OPEN_ORDERS = 16;
|
||||||
|
const int REQ_MANAGED_ACCTS = 17;
|
||||||
|
const int REQ_FA = 18;
|
||||||
|
const int REPLACE_FA = 19;
|
||||||
|
const int REQ_HISTORICAL_DATA = 20;
|
||||||
|
const int EXERCISE_OPTIONS = 21;
|
||||||
|
const int REQ_SCANNER_SUBSCRIPTION = 22;
|
||||||
|
const int CANCEL_SCANNER_SUBSCRIPTION = 23;
|
||||||
|
const int REQ_SCANNER_PARAMETERS = 24;
|
||||||
|
const int CANCEL_HISTORICAL_DATA = 25;
|
||||||
|
const int REQ_CURRENT_TIME = 49;
|
||||||
|
const int REQ_REAL_TIME_BARS = 50;
|
||||||
|
const int CANCEL_REAL_TIME_BARS = 51;
|
||||||
|
const int REQ_FUNDAMENTAL_DATA = 52;
|
||||||
|
const int CANCEL_FUNDAMENTAL_DATA = 53;
|
||||||
|
const int REQ_CALC_IMPLIED_VOLAT = 54;
|
||||||
|
const int REQ_CALC_OPTION_PRICE = 55;
|
||||||
|
const int CANCEL_CALC_IMPLIED_VOLAT = 56;
|
||||||
|
const int CANCEL_CALC_OPTION_PRICE = 57;
|
||||||
|
const int REQ_GLOBAL_CANCEL = 58;
|
||||||
|
const int REQ_MARKET_DATA_TYPE = 59;
|
||||||
|
const int REQ_POSITIONS = 61;
|
||||||
|
const int REQ_ACCOUNT_SUMMARY = 62;
|
||||||
|
const int CANCEL_ACCOUNT_SUMMARY = 63;
|
||||||
|
const int CANCEL_POSITIONS = 64;
|
||||||
|
const int VERIFY_REQUEST = 65;
|
||||||
|
const int VERIFY_MESSAGE = 66;
|
||||||
|
const int QUERY_DISPLAY_GROUPS = 67;
|
||||||
|
const int SUBSCRIBE_TO_GROUP_EVENTS = 68;
|
||||||
|
const int UPDATE_DISPLAY_GROUP = 69;
|
||||||
|
const int UNSUBSCRIBE_FROM_GROUP_EVENTS = 70;
|
||||||
|
const int START_API = 71;
|
||||||
|
const int VERIFY_AND_AUTH_REQUEST = 72;
|
||||||
|
const int VERIFY_AND_AUTH_MESSAGE = 73;
|
||||||
|
const int REQ_POSITIONS_MULTI = 74;
|
||||||
|
const int CANCEL_POSITIONS_MULTI = 75;
|
||||||
|
const int REQ_ACCOUNT_UPDATES_MULTI = 76;
|
||||||
|
const int CANCEL_ACCOUNT_UPDATES_MULTI = 77;
|
||||||
|
const int REQ_SEC_DEF_OPT_PARAMS = 78;
|
||||||
|
const int REQ_SOFT_DOLLAR_TIERS = 79;
|
||||||
|
|
||||||
|
// TWS New Bulletins constants
|
||||||
|
const int NEWS_MSG = 1; // standard IB news bulleting message
|
||||||
|
const int EXCHANGE_AVAIL_MSG = 2; // control message specifing that an exchange is available for trading
|
||||||
|
const int EXCHANGE_UNAVAIL_MSG = 3; // control message specifing that an exchange is unavailable for trading
|
||||||
|
|
||||||
|
} // namespace client_constants
|
||||||
|
} // namespace ibapi
|
||||||
|
|
||||||
|
struct Contract;
|
||||||
|
struct Order;
|
||||||
|
struct ExecutionFilter;
|
||||||
|
struct ScannerSubscription;
|
||||||
|
struct ETransport;
|
||||||
|
|
||||||
|
class EWrapper;
|
||||||
|
typedef std::vector<char> BytesVec;
|
||||||
|
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit EClient(EWrapper *ptr, ETransport *pTransport);
|
||||||
|
~EClient();
|
||||||
|
|
||||||
|
virtual void eDisconnect() = 0;
|
||||||
|
|
||||||
|
int clientId() const { return m_clientId; }
|
||||||
|
|
||||||
|
const std::string& optionalCapabilities() const;
|
||||||
|
void setOptionalCapabilities(const std::string& optCapts);
|
||||||
|
|
||||||
|
void setConnectOptions(const std::string& connectOptions);
|
||||||
|
void disableUseV100Plus();
|
||||||
|
bool usingV100Plus();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void eConnectBase();
|
||||||
|
void eDisconnectBase();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ConnState {
|
||||||
|
CS_DISCONNECTED,
|
||||||
|
CS_CONNECTING,
|
||||||
|
CS_CONNECTED,
|
||||||
|
CS_REDIRECT
|
||||||
|
};
|
||||||
|
|
||||||
|
// connection state
|
||||||
|
ConnState connState() const;
|
||||||
|
bool isConnected() const;
|
||||||
|
|
||||||
|
const std::string& host() const { return m_host; }
|
||||||
|
unsigned port() const { return m_port; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// access to protected variables
|
||||||
|
EWrapper * getWrapper() const;
|
||||||
|
protected:
|
||||||
|
void setClientId( int clientId);
|
||||||
|
void setExtraAuth( bool extraAuth);
|
||||||
|
void setHost( const std::string& host);
|
||||||
|
void setPort( unsigned port);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool isInBufferEmpty() const;
|
||||||
|
|
||||||
|
// override virtual funcs from EClient
|
||||||
|
int serverVersion();
|
||||||
|
std::string TwsConnectionTime();
|
||||||
|
void reqMktData(TickerId id, const Contract& contract,
|
||||||
|
const std::string& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions);
|
||||||
|
void cancelMktData(TickerId id);
|
||||||
|
void placeOrder(OrderId id, const Contract& contract, const Order& order);
|
||||||
|
void cancelOrder(OrderId id) ;
|
||||||
|
void reqOpenOrders();
|
||||||
|
void reqAccountUpdates(bool subscribe, const std::string& acctCode);
|
||||||
|
void reqExecutions(int reqId, const ExecutionFilter& filter);
|
||||||
|
void reqIds(int numIds);
|
||||||
|
void reqContractDetails(int reqId, const Contract& contract);
|
||||||
|
void reqMktDepth(TickerId tickerId, const Contract& contract, int numRows, const TagValueListSPtr& mktDepthOptions);
|
||||||
|
void cancelMktDepth(TickerId tickerId);
|
||||||
|
void reqNewsBulletins(bool allMsgs);
|
||||||
|
void cancelNewsBulletins();
|
||||||
|
void setServerLogLevel(int level);
|
||||||
|
void reqAutoOpenOrders(bool bAutoBind);
|
||||||
|
void reqAllOpenOrders();
|
||||||
|
void reqManagedAccts();
|
||||||
|
void requestFA(faDataType pFaDataType);
|
||||||
|
void replaceFA(faDataType pFaDataType, const std::string& cxml);
|
||||||
|
void reqHistoricalData( TickerId id, const Contract& contract,
|
||||||
|
const std::string& endDateTime, const std::string& durationStr,
|
||||||
|
const std::string& barSizeSetting, const std::string& whatToShow,
|
||||||
|
int useRTH, int formatDate, const TagValueListSPtr& chartOptions);
|
||||||
|
void exerciseOptions(TickerId tickerId, const Contract& contract,
|
||||||
|
int exerciseAction, int exerciseQuantity,
|
||||||
|
const std::string& account, int override);
|
||||||
|
void cancelHistoricalData(TickerId tickerId );
|
||||||
|
void reqRealTimeBars(TickerId id, const Contract& contract, int barSize,
|
||||||
|
const std::string& whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions);
|
||||||
|
void cancelRealTimeBars(TickerId tickerId );
|
||||||
|
void cancelScannerSubscription(int tickerId);
|
||||||
|
void reqScannerParameters();
|
||||||
|
void reqScannerSubscription(int tickerId, const ScannerSubscription& subscription, const TagValueListSPtr& scannerSubscriptionOptions);
|
||||||
|
void reqCurrentTime();
|
||||||
|
void reqFundamentalData(TickerId reqId, const Contract&, const std::string& reportType);
|
||||||
|
void cancelFundamentalData(TickerId reqId);
|
||||||
|
void calculateImpliedVolatility(TickerId reqId, const Contract& contract, double optionPrice, double underPrice);
|
||||||
|
void calculateOptionPrice(TickerId reqId, const Contract& contract, double volatility, double underPrice);
|
||||||
|
void cancelCalculateImpliedVolatility(TickerId reqId);
|
||||||
|
void cancelCalculateOptionPrice(TickerId reqId);
|
||||||
|
void reqGlobalCancel();
|
||||||
|
void reqMarketDataType(int marketDataType);
|
||||||
|
void reqPositions();
|
||||||
|
void cancelPositions();
|
||||||
|
void reqAccountSummary( int reqId, const std::string& groupName, const std::string& tags);
|
||||||
|
void cancelAccountSummary( int reqId);
|
||||||
|
void verifyRequest( const std::string& apiName, const std::string& apiVersion);
|
||||||
|
void verifyMessage( const std::string& apiData);
|
||||||
|
void verifyAndAuthRequest( const std::string& apiName, const std::string& apiVersion, const std::string& opaqueIsvKey);
|
||||||
|
void verifyAndAuthMessage( const std::string& apiData, const std::string& xyzResponse);
|
||||||
|
void queryDisplayGroups( int reqId);
|
||||||
|
void subscribeToGroupEvents( int reqId, int groupId);
|
||||||
|
void updateDisplayGroup( int reqId, const std::string& contractInfo);
|
||||||
|
void unsubscribeFromGroupEvents( int reqId);
|
||||||
|
void reqPositionsMulti( int reqId, const std::string& account, const std::string& modelCode);
|
||||||
|
void cancelPositionsMulti( int reqId);
|
||||||
|
void reqAccountUpdatessMulti( int reqId, const std::string& account, const std::string& modelCode, bool ledgerAndNLV);
|
||||||
|
void cancelAccountUpdatesMulti( int reqId);
|
||||||
|
void reqSecDefOptParams(int reqId, const std::string& underlyingSymbol, const std::string& futFopExchange, const std::string& underlyingSecType, int underlyingConId);
|
||||||
|
void reqSoftDollarTiers(int reqId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual int receive(char* buf, size_t sz) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void prepareBufferImpl(std::ostream&) const = 0;
|
||||||
|
virtual void prepareBuffer(std::ostream&) const = 0;
|
||||||
|
virtual bool closeAndSend(std::string msg, unsigned offset = 0) = 0;
|
||||||
|
virtual int bufferedSend(const std::string& msg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int bufferedRead();
|
||||||
|
|
||||||
|
// try to process connection request ack
|
||||||
|
private:
|
||||||
|
// try to process single msg
|
||||||
|
int processMsgImpl(const char*& ptr, const char* endPtr);
|
||||||
|
int processMsg(const char*& ptr, const char* endPtr);
|
||||||
|
|
||||||
|
typedef int (EClient::*messageHandler)(const char*& ptr, const char* endPtr);
|
||||||
|
int processOnePrefixedMsg(const char*& ptr, const char* endPtr, messageHandler);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void startApi();
|
||||||
|
|
||||||
|
|
||||||
|
// encoders
|
||||||
|
template<class T> static void EncodeField(std::ostream&, T);
|
||||||
|
|
||||||
|
// "max" encoders
|
||||||
|
static void EncodeFieldMax(std::ostream& os, int);
|
||||||
|
static void EncodeFieldMax(std::ostream& os, double);
|
||||||
|
|
||||||
|
// socket state
|
||||||
|
private:
|
||||||
|
virtual bool isSocketOK() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool isConnecting() const;
|
||||||
|
int sendConnectRequest();
|
||||||
|
bool extraAuth();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
EWrapper *m_pEWrapper;
|
||||||
|
std::auto_ptr<ETransport> m_transport;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BytesVec m_inBuffer;
|
||||||
|
|
||||||
|
std::string m_host;
|
||||||
|
int m_port;
|
||||||
|
|
||||||
|
int m_clientId;
|
||||||
|
|
||||||
|
ConnState m_connState;
|
||||||
|
bool m_extraAuth;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_serverVersion;
|
||||||
|
std::string m_TwsTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_optionalCapabilities;
|
||||||
|
|
||||||
|
std::string m_connectOptions;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_useV100Plus;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> void EClient::EncodeField<bool>(std::ostream& os, bool);
|
||||||
|
template<> void EClient::EncodeField<double>(std::ostream& os, double);
|
||||||
|
|
||||||
|
#define ENCODE_FIELD(x) EClient::EncodeField(msg, x);
|
||||||
|
#define ENCODE_FIELD_MAX(x) EClient::EncodeFieldMax(msg, x);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -642,6 +642,16 @@ const char* EDecoder::processOpenOrderMsg(const char* ptr, const char* endPtr) {
|
|||||||
DECODE_FIELD(order.adjustableTrailingUnit);
|
DECODE_FIELD(order.adjustableTrailingUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_serverVersion >= MIN_SERVER_VER_SOFT_DOLLAR_TIER) {
|
||||||
|
std::string name, value, displayName;
|
||||||
|
|
||||||
|
DECODE_FIELD(name);
|
||||||
|
DECODE_FIELD(value);
|
||||||
|
DECODE_FIELD(displayName);
|
||||||
|
|
||||||
|
order.softDollarTier = SoftDollarTier(name, value, displayName);
|
||||||
|
}
|
||||||
|
|
||||||
m_pEWrapper->openOrder( (OrderId)order.orderId, contract, order, orderState);
|
m_pEWrapper->openOrder( (OrderId)order.orderId, contract, order, orderState);
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
@ -1585,7 +1595,7 @@ const char* EDecoder::processAccountUpdateMultiEndMsg(const char* ptr, const cha
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* EDecoder::processSecurityDefinitionOptionalParameter(const char* ptr, const char* endPtr) {
|
const char* EDecoder::processSecurityDefinitionOptionalParameterMsg(const char* ptr, const char* endPtr) {
|
||||||
int reqId;
|
int reqId;
|
||||||
std::string exchange;
|
std::string exchange;
|
||||||
int underlyingConId;
|
int underlyingConId;
|
||||||
@ -1625,7 +1635,7 @@ const char* EDecoder::processSecurityDefinitionOptionalParameter(const char* ptr
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* EDecoder::processSecurityDefinitionOptionalParameterEnd(const char* ptr, const char* endPtr) {
|
const char* EDecoder::processSecurityDefinitionOptionalParameterEndMsg(const char* ptr, const char* endPtr) {
|
||||||
int reqId;
|
int reqId;
|
||||||
|
|
||||||
DECODE_FIELD(reqId);
|
DECODE_FIELD(reqId);
|
||||||
@ -1635,6 +1645,31 @@ const char* EDecoder::processSecurityDefinitionOptionalParameterEnd(const char*
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* EDecoder::processSoftDollarTiersMsg(const char* ptr, const char* endPtr)
|
||||||
|
{
|
||||||
|
int reqId;
|
||||||
|
int nTiers;
|
||||||
|
|
||||||
|
DECODE_FIELD(reqId);
|
||||||
|
DECODE_FIELD(nTiers);
|
||||||
|
|
||||||
|
std::vector<SoftDollarTier> tiers(nTiers);
|
||||||
|
|
||||||
|
for (int i = 0; i < nTiers; i++) {
|
||||||
|
std::string name, value, dislplayName;
|
||||||
|
|
||||||
|
DECODE_FIELD(name);
|
||||||
|
DECODE_FIELD(value);
|
||||||
|
DECODE_FIELD(dislplayName);
|
||||||
|
|
||||||
|
tiers[i] = SoftDollarTier(name, value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pEWrapper->softDollarTiers(reqId, tiers);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int EDecoder::processConnectAck(const char*& beginPtr, const char* endPtr)
|
int EDecoder::processConnectAck(const char*& beginPtr, const char* endPtr)
|
||||||
{
|
{
|
||||||
@ -1910,11 +1945,15 @@ int EDecoder::parseAndProcessMsg(const char*& beginPtr, const char* endPtr) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SECURITY_DEFINITION_OPTION_PARAMETER:
|
case SECURITY_DEFINITION_OPTION_PARAMETER:
|
||||||
ptr = processSecurityDefinitionOptionalParameter(ptr, endPtr);
|
ptr = processSecurityDefinitionOptionalParameterMsg(ptr, endPtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECURITY_DEFINITION_OPTION_PARAMETER_END:
|
case SECURITY_DEFINITION_OPTION_PARAMETER_END:
|
||||||
ptr = processSecurityDefinitionOptionalParameterEnd(ptr, endPtr);
|
ptr = processSecurityDefinitionOptionalParameterEndMsg(ptr, endPtr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOFT_DOLLAR_TIERS:
|
||||||
|
ptr = processSoftDollarTiersMsg(ptr, endPtr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
@ -55,12 +55,13 @@ const int MIN_SERVER_VER_PEGGED_TO_BENCHMARK = 102;
|
|||||||
const int MIN_SERVER_VER_MODELS_SUPPORT = 103;
|
const int MIN_SERVER_VER_MODELS_SUPPORT = 103;
|
||||||
const int MIN_SERVER_VER_SEC_DEF_OPT_PARAMS_REQ = 104;
|
const int MIN_SERVER_VER_SEC_DEF_OPT_PARAMS_REQ = 104;
|
||||||
const int MIN_SERVER_VER_EXT_OPERATOR = 105;
|
const int MIN_SERVER_VER_EXT_OPERATOR = 105;
|
||||||
|
const int MIN_SERVER_VER_SOFT_DOLLAR_TIER = 106;
|
||||||
|
|
||||||
/* 100+ messaging */
|
/* 100+ messaging */
|
||||||
// 100 = enhanced handshake, msg length prefixes
|
// 100 = enhanced handshake, msg length prefixes
|
||||||
|
|
||||||
const int MIN_CLIENT_VER = 100;
|
const int MIN_CLIENT_VER = 100;
|
||||||
const int MAX_CLIENT_VER = MIN_SERVER_VER_EXT_OPERATOR;
|
const int MAX_CLIENT_VER = MIN_SERVER_VER_SOFT_DOLLAR_TIER;
|
||||||
|
|
||||||
|
|
||||||
// incoming msg id's
|
// incoming msg id's
|
||||||
@ -115,6 +116,7 @@ const int ACCOUNT_UPDATE_MULTI = 73;
|
|||||||
const int ACCOUNT_UPDATE_MULTI_END = 74;
|
const int ACCOUNT_UPDATE_MULTI_END = 74;
|
||||||
const int SECURITY_DEFINITION_OPTION_PARAMETER = 75;
|
const int SECURITY_DEFINITION_OPTION_PARAMETER = 75;
|
||||||
const int SECURITY_DEFINITION_OPTION_PARAMETER_END = 76;
|
const int SECURITY_DEFINITION_OPTION_PARAMETER_END = 76;
|
||||||
|
const int SOFT_DOLLAR_TIERS = 77;
|
||||||
|
|
||||||
const int HEADER_LEN = 4; // 4 bytes for msg length
|
const int HEADER_LEN = 4; // 4 bytes for msg length
|
||||||
const int MAX_MSG_LEN = 0xFFFFFF; // 16Mb - 1byte
|
const int MAX_MSG_LEN = 0xFFFFFF; // 16Mb - 1byte
|
||||||
@ -213,8 +215,9 @@ class TWSAPIDLLEXP EDecoder
|
|||||||
const char* processPositionMultiEndMsg(const char* ptr, const char* endPtr);
|
const char* processPositionMultiEndMsg(const char* ptr, const char* endPtr);
|
||||||
const char* processAccountUpdateMultiMsg(const char* ptr, const char* endPtr);
|
const char* processAccountUpdateMultiMsg(const char* ptr, const char* endPtr);
|
||||||
const char* processAccountUpdateMultiEndMsg(const char* ptr, const char* endPtr);
|
const char* processAccountUpdateMultiEndMsg(const char* ptr, const char* endPtr);
|
||||||
const char* processSecurityDefinitionOptionalParameter(const char* ptr, const char* endPtr);
|
const char* processSecurityDefinitionOptionalParameterMsg(const char* ptr, const char* endPtr);
|
||||||
const char* processSecurityDefinitionOptionalParameterEnd(const char* ptr, const char* endPtr);
|
const char* processSecurityDefinitionOptionalParameterEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processSoftDollarTiersMsg(const char* ptr, const char* endPtr);
|
||||||
|
|
||||||
int processConnectAck(const char*& beginPtr, const char* endPtr);
|
int processConnectAck(const char*& beginPtr, const char* endPtr);
|
||||||
|
|
@ -178,13 +178,20 @@ void EReader::onReceive() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EReader::bufferedRead(char *buf, int size) {
|
bool EReader::bufferedRead(char *buf, int size) {
|
||||||
while (m_buf.size() < size)
|
while (size > 0) {
|
||||||
|
while (m_buf.size() < size && m_buf.size() < m_nMaxBufSize)
|
||||||
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
|
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::copy(m_buf.begin(), m_buf.begin() + size, buf);
|
int nBytes = min(m_nMaxBufSize, size);
|
||||||
std::copy(m_buf.begin() + size, m_buf.end(), m_buf.begin());
|
|
||||||
m_buf.resize(m_buf.size() - size);
|
std::copy(m_buf.begin(), m_buf.begin() + nBytes, buf);
|
||||||
|
std::copy(m_buf.begin() + nBytes, m_buf.end(), m_buf.begin());
|
||||||
|
m_buf.resize(m_buf.size() - nBytes);
|
||||||
|
|
||||||
|
size -= nBytes;
|
||||||
|
buf += nBytes;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "EReaderSignal.h"
|
#include "EReaderSignal.h"
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#if !defined(INFINITE)
|
#if !defined(INFINITE)
|
||||||
#define INFINITE ((unsigned long)-1)
|
#define INFINITE ((unsigned long)-1)
|
@ -6,6 +6,7 @@
|
|||||||
#define ewrapper_def
|
#define ewrapper_def
|
||||||
|
|
||||||
#include "CommonDefs.h"
|
#include "CommonDefs.h"
|
||||||
|
#include "SoftDollarTier.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@ -78,6 +79,9 @@ enum TickType { BID_SIZE, BID, ASK, ASK_SIZE, LAST, LAST_SIZE,
|
|||||||
DELAYED_VOLUME,
|
DELAYED_VOLUME,
|
||||||
DELAYED_CLOSE,
|
DELAYED_CLOSE,
|
||||||
DELAYED_OPEN,
|
DELAYED_OPEN,
|
||||||
|
RT_TRD_VOLUME,
|
||||||
|
CREDITMAN_MARK_PRICE,
|
||||||
|
CREDITMAN_SLOW_MARK_PRICE,
|
||||||
NOT_SET };
|
NOT_SET };
|
||||||
|
|
||||||
inline bool isPrice( TickType tickType) {
|
inline bool isPrice( TickType tickType) {
|
||||||
@ -165,6 +169,7 @@ public:
|
|||||||
virtual void accountUpdateMultiEnd( int reqId) = 0;
|
virtual void accountUpdateMultiEnd( int reqId) = 0;
|
||||||
virtual void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes) = 0;
|
virtual void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes) = 0;
|
||||||
virtual void securityDefinitionOptionalParameterEnd(int reqId) = 0;
|
virtual void securityDefinitionOptionalParameterEnd(int reqId) = 0;
|
||||||
|
virtual void softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "TagValue.h"
|
#include "TagValue.h"
|
||||||
#include "OrderCondition.h"
|
#include "OrderCondition.h"
|
||||||
|
#include "SoftDollarTier.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@ -42,7 +43,8 @@ typedef ibapi::shared_ptr<OrderComboLeg> OrderComboLegSPtr;
|
|||||||
|
|
||||||
struct Order
|
struct Order
|
||||||
{
|
{
|
||||||
Order()
|
Order() :
|
||||||
|
softDollarTier("", "", "")
|
||||||
{
|
{
|
||||||
// order identifier
|
// order identifier
|
||||||
orderId = 0;
|
orderId = 0;
|
||||||
@ -307,6 +309,8 @@ struct Order
|
|||||||
// ext operator
|
// ext operator
|
||||||
std::string extOperator;
|
std::string extOperator;
|
||||||
|
|
||||||
|
SoftDollarTier softDollarTier;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
22
vn.ib/ibapi/linux/client/SoftDollarTier.cpp
Normal file
22
vn.ib/ibapi/linux/client/SoftDollarTier.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "SoftDollarTier.h"
|
||||||
|
|
||||||
|
SoftDollarTier::SoftDollarTier(const std::string& name, const std::string& val, const std::string& displayName) :
|
||||||
|
m_name(name), m_val(val), m_displayName(displayName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SoftDollarTier::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SoftDollarTier::val() const
|
||||||
|
{
|
||||||
|
return m_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SoftDollarTier::displayName() const
|
||||||
|
{
|
||||||
|
return m_displayName;
|
||||||
|
}
|
14
vn.ib/ibapi/linux/client/SoftDollarTier.h
Normal file
14
vn.ib/ibapi/linux/client/SoftDollarTier.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP SoftDollarTier
|
||||||
|
{
|
||||||
|
std::string m_name, m_val, m_displayName;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SoftDollarTier(const std::string& name = "", const std::string& val = "", const std::string& displayName = "");
|
||||||
|
|
||||||
|
std::string name() const;
|
||||||
|
std::string val() const;
|
||||||
|
std::string displayName() const;
|
||||||
|
};
|
||||||
|
|
106
vn.ib/ibapi/linux/client/shared_ptr.h
Normal file
106
vn.ib/ibapi/linux/client/shared_ptr.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef shared_ptr_h_INCLUDED
|
||||||
|
#define shared_ptr_h_INCLUDED
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implements a subset of shared_prt found at www.boost.org.
|
||||||
|
// Uses a singly linked circular list instead of a reference counter.
|
||||||
|
// Avoids extra heap allocation needed to get a shared reference counter,
|
||||||
|
// but sizeof(shared_ptr) == sizeof(void*) * 3 compared to sizeof(void*) * 2
|
||||||
|
//
|
||||||
|
// See "Handles and Exception Safety, Part 4: Tracking References without Counters"
|
||||||
|
// by Andrew Koenig and Barbara E. Moo, Feb. 2003 C++ Users Journal
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace ibapi {
|
||||||
|
|
||||||
|
namespace shared_ptr_defs {
|
||||||
|
|
||||||
|
class Use {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Use() { forward_ = this; back_ = this; }
|
||||||
|
~Use() { remove(); }
|
||||||
|
|
||||||
|
Use(const Use& u) { insert(u); }
|
||||||
|
Use& operator=(const Use& u)
|
||||||
|
{
|
||||||
|
if (this != &u) {
|
||||||
|
remove();
|
||||||
|
insert(u);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool only() const { return this == this->forward_; }
|
||||||
|
private:
|
||||||
|
mutable const Use *forward_;
|
||||||
|
mutable const Use *back_;
|
||||||
|
|
||||||
|
void insert(const Use& u) const {
|
||||||
|
this->back_ = &u;
|
||||||
|
this->forward_ = u.forward_;
|
||||||
|
u.forward_->back_ = this;
|
||||||
|
u.forward_ = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove() const {
|
||||||
|
this->forward_->back_ = this->back_;
|
||||||
|
this->back_->forward_ = this->forward_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace shared_ptr_defs
|
||||||
|
|
||||||
|
template<typename X> class shared_ptr {
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef shared_ptr_defs::Use Use;
|
||||||
|
|
||||||
|
template<typename Y> friend class shared_ptr;
|
||||||
|
|
||||||
|
explicit shared_ptr(X* ptr = 0) : ptr_(ptr) {}
|
||||||
|
|
||||||
|
~shared_ptr() { if (use_.only()) delete ptr_; }
|
||||||
|
|
||||||
|
template<typename Y>
|
||||||
|
shared_ptr(const shared_ptr<Y>& other)
|
||||||
|
: ptr_(other.ptr_),
|
||||||
|
use_(other.use_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
shared_ptr& operator=(const shared_ptr& other) {
|
||||||
|
if ( &use_ == &other.use_ ) { return *this; }
|
||||||
|
if ( use_.only() ) { delete ptr_; }
|
||||||
|
use_ = other.use_;
|
||||||
|
ptr_ = other.ptr_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
X& operator*() const { return *ptr_; }
|
||||||
|
X* operator->() const { return ptr_; }
|
||||||
|
X* get() const { return ptr_; }
|
||||||
|
bool only() const { return use_.only(); }
|
||||||
|
|
||||||
|
void reset(X* ptr = 0) {
|
||||||
|
if ( use_.only() ) { delete ptr_; }
|
||||||
|
ptr_ = ptr;
|
||||||
|
use_ = Use();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
X *ptr_;
|
||||||
|
Use use_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} //end of namespace ibapi
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
//#include <memory>
|
||||||
|
//using std::shared_ptr;
|
||||||
|
#endif /* shared_ptr_h_INCLUDED */
|
27
vn.ib/ibapi/windows/client/CommissionReport.h
Normal file
27
vn.ib/ibapi/windows/client/CommissionReport.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef commissionreport_def
|
||||||
|
#define commissionreport_def
|
||||||
|
|
||||||
|
struct CommissionReport
|
||||||
|
{
|
||||||
|
CommissionReport()
|
||||||
|
{
|
||||||
|
commission = 0;
|
||||||
|
realizedPNL = 0;
|
||||||
|
yield = 0;
|
||||||
|
yieldRedemptionDate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// commission report fields
|
||||||
|
std::string execId;
|
||||||
|
double commission;
|
||||||
|
std::string currency;
|
||||||
|
double realizedPNL;
|
||||||
|
double yield;
|
||||||
|
int yieldRedemptionDate; // YYYYMMDD format
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // commissionreport_def
|
33
vn.ib/ibapi/windows/client/CommonDefs.h
Normal file
33
vn.ib/ibapi/windows/client/CommonDefs.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef common_defs_h_INCLUDED
|
||||||
|
#define common_defs_h_INCLUDED
|
||||||
|
|
||||||
|
typedef long TickerId;
|
||||||
|
typedef long OrderId;
|
||||||
|
|
||||||
|
enum faDataType { GROUPS=1, PROFILES, ALIASES } ;
|
||||||
|
|
||||||
|
inline const char* faDataTypeStr ( faDataType pFaDataType )
|
||||||
|
{
|
||||||
|
switch (pFaDataType) {
|
||||||
|
case GROUPS:
|
||||||
|
return "GROUPS";
|
||||||
|
case PROFILES:
|
||||||
|
return "PROFILES";
|
||||||
|
case ALIASES:
|
||||||
|
return "ALIASES";
|
||||||
|
}
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MarketDataType {
|
||||||
|
REALTIME = 1,
|
||||||
|
FROZEN = 2,
|
||||||
|
DELAYED = 3,
|
||||||
|
DELAYED_FROZEN = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* common_defs_h_INCLUDED */
|
187
vn.ib/ibapi/windows/client/Contract.h
Normal file
187
vn.ib/ibapi/windows/client/Contract.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef contract_def
|
||||||
|
#define contract_def
|
||||||
|
|
||||||
|
#include "TagValue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
SAME_POS = open/close leg value is same as combo
|
||||||
|
OPEN_POS = open
|
||||||
|
CLOSE_POS = close
|
||||||
|
UNKNOWN_POS = unknown
|
||||||
|
*/
|
||||||
|
enum LegOpenClose { SAME_POS, OPEN_POS, CLOSE_POS, UNKNOWN_POS };
|
||||||
|
|
||||||
|
struct ComboLeg
|
||||||
|
{
|
||||||
|
ComboLeg()
|
||||||
|
: conId(0)
|
||||||
|
, ratio(0)
|
||||||
|
, openClose(0)
|
||||||
|
, shortSaleSlot(0)
|
||||||
|
, exemptCode(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
long conId;
|
||||||
|
long ratio;
|
||||||
|
std::string action; //BUY/SELL/SSHORT
|
||||||
|
|
||||||
|
std::string exchange;
|
||||||
|
long openClose; // LegOpenClose enum values
|
||||||
|
|
||||||
|
// for stock legs when doing short sale
|
||||||
|
long shortSaleSlot; // 1 = clearing broker, 2 = third party
|
||||||
|
std::string designatedLocation;
|
||||||
|
int exemptCode;
|
||||||
|
|
||||||
|
bool operator==( const ComboLeg& other) const
|
||||||
|
{
|
||||||
|
return (conId == other.conId &&
|
||||||
|
ratio == other.ratio &&
|
||||||
|
openClose == other.openClose &&
|
||||||
|
shortSaleSlot == other.shortSaleSlot &&
|
||||||
|
exemptCode == other.exemptCode &&
|
||||||
|
action == other.action &&
|
||||||
|
exchange == other.exchange &&
|
||||||
|
designatedLocation == other.designatedLocation);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UnderComp
|
||||||
|
{
|
||||||
|
UnderComp()
|
||||||
|
: conId(0)
|
||||||
|
, delta(0)
|
||||||
|
, price(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
long conId;
|
||||||
|
double delta;
|
||||||
|
double price;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ibapi::shared_ptr<ComboLeg> ComboLegSPtr;
|
||||||
|
|
||||||
|
struct Contract
|
||||||
|
{
|
||||||
|
Contract()
|
||||||
|
: conId(0)
|
||||||
|
, strike(0)
|
||||||
|
, includeExpired(false)
|
||||||
|
, comboLegs(NULL)
|
||||||
|
, underComp(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
long conId;
|
||||||
|
std::string symbol;
|
||||||
|
std::string secType;
|
||||||
|
std::string lastTradeDateOrContractMonth;
|
||||||
|
double strike;
|
||||||
|
std::string right;
|
||||||
|
std::string multiplier;
|
||||||
|
std::string exchange;
|
||||||
|
std::string primaryExchange; // pick an actual (ie non-aggregate) exchange that the contract trades on. DO NOT SET TO SMART.
|
||||||
|
std::string currency;
|
||||||
|
std::string localSymbol;
|
||||||
|
std::string tradingClass;
|
||||||
|
bool includeExpired;
|
||||||
|
std::string secIdType; // CUSIP;SEDOL;ISIN;RIC
|
||||||
|
std::string secId;
|
||||||
|
|
||||||
|
// COMBOS
|
||||||
|
std::string comboLegsDescrip; // received in open order 14 and up for all combos
|
||||||
|
|
||||||
|
// combo legs
|
||||||
|
typedef std::vector<ComboLegSPtr> ComboLegList;
|
||||||
|
typedef ibapi::shared_ptr<ComboLegList> ComboLegListSPtr;
|
||||||
|
|
||||||
|
ComboLegListSPtr comboLegs;
|
||||||
|
|
||||||
|
// delta neutral
|
||||||
|
UnderComp* underComp;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
static void CloneComboLegs(ComboLegListSPtr& dst, const ComboLegListSPtr& src);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ContractDetails
|
||||||
|
{
|
||||||
|
ContractDetails()
|
||||||
|
: minTick(0)
|
||||||
|
, priceMagnifier(0)
|
||||||
|
, underConId(0)
|
||||||
|
, evMultiplier(0)
|
||||||
|
, callable(false)
|
||||||
|
, putable(false)
|
||||||
|
, coupon(0)
|
||||||
|
, convertible(false)
|
||||||
|
, nextOptionPartial(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Contract summary;
|
||||||
|
std::string marketName;
|
||||||
|
double minTick;
|
||||||
|
std::string orderTypes;
|
||||||
|
std::string validExchanges;
|
||||||
|
long priceMagnifier;
|
||||||
|
int underConId;
|
||||||
|
std::string longName;
|
||||||
|
std::string contractMonth;
|
||||||
|
std::string industry;
|
||||||
|
std::string category;
|
||||||
|
std::string subcategory;
|
||||||
|
std::string timeZoneId;
|
||||||
|
std::string tradingHours;
|
||||||
|
std::string liquidHours;
|
||||||
|
std::string evRule;
|
||||||
|
double evMultiplier;
|
||||||
|
|
||||||
|
TagValueListSPtr secIdList;
|
||||||
|
|
||||||
|
// BOND values
|
||||||
|
std::string cusip;
|
||||||
|
std::string ratings;
|
||||||
|
std::string descAppend;
|
||||||
|
std::string bondType;
|
||||||
|
std::string couponType;
|
||||||
|
bool callable;
|
||||||
|
bool putable;
|
||||||
|
double coupon;
|
||||||
|
bool convertible;
|
||||||
|
std::string maturity;
|
||||||
|
std::string issueDate;
|
||||||
|
std::string nextOptionDate;
|
||||||
|
std::string nextOptionType;
|
||||||
|
bool nextOptionPartial;
|
||||||
|
std::string notes;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Contract::CloneComboLegs(ComboLegListSPtr& dst, const ComboLegListSPtr& src)
|
||||||
|
{
|
||||||
|
if (!src.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst->reserve(src->size());
|
||||||
|
|
||||||
|
ComboLegList::const_iterator iter = src->begin();
|
||||||
|
const ComboLegList::const_iterator iterEnd = src->end();
|
||||||
|
|
||||||
|
for (; iter != iterEnd; ++iter) {
|
||||||
|
const ComboLeg* leg = iter->get();
|
||||||
|
if (!leg)
|
||||||
|
continue;
|
||||||
|
dst->push_back(ComboLegSPtr(new ComboLeg(*leg)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
43
vn.ib/ibapi/windows/client/ContractCondition.cpp
Normal file
43
vn.ib/ibapi/windows/client/ContractCondition.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "ContractCondition.h"
|
||||||
|
#include "EDecoder.h"
|
||||||
|
#include "EClient.h"
|
||||||
|
|
||||||
|
std::string ContractCondition::toString() {
|
||||||
|
std::string strContract = conId() + "";
|
||||||
|
|
||||||
|
return type() + " of " + strContract + OperatorCondition::toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ContractCondition::readExternal(const char* ptr, const char* endPtr) {
|
||||||
|
if (!(ptr = OperatorCondition::readExternal(ptr, endPtr)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DECODE_FIELD(m_conId);
|
||||||
|
DECODE_FIELD(m_exchange);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContractCondition::writeExternal(std::ostream & msg) const {
|
||||||
|
OperatorCondition::writeExternal(msg);
|
||||||
|
|
||||||
|
ENCODE_FIELD(m_conId);
|
||||||
|
ENCODE_FIELD(m_exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ContractCondition::conId() {
|
||||||
|
return m_conId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContractCondition::conId(int conId) {
|
||||||
|
m_conId = conId;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ContractCondition::exchange() {
|
||||||
|
return m_exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContractCondition::exchange(const std::string & exchange) {
|
||||||
|
m_exchange = exchange;
|
||||||
|
}
|
17
vn.ib/ibapi/windows/client/ContractCondition.h
Normal file
17
vn.ib/ibapi/windows/client/ContractCondition.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "OperatorCondition.h"
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP ContractCondition : public OperatorCondition {
|
||||||
|
int m_conId;
|
||||||
|
std::string m_exchange;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual std::string toString();
|
||||||
|
virtual const char* readExternal(const char* ptr, const char* endPtr);
|
||||||
|
virtual void writeExternal(std::ostream &out) const;
|
||||||
|
|
||||||
|
int conId();
|
||||||
|
void conId(int conId);
|
||||||
|
std::string exchange();
|
||||||
|
void exchange(const std::string &exchange);
|
||||||
|
};
|
77
vn.ib/ibapi/windows/client/DefaultEWrapper.cpp
Normal file
77
vn.ib/ibapi/windows/client/DefaultEWrapper.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "DefaultEWrapper.h"
|
||||||
|
|
||||||
|
void DefaultEWrapper::tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) { }
|
||||||
|
void DefaultEWrapper::tickSize( TickerId tickerId, TickType field, int size) { }
|
||||||
|
void DefaultEWrapper::tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta,
|
||||||
|
double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) { }
|
||||||
|
void DefaultEWrapper::tickGeneric(TickerId tickerId, TickType tickType, double value) { }
|
||||||
|
void DefaultEWrapper::tickString(TickerId tickerId, TickType tickType, const std::string& value) { }
|
||||||
|
void DefaultEWrapper::tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const std::string& formattedBasisPoints,
|
||||||
|
double totalDividends, int holdDays, const std::string& futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate) { }
|
||||||
|
void DefaultEWrapper::orderStatus( OrderId orderId, const std::string& status, double filled,
|
||||||
|
double remaining, double avgFillPrice, int permId, int parentId,
|
||||||
|
double lastFillPrice, int clientId, const std::string& whyHeld) { }
|
||||||
|
void DefaultEWrapper::openOrder( OrderId orderId, const Contract&, const Order&, const OrderState&) { }
|
||||||
|
void DefaultEWrapper::openOrderEnd() { }
|
||||||
|
void DefaultEWrapper::winError( const std::string& str, int lastError) { }
|
||||||
|
void DefaultEWrapper::connectionClosed() { }
|
||||||
|
void DefaultEWrapper::updateAccountValue(const std::string& key, const std::string& val,
|
||||||
|
const std::string& currency, const std::string& accountName) { }
|
||||||
|
void DefaultEWrapper::updatePortfolio( const Contract& contract, double position,
|
||||||
|
double marketPrice, double marketValue, double averageCost,
|
||||||
|
double unrealizedPNL, double realizedPNL, const std::string& accountName) { }
|
||||||
|
void DefaultEWrapper::updateAccountTime(const std::string& timeStamp) { }
|
||||||
|
void DefaultEWrapper::accountDownloadEnd(const std::string& accountName) { }
|
||||||
|
void DefaultEWrapper::nextValidId( OrderId orderId) { }
|
||||||
|
void DefaultEWrapper::contractDetails( int reqId, const ContractDetails& contractDetails) { }
|
||||||
|
void DefaultEWrapper::bondContractDetails( int reqId, const ContractDetails& contractDetails) { }
|
||||||
|
void DefaultEWrapper::contractDetailsEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::execDetails( int reqId, const Contract& contract, const Execution& execution) { }
|
||||||
|
void DefaultEWrapper::execDetailsEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::error(const int id, const int errorCode, const std::string errorString) { }
|
||||||
|
void DefaultEWrapper::updateMktDepth(TickerId id, int position, int operation, int side,
|
||||||
|
double price, int size) { }
|
||||||
|
void DefaultEWrapper::updateMktDepthL2(TickerId id, int position, std::string marketMaker, int operation,
|
||||||
|
int side, double price, int size) { }
|
||||||
|
void DefaultEWrapper::updateNewsBulletin(int msgId, int msgType, const std::string& newsMessage, const std::string& originExch) { }
|
||||||
|
void DefaultEWrapper::managedAccounts( const std::string& accountsList) { }
|
||||||
|
void DefaultEWrapper::receiveFA(faDataType pFaDataType, const std::string& cxml) { }
|
||||||
|
void DefaultEWrapper::historicalData(TickerId reqId, const std::string& date, double open, double high,
|
||||||
|
double low, double close, int volume, int barCount, double WAP, int hasGaps) { }
|
||||||
|
void DefaultEWrapper::scannerParameters(const std::string& xml) { }
|
||||||
|
void DefaultEWrapper::scannerData(int reqId, int rank, const ContractDetails& contractDetails,
|
||||||
|
const std::string& distance, const std::string& benchmark, const std::string& projection,
|
||||||
|
const std::string& legsStr) { }
|
||||||
|
void DefaultEWrapper::scannerDataEnd(int reqId) { }
|
||||||
|
void DefaultEWrapper::realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
|
||||||
|
long volume, double wap, int count) { }
|
||||||
|
void DefaultEWrapper::currentTime(long time) { }
|
||||||
|
void DefaultEWrapper::fundamentalData(TickerId reqId, const std::string& data) { }
|
||||||
|
void DefaultEWrapper::deltaNeutralValidation(int reqId, const UnderComp& underComp) { }
|
||||||
|
void DefaultEWrapper::tickSnapshotEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::marketDataType( TickerId reqId, int marketDataType) { }
|
||||||
|
void DefaultEWrapper::commissionReport( const CommissionReport& commissionReport) { }
|
||||||
|
void DefaultEWrapper::position( const std::string& account, const Contract& contract, double position, double avgCost) { }
|
||||||
|
void DefaultEWrapper::positionEnd() { }
|
||||||
|
void DefaultEWrapper::accountSummary( int reqId, const std::string& account, const std::string& tag, const std::string& value, const std::string& curency) { }
|
||||||
|
void DefaultEWrapper::accountSummaryEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::verifyMessageAPI( const std::string& apiData) { }
|
||||||
|
void DefaultEWrapper::verifyCompleted( bool isSuccessful, const std::string& errorText) { }
|
||||||
|
void DefaultEWrapper::displayGroupList( int reqId, const std::string& groups) { }
|
||||||
|
void DefaultEWrapper::displayGroupUpdated( int reqId, const std::string& contractInfo) { }
|
||||||
|
void DefaultEWrapper::verifyAndAuthMessageAPI( const std::string& apiData, const std::string& xyzChallange) { }
|
||||||
|
void DefaultEWrapper::verifyAndAuthCompleted( bool isSuccessful, const std::string& errorText) { }
|
||||||
|
void DefaultEWrapper::connectAck() { }
|
||||||
|
void DefaultEWrapper::positionMulti( int reqId, const std::string& account,const std::string& modelCode, const Contract& contract, double pos, double avgCost) { }
|
||||||
|
void DefaultEWrapper::positionMultiEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::accountUpdateMulti( int reqId, const std::string& account, const std::string& modelCode, const std::string& key, const std::string& value, const std::string& currency) { }
|
||||||
|
void DefaultEWrapper::accountUpdateMultiEnd( int reqId) { }
|
||||||
|
void DefaultEWrapper::securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes) { }
|
||||||
|
void DefaultEWrapper::securityDefinitionOptionalParameterEnd(int reqId) { }
|
||||||
|
void DefaultEWrapper::softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers) { }
|
||||||
|
|
||||||
|
|
81
vn.ib/ibapi/windows/client/DefaultEWrapper.h
Normal file
81
vn.ib/ibapi/windows/client/DefaultEWrapper.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "EWrapper.h"
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP DefaultEWrapper :
|
||||||
|
public EWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute);
|
||||||
|
virtual void tickSize( TickerId tickerId, TickType field, int size);
|
||||||
|
virtual void tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta,
|
||||||
|
double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice);
|
||||||
|
virtual void tickGeneric(TickerId tickerId, TickType tickType, double value);
|
||||||
|
virtual void tickString(TickerId tickerId, TickType tickType, const std::string& value);
|
||||||
|
virtual void tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const std::string& formattedBasisPoints,
|
||||||
|
double totalDividends, int holdDays, const std::string& futureLastTradeDate, double dividendImpact, double dividendsToLastTradeDate);
|
||||||
|
virtual void orderStatus( OrderId orderId, const std::string& status, double filled,
|
||||||
|
double remaining, double avgFillPrice, int permId, int parentId,
|
||||||
|
double lastFillPrice, int clientId, const std::string& whyHeld);
|
||||||
|
virtual void openOrder( OrderId orderId, const Contract&, const Order&, const OrderState&);
|
||||||
|
virtual void openOrderEnd();
|
||||||
|
virtual void winError( const std::string& str, int lastError);
|
||||||
|
virtual void connectionClosed();
|
||||||
|
virtual void updateAccountValue(const std::string& key, const std::string& val,
|
||||||
|
const std::string& currency, const std::string& accountName);
|
||||||
|
virtual void updatePortfolio( const Contract& contract, double position,
|
||||||
|
double marketPrice, double marketValue, double averageCost,
|
||||||
|
double unrealizedPNL, double realizedPNL, const std::string& accountName);
|
||||||
|
virtual void updateAccountTime(const std::string& timeStamp);
|
||||||
|
virtual void accountDownloadEnd(const std::string& accountName);
|
||||||
|
virtual void nextValidId( OrderId orderId);
|
||||||
|
virtual void contractDetails( int reqId, const ContractDetails& contractDetails);
|
||||||
|
virtual void bondContractDetails( int reqId, const ContractDetails& contractDetails);
|
||||||
|
virtual void contractDetailsEnd( int reqId);
|
||||||
|
virtual void execDetails( int reqId, const Contract& contract, const Execution& execution);
|
||||||
|
virtual void execDetailsEnd( int reqId);
|
||||||
|
virtual void error(const int id, const int errorCode, const std::string errorString);
|
||||||
|
virtual void updateMktDepth(TickerId id, int position, int operation, int side,
|
||||||
|
double price, int size);
|
||||||
|
virtual void updateMktDepthL2(TickerId id, int position, std::string marketMaker, int operation,
|
||||||
|
int side, double price, int size);
|
||||||
|
virtual void updateNewsBulletin(int msgId, int msgType, const std::string& newsMessage, const std::string& originExch);
|
||||||
|
virtual void managedAccounts( const std::string& accountsList);
|
||||||
|
virtual void receiveFA(faDataType pFaDataType, const std::string& cxml);
|
||||||
|
virtual void historicalData(TickerId reqId, const std::string& date, double open, double high,
|
||||||
|
double low, double close, int volume, int barCount, double WAP, int hasGaps);
|
||||||
|
virtual void scannerParameters(const std::string& xml);
|
||||||
|
virtual void scannerData(int reqId, int rank, const ContractDetails& contractDetails,
|
||||||
|
const std::string& distance, const std::string& benchmark, const std::string& projection,
|
||||||
|
const std::string& legsStr);
|
||||||
|
virtual void scannerDataEnd(int reqId);
|
||||||
|
virtual void realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
|
||||||
|
long volume, double wap, int count);
|
||||||
|
virtual void currentTime(long time);
|
||||||
|
virtual void fundamentalData(TickerId reqId, const std::string& data);
|
||||||
|
virtual void deltaNeutralValidation(int reqId, const UnderComp& underComp);
|
||||||
|
virtual void tickSnapshotEnd( int reqId);
|
||||||
|
virtual void marketDataType( TickerId reqId, int marketDataType);
|
||||||
|
virtual void commissionReport( const CommissionReport& commissionReport);
|
||||||
|
virtual void position( const std::string& account, const Contract& contract, double position, double avgCost);
|
||||||
|
virtual void positionEnd();
|
||||||
|
virtual void accountSummary( int reqId, const std::string& account, const std::string& tag, const std::string& value, const std::string& curency);
|
||||||
|
virtual void accountSummaryEnd( int reqId);
|
||||||
|
virtual void verifyMessageAPI( const std::string& apiData);
|
||||||
|
virtual void verifyCompleted( bool isSuccessful, const std::string& errorText);
|
||||||
|
virtual void displayGroupList( int reqId, const std::string& groups);
|
||||||
|
virtual void displayGroupUpdated( int reqId, const std::string& contractInfo);
|
||||||
|
virtual void verifyAndAuthMessageAPI( const std::string& apiData, const std::string& xyzChallange);
|
||||||
|
virtual void verifyAndAuthCompleted( bool isSuccessful, const std::string& errorText);
|
||||||
|
virtual void connectAck();
|
||||||
|
virtual void positionMulti( int reqId, const std::string& account,const std::string& modelCode, const Contract& contract, double pos, double avgCost);
|
||||||
|
virtual void positionMultiEnd( int reqId);
|
||||||
|
virtual void accountUpdateMulti( int reqId, const std::string& account, const std::string& modelCode, const std::string& key, const std::string& value, const std::string& currency);
|
||||||
|
virtual void accountUpdateMultiEnd( int reqId);
|
||||||
|
virtual void securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass, const std::string& multiplier, std::set<std::string> expirations, std::set<double> strikes);
|
||||||
|
virtual void securityDefinitionOptionalParameterEnd(int reqId);
|
||||||
|
virtual void softDollarTiers(int reqId, const std::vector<SoftDollarTier> &tiers);
|
||||||
|
};
|
||||||
|
|
2840
vn.ib/ibapi/windows/client/EClient.cpp
Normal file
2840
vn.ib/ibapi/windows/client/EClient.cpp
Normal file
File diff suppressed because it is too large
Load Diff
384
vn.ib/ibapi/windows/client/EClient.h
Normal file
384
vn.ib/ibapi/windows/client/EClient.h
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef eclient_h__INCLUDED
|
||||||
|
#define eclient_h__INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include "CommonDefs.h"
|
||||||
|
#include "TagValue.h"
|
||||||
|
|
||||||
|
namespace ibapi {
|
||||||
|
namespace client_constants {
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SOCKET CLIENT VERSION CHANGE LOG : Incremented when the format of incomming
|
||||||
|
// server responses change
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// constants
|
||||||
|
// 6 = Added parentId to orderStatus
|
||||||
|
// 7 = The new execDetails event returned for an order filled status and reqExecDetails
|
||||||
|
// Also added market depth support.
|
||||||
|
// 8 = Added 'lastFillPrice' to orderStatus and 'permId' to execDetails
|
||||||
|
// 9 = Added 'avgCost', 'unrealizedPNL', and 'unrealizedPNL' to updatePortfolio event
|
||||||
|
// 10 = Added 'serverId' to the 'open order' & 'order status' events.
|
||||||
|
// We send back all the API open orders upon connection.
|
||||||
|
// Added new methods reqAllOpenOrders, reqAutoOpenOrders()
|
||||||
|
// Added FA support - reqExecution has filter.
|
||||||
|
// - reqAccountUpdates takes acct code.
|
||||||
|
// 11 = Added permId to openOrder event.
|
||||||
|
// 12 = Added IgnoreRth, hidden, and discretionaryAmt
|
||||||
|
// 13 = Added GoodAfterTime
|
||||||
|
// 14 = always send size on bid/ask/last tick
|
||||||
|
// 15 = send allocation string with open order
|
||||||
|
// 16 = can receive account name in account and portfolio updates, and fa params in openOrder
|
||||||
|
// 17 = can receive liquidation field in exec reports, and notAutoAvailable field in mkt data
|
||||||
|
// 18 = can receive good till date field in open order messages, and send backfill requests
|
||||||
|
// 19 = can receive new extended order attributes in OPEN_ORDER
|
||||||
|
// 20 = expects TWS time string on connection after server version >= 20, and parentId in open order
|
||||||
|
// 21 = can receive bond contract details.
|
||||||
|
// 22 = can receive price magnifier in contract details
|
||||||
|
// 23 = support for scanner
|
||||||
|
// 24 = can receive volatility order parameters in open order messages
|
||||||
|
// 25 = can receive HMDS query start and end times
|
||||||
|
// 26 = can receive option vols in option market data messages
|
||||||
|
// 27 = can receive delta neutral order type and delta neutral aux price
|
||||||
|
// 28 = can receive option model computation ticks
|
||||||
|
// 29 = can receive trail stop limit price in open order and can place them: API 8.91
|
||||||
|
// 30 = can receive extended bond contract def, new ticks, and trade count in bars
|
||||||
|
// 31 = can receive EFP extensions to scanner and market data, and combo legs on open orders
|
||||||
|
// ; can receive RT bars
|
||||||
|
// 32 = can receive TickType.LAST_TIMESTAMP
|
||||||
|
// 33 = can receive ScaleNumComponents and ScaleComponentSize is open order messages
|
||||||
|
// 34 = can receive whatIf orders / order state
|
||||||
|
// 35 = can receive contId field for Contract objects
|
||||||
|
// 36 = can receive outsideRth field for Order objects
|
||||||
|
// 37 = can receive clearingAccount and clearingIntent for Order objects
|
||||||
|
// 38 = can receive multipier and primaryExchange in portfolio updates
|
||||||
|
// ; can receive cumQty and avgPrice in execution
|
||||||
|
// ; can receive fundamental data
|
||||||
|
// ; can receive underComp for Contract objects
|
||||||
|
// ; can receive reqId and end marker in contractDetails/bondContractDetails
|
||||||
|
// ; can receive ScaleInitComponentSize and ScaleSubsComponentSize for Order objects
|
||||||
|
// 39 = can receive underConId in contractDetails
|
||||||
|
// 40 = can receive algoStrategy/algoParams in openOrder
|
||||||
|
// 41 = can receive end marker for openOrder
|
||||||
|
// ; can receive end marker for account download
|
||||||
|
// ; can receive end marker for executions download
|
||||||
|
// 42 = can receive deltaNeutralValidation
|
||||||
|
// 43 = can receive longName(companyName)
|
||||||
|
// ; can receive listingExchange
|
||||||
|
// ; can receive RTVolume tick
|
||||||
|
// 44 = can receive end market for ticker snapshot
|
||||||
|
// 45 = can receive notHeld field in openOrder
|
||||||
|
// 46 = can receive contractMonth, industry, category, subcategory fields in contractDetails
|
||||||
|
// ; can receive timeZoneId, tradingHours, liquidHours fields in contractDetails
|
||||||
|
// 47 = can receive gamma, vega, theta, undPrice fields in TICK_OPTION_COMPUTATION
|
||||||
|
// 48 = can receive exemptCode in openOrder
|
||||||
|
// 49 = can receive hedgeType and hedgeParam in openOrder
|
||||||
|
// 50 = can receive optOutSmartRouting field in openOrder
|
||||||
|
// 51 = can receive smartComboRoutingParams in openOrder
|
||||||
|
// 52 = can receive deltaNeutralConId, deltaNeutralSettlingFirm, deltaNeutralClearingAccount and deltaNeutralClearingIntent in openOrder
|
||||||
|
// 53 = can receive orderRef in execution
|
||||||
|
// 54 = can receive scale order fields (PriceAdjustValue, PriceAdjustInterval, ProfitOffset, AutoReset,
|
||||||
|
// InitPosition, InitFillQty and RandomPercent) in openOrder
|
||||||
|
// 55 = can receive orderComboLegs (price) in openOrder
|
||||||
|
// 56 = can receive trailingPercent in openOrder
|
||||||
|
// 57 = can receive commissionReport message
|
||||||
|
// 58 = can receive CUSIP/ISIN/etc. in contractDescription/bondContractDescription
|
||||||
|
// 59 = can receive evRule, evMultiplier in contractDescription/bondContractDescription/executionDetails
|
||||||
|
// can receive multiplier in executionDetails
|
||||||
|
// 60 = can receive deltaNeutralOpenClose, deltaNeutralShortSale, deltaNeutralShortSaleSlot
|
||||||
|
// and deltaNeutralDesignatedLocation in openOrder
|
||||||
|
// can receive position, positionEnd, accountSummary and accountSummaryEnd
|
||||||
|
// 61 = can receive multiplier in openOrder
|
||||||
|
// can receive tradingClass in openOrder, updatePortfolio, execDetails and position
|
||||||
|
// 62 = can receive avgCost in position message
|
||||||
|
// 63 = can receive verifyMessageAPI, verifyCompleted, displayGroupList and displayGroupUpdated messages
|
||||||
|
// 64 = can receive solicited attrib in openOrder message
|
||||||
|
// 65 = can receive verifyAndAuthMessageAPI and verifyAndAuthCompleted messages
|
||||||
|
// 66 = can receive randomize size and randomize price order fields
|
||||||
|
|
||||||
|
const int CLIENT_VERSION = 66;
|
||||||
|
|
||||||
|
|
||||||
|
// outgoing msg id's
|
||||||
|
const int REQ_MKT_DATA = 1;
|
||||||
|
const int CANCEL_MKT_DATA = 2;
|
||||||
|
const int PLACE_ORDER = 3;
|
||||||
|
const int CANCEL_ORDER = 4;
|
||||||
|
const int REQ_OPEN_ORDERS = 5;
|
||||||
|
const int REQ_ACCT_DATA = 6;
|
||||||
|
const int REQ_EXECUTIONS = 7;
|
||||||
|
const int REQ_IDS = 8;
|
||||||
|
const int REQ_CONTRACT_DATA = 9;
|
||||||
|
const int REQ_MKT_DEPTH = 10;
|
||||||
|
const int CANCEL_MKT_DEPTH = 11;
|
||||||
|
const int REQ_NEWS_BULLETINS = 12;
|
||||||
|
const int CANCEL_NEWS_BULLETINS = 13;
|
||||||
|
const int SET_SERVER_LOGLEVEL = 14;
|
||||||
|
const int REQ_AUTO_OPEN_ORDERS = 15;
|
||||||
|
const int REQ_ALL_OPEN_ORDERS = 16;
|
||||||
|
const int REQ_MANAGED_ACCTS = 17;
|
||||||
|
const int REQ_FA = 18;
|
||||||
|
const int REPLACE_FA = 19;
|
||||||
|
const int REQ_HISTORICAL_DATA = 20;
|
||||||
|
const int EXERCISE_OPTIONS = 21;
|
||||||
|
const int REQ_SCANNER_SUBSCRIPTION = 22;
|
||||||
|
const int CANCEL_SCANNER_SUBSCRIPTION = 23;
|
||||||
|
const int REQ_SCANNER_PARAMETERS = 24;
|
||||||
|
const int CANCEL_HISTORICAL_DATA = 25;
|
||||||
|
const int REQ_CURRENT_TIME = 49;
|
||||||
|
const int REQ_REAL_TIME_BARS = 50;
|
||||||
|
const int CANCEL_REAL_TIME_BARS = 51;
|
||||||
|
const int REQ_FUNDAMENTAL_DATA = 52;
|
||||||
|
const int CANCEL_FUNDAMENTAL_DATA = 53;
|
||||||
|
const int REQ_CALC_IMPLIED_VOLAT = 54;
|
||||||
|
const int REQ_CALC_OPTION_PRICE = 55;
|
||||||
|
const int CANCEL_CALC_IMPLIED_VOLAT = 56;
|
||||||
|
const int CANCEL_CALC_OPTION_PRICE = 57;
|
||||||
|
const int REQ_GLOBAL_CANCEL = 58;
|
||||||
|
const int REQ_MARKET_DATA_TYPE = 59;
|
||||||
|
const int REQ_POSITIONS = 61;
|
||||||
|
const int REQ_ACCOUNT_SUMMARY = 62;
|
||||||
|
const int CANCEL_ACCOUNT_SUMMARY = 63;
|
||||||
|
const int CANCEL_POSITIONS = 64;
|
||||||
|
const int VERIFY_REQUEST = 65;
|
||||||
|
const int VERIFY_MESSAGE = 66;
|
||||||
|
const int QUERY_DISPLAY_GROUPS = 67;
|
||||||
|
const int SUBSCRIBE_TO_GROUP_EVENTS = 68;
|
||||||
|
const int UPDATE_DISPLAY_GROUP = 69;
|
||||||
|
const int UNSUBSCRIBE_FROM_GROUP_EVENTS = 70;
|
||||||
|
const int START_API = 71;
|
||||||
|
const int VERIFY_AND_AUTH_REQUEST = 72;
|
||||||
|
const int VERIFY_AND_AUTH_MESSAGE = 73;
|
||||||
|
const int REQ_POSITIONS_MULTI = 74;
|
||||||
|
const int CANCEL_POSITIONS_MULTI = 75;
|
||||||
|
const int REQ_ACCOUNT_UPDATES_MULTI = 76;
|
||||||
|
const int CANCEL_ACCOUNT_UPDATES_MULTI = 77;
|
||||||
|
const int REQ_SEC_DEF_OPT_PARAMS = 78;
|
||||||
|
const int REQ_SOFT_DOLLAR_TIERS = 79;
|
||||||
|
|
||||||
|
// TWS New Bulletins constants
|
||||||
|
const int NEWS_MSG = 1; // standard IB news bulleting message
|
||||||
|
const int EXCHANGE_AVAIL_MSG = 2; // control message specifing that an exchange is available for trading
|
||||||
|
const int EXCHANGE_UNAVAIL_MSG = 3; // control message specifing that an exchange is unavailable for trading
|
||||||
|
|
||||||
|
} // namespace client_constants
|
||||||
|
} // namespace ibapi
|
||||||
|
|
||||||
|
struct Contract;
|
||||||
|
struct Order;
|
||||||
|
struct ExecutionFilter;
|
||||||
|
struct ScannerSubscription;
|
||||||
|
struct ETransport;
|
||||||
|
|
||||||
|
class EWrapper;
|
||||||
|
typedef std::vector<char> BytesVec;
|
||||||
|
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit EClient(EWrapper *ptr, ETransport *pTransport);
|
||||||
|
~EClient();
|
||||||
|
|
||||||
|
virtual void eDisconnect() = 0;
|
||||||
|
|
||||||
|
int clientId() const { return m_clientId; }
|
||||||
|
|
||||||
|
const std::string& optionalCapabilities() const;
|
||||||
|
void setOptionalCapabilities(const std::string& optCapts);
|
||||||
|
|
||||||
|
void setConnectOptions(const std::string& connectOptions);
|
||||||
|
void disableUseV100Plus();
|
||||||
|
bool usingV100Plus();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void eConnectBase();
|
||||||
|
void eDisconnectBase();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ConnState {
|
||||||
|
CS_DISCONNECTED,
|
||||||
|
CS_CONNECTING,
|
||||||
|
CS_CONNECTED,
|
||||||
|
CS_REDIRECT
|
||||||
|
};
|
||||||
|
|
||||||
|
// connection state
|
||||||
|
ConnState connState() const;
|
||||||
|
bool isConnected() const;
|
||||||
|
|
||||||
|
const std::string& host() const { return m_host; }
|
||||||
|
unsigned port() const { return m_port; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// access to protected variables
|
||||||
|
EWrapper * getWrapper() const;
|
||||||
|
protected:
|
||||||
|
void setClientId( int clientId);
|
||||||
|
void setExtraAuth( bool extraAuth);
|
||||||
|
void setHost( const std::string& host);
|
||||||
|
void setPort( unsigned port);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool isInBufferEmpty() const;
|
||||||
|
|
||||||
|
// override virtual funcs from EClient
|
||||||
|
int serverVersion();
|
||||||
|
std::string TwsConnectionTime();
|
||||||
|
void reqMktData(TickerId id, const Contract& contract,
|
||||||
|
const std::string& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions);
|
||||||
|
void cancelMktData(TickerId id);
|
||||||
|
void placeOrder(OrderId id, const Contract& contract, const Order& order);
|
||||||
|
void cancelOrder(OrderId id) ;
|
||||||
|
void reqOpenOrders();
|
||||||
|
void reqAccountUpdates(bool subscribe, const std::string& acctCode);
|
||||||
|
void reqExecutions(int reqId, const ExecutionFilter& filter);
|
||||||
|
void reqIds(int numIds);
|
||||||
|
void reqContractDetails(int reqId, const Contract& contract);
|
||||||
|
void reqMktDepth(TickerId tickerId, const Contract& contract, int numRows, const TagValueListSPtr& mktDepthOptions);
|
||||||
|
void cancelMktDepth(TickerId tickerId);
|
||||||
|
void reqNewsBulletins(bool allMsgs);
|
||||||
|
void cancelNewsBulletins();
|
||||||
|
void setServerLogLevel(int level);
|
||||||
|
void reqAutoOpenOrders(bool bAutoBind);
|
||||||
|
void reqAllOpenOrders();
|
||||||
|
void reqManagedAccts();
|
||||||
|
void requestFA(faDataType pFaDataType);
|
||||||
|
void replaceFA(faDataType pFaDataType, const std::string& cxml);
|
||||||
|
void reqHistoricalData( TickerId id, const Contract& contract,
|
||||||
|
const std::string& endDateTime, const std::string& durationStr,
|
||||||
|
const std::string& barSizeSetting, const std::string& whatToShow,
|
||||||
|
int useRTH, int formatDate, const TagValueListSPtr& chartOptions);
|
||||||
|
void exerciseOptions(TickerId tickerId, const Contract& contract,
|
||||||
|
int exerciseAction, int exerciseQuantity,
|
||||||
|
const std::string& account, int override);
|
||||||
|
void cancelHistoricalData(TickerId tickerId );
|
||||||
|
void reqRealTimeBars(TickerId id, const Contract& contract, int barSize,
|
||||||
|
const std::string& whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions);
|
||||||
|
void cancelRealTimeBars(TickerId tickerId );
|
||||||
|
void cancelScannerSubscription(int tickerId);
|
||||||
|
void reqScannerParameters();
|
||||||
|
void reqScannerSubscription(int tickerId, const ScannerSubscription& subscription, const TagValueListSPtr& scannerSubscriptionOptions);
|
||||||
|
void reqCurrentTime();
|
||||||
|
void reqFundamentalData(TickerId reqId, const Contract&, const std::string& reportType);
|
||||||
|
void cancelFundamentalData(TickerId reqId);
|
||||||
|
void calculateImpliedVolatility(TickerId reqId, const Contract& contract, double optionPrice, double underPrice);
|
||||||
|
void calculateOptionPrice(TickerId reqId, const Contract& contract, double volatility, double underPrice);
|
||||||
|
void cancelCalculateImpliedVolatility(TickerId reqId);
|
||||||
|
void cancelCalculateOptionPrice(TickerId reqId);
|
||||||
|
void reqGlobalCancel();
|
||||||
|
void reqMarketDataType(int marketDataType);
|
||||||
|
void reqPositions();
|
||||||
|
void cancelPositions();
|
||||||
|
void reqAccountSummary( int reqId, const std::string& groupName, const std::string& tags);
|
||||||
|
void cancelAccountSummary( int reqId);
|
||||||
|
void verifyRequest( const std::string& apiName, const std::string& apiVersion);
|
||||||
|
void verifyMessage( const std::string& apiData);
|
||||||
|
void verifyAndAuthRequest( const std::string& apiName, const std::string& apiVersion, const std::string& opaqueIsvKey);
|
||||||
|
void verifyAndAuthMessage( const std::string& apiData, const std::string& xyzResponse);
|
||||||
|
void queryDisplayGroups( int reqId);
|
||||||
|
void subscribeToGroupEvents( int reqId, int groupId);
|
||||||
|
void updateDisplayGroup( int reqId, const std::string& contractInfo);
|
||||||
|
void unsubscribeFromGroupEvents( int reqId);
|
||||||
|
void reqPositionsMulti( int reqId, const std::string& account, const std::string& modelCode);
|
||||||
|
void cancelPositionsMulti( int reqId);
|
||||||
|
void reqAccountUpdatessMulti( int reqId, const std::string& account, const std::string& modelCode, bool ledgerAndNLV);
|
||||||
|
void cancelAccountUpdatesMulti( int reqId);
|
||||||
|
void reqSecDefOptParams(int reqId, const std::string& underlyingSymbol, const std::string& futFopExchange, const std::string& underlyingSecType, int underlyingConId);
|
||||||
|
void reqSoftDollarTiers(int reqId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual int receive(char* buf, size_t sz) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void prepareBufferImpl(std::ostream&) const = 0;
|
||||||
|
virtual void prepareBuffer(std::ostream&) const = 0;
|
||||||
|
virtual bool closeAndSend(std::string msg, unsigned offset = 0) = 0;
|
||||||
|
virtual int bufferedSend(const std::string& msg);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int bufferedRead();
|
||||||
|
|
||||||
|
// try to process connection request ack
|
||||||
|
private:
|
||||||
|
// try to process single msg
|
||||||
|
int processMsgImpl(const char*& ptr, const char* endPtr);
|
||||||
|
int processMsg(const char*& ptr, const char* endPtr);
|
||||||
|
|
||||||
|
typedef int (EClient::*messageHandler)(const char*& ptr, const char* endPtr);
|
||||||
|
int processOnePrefixedMsg(const char*& ptr, const char* endPtr, messageHandler);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void startApi();
|
||||||
|
|
||||||
|
|
||||||
|
// encoders
|
||||||
|
template<class T> static void EncodeField(std::ostream&, T);
|
||||||
|
|
||||||
|
// "max" encoders
|
||||||
|
static void EncodeFieldMax(std::ostream& os, int);
|
||||||
|
static void EncodeFieldMax(std::ostream& os, double);
|
||||||
|
|
||||||
|
// socket state
|
||||||
|
private:
|
||||||
|
virtual bool isSocketOK() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool isConnecting() const;
|
||||||
|
int sendConnectRequest();
|
||||||
|
bool extraAuth();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
EWrapper *m_pEWrapper;
|
||||||
|
std::auto_ptr<ETransport> m_transport;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BytesVec m_inBuffer;
|
||||||
|
|
||||||
|
std::string m_host;
|
||||||
|
int m_port;
|
||||||
|
|
||||||
|
int m_clientId;
|
||||||
|
|
||||||
|
ConnState m_connState;
|
||||||
|
bool m_extraAuth;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_serverVersion;
|
||||||
|
std::string m_TwsTime;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_optionalCapabilities;
|
||||||
|
|
||||||
|
std::string m_connectOptions;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_useV100Plus;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> void EClient::EncodeField<bool>(std::ostream& os, bool);
|
||||||
|
template<> void EClient::EncodeField<double>(std::ostream& os, double);
|
||||||
|
|
||||||
|
#define ENCODE_FIELD(x) EClient::EncodeField(msg, x);
|
||||||
|
#define ENCODE_FIELD_MAX(x) EClient::EncodeFieldMax(msg, x);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
10
vn.ib/ibapi/windows/client/EClientMsgSink.h
Normal file
10
vn.ib/ibapi/windows/client/EClientMsgSink.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
struct EClientMsgSink
|
||||||
|
{
|
||||||
|
virtual void serverVersion(int version, const char *time) = 0;
|
||||||
|
virtual void redirect(const char *host, int port) = 0;
|
||||||
|
};
|
||||||
|
|
332
vn.ib/ibapi/windows/client/EClientSocket.cpp
Normal file
332
vn.ib/ibapi/windows/client/EClientSocket.cpp
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "EPosixClientSocketPlatform.h"
|
||||||
|
#include "EClientSocket.h"
|
||||||
|
|
||||||
|
#include "TwsSocketClientErrors.h"
|
||||||
|
#include "EWrapper.h"
|
||||||
|
#include "EDecoder.h"
|
||||||
|
#include "EReaderSignal.h"
|
||||||
|
#include "EReader.h"
|
||||||
|
#include "EMessage.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
const int MIN_SERVER_VER_SUPPORTED = 38; //all supported server versions are defined in EDecoder.h
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// member funcs
|
||||||
|
EClientSocket::EClientSocket(EWrapper *ptr, EReaderSignal *pSignal) : EClient( ptr, new ESocket())
|
||||||
|
{
|
||||||
|
m_fd = SocketsInit() ? -1 : -2;
|
||||||
|
m_allowRedirect = false;
|
||||||
|
m_asyncEConnect = false;
|
||||||
|
m_pSignal = pSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
EClientSocket::~EClientSocket()
|
||||||
|
{
|
||||||
|
if( m_fd != -2)
|
||||||
|
SocketsDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::asyncEConnect() const {
|
||||||
|
return m_asyncEConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::asyncEConnect(bool val) {
|
||||||
|
m_asyncEConnect = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::eConnect( const char *host, unsigned int port, int clientId, bool extraAuth)
|
||||||
|
{
|
||||||
|
if( m_fd == -2) {
|
||||||
|
getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset errno
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
// already connected?
|
||||||
|
if( m_fd >= 0) {
|
||||||
|
errno = EISCONN;
|
||||||
|
getWrapper()->error( NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize host
|
||||||
|
m_hostNorm = (host && *host) ? host : "127.0.0.1";
|
||||||
|
|
||||||
|
// initialize host and port
|
||||||
|
setHost( m_hostNorm);
|
||||||
|
setPort( port);
|
||||||
|
|
||||||
|
// try to connect to specified host and port
|
||||||
|
ConnState resState = CS_DISCONNECTED;
|
||||||
|
|
||||||
|
return eConnectImpl( clientId, extraAuth, &resState);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESocket *EClientSocket::getTransport() {
|
||||||
|
assert(dynamic_cast<ESocket*>(m_transport.get()) != 0);
|
||||||
|
|
||||||
|
return static_cast<ESocket*>(m_transport.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::eConnectImpl(int clientId, bool extraAuth, ConnState* stateOutPt)
|
||||||
|
{
|
||||||
|
// resolve host
|
||||||
|
struct hostent* hostEnt = gethostbyname( host().c_str());
|
||||||
|
if ( !hostEnt) {
|
||||||
|
getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create socket
|
||||||
|
m_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
// cannot create socket
|
||||||
|
if( m_fd < 0) {
|
||||||
|
getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// starting to connect to server
|
||||||
|
struct sockaddr_in sa;
|
||||||
|
memset( &sa, 0, sizeof(sa));
|
||||||
|
sa.sin_family = AF_INET;
|
||||||
|
sa.sin_port = htons( port());
|
||||||
|
sa.sin_addr.s_addr = ((in_addr*)hostEnt->h_addr)->s_addr;
|
||||||
|
|
||||||
|
// try to connect
|
||||||
|
if( (connect( m_fd, (struct sockaddr *) &sa, sizeof( sa))) < 0) {
|
||||||
|
// error connecting
|
||||||
|
SocketClose( m_fd);
|
||||||
|
m_fd = -1;
|
||||||
|
getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTransport()->fd(m_fd);
|
||||||
|
|
||||||
|
// set client id
|
||||||
|
setClientId( clientId);
|
||||||
|
setExtraAuth( extraAuth);
|
||||||
|
|
||||||
|
int res = sendConnectRequest();
|
||||||
|
|
||||||
|
if (res < 0 && !handleSocketError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !isConnected()) {
|
||||||
|
if( connState() != CS_DISCONNECTED) {
|
||||||
|
assert( connState() == CS_REDIRECT);
|
||||||
|
if( stateOutPt) {
|
||||||
|
*stateOutPt = connState();
|
||||||
|
}
|
||||||
|
eDisconnect();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set socket to non-blocking state
|
||||||
|
if ( !SetSocketNonBlocking(m_fd)) {
|
||||||
|
// error setting socket to non-blocking
|
||||||
|
eDisconnect();
|
||||||
|
getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( connState() == CS_CONNECTED);
|
||||||
|
if( stateOutPt) {
|
||||||
|
*stateOutPt = connState();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_asyncEConnect) {
|
||||||
|
EReader reader(this, m_pSignal);
|
||||||
|
|
||||||
|
reader.putMessageToQueue();
|
||||||
|
|
||||||
|
while (m_pSignal && !m_serverVersion && isSocketOK()) {
|
||||||
|
reader.checkClient();
|
||||||
|
m_pSignal->waitForSignal();
|
||||||
|
reader.processMsgs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// successfully connected
|
||||||
|
return isSocketOK();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::encodeMsgLen(std::string& msg, unsigned offset) const
|
||||||
|
{
|
||||||
|
assert( !msg.empty());
|
||||||
|
assert( m_useV100Plus);
|
||||||
|
|
||||||
|
assert( sizeof(unsigned) == HEADER_LEN);
|
||||||
|
assert( msg.size() > offset + HEADER_LEN);
|
||||||
|
unsigned len = msg.size() - HEADER_LEN - offset;
|
||||||
|
if( len > MAX_MSG_LEN) {
|
||||||
|
m_pEWrapper->error( NO_VALID_ID, BAD_LENGTH.code(), BAD_LENGTH.msg());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned netlen = htonl( len);
|
||||||
|
memcpy( &msg[offset], &netlen, HEADER_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::closeAndSend(std::string msg, unsigned offset)
|
||||||
|
{
|
||||||
|
assert( !msg.empty());
|
||||||
|
if( m_useV100Plus) {
|
||||||
|
encodeMsgLen( msg, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferedSend(msg) == -1)
|
||||||
|
return handleSocketError();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::prepareBufferImpl(std::ostream& buf) const
|
||||||
|
{
|
||||||
|
assert( m_useV100Plus);
|
||||||
|
assert( sizeof(unsigned) == HEADER_LEN);
|
||||||
|
|
||||||
|
char header[HEADER_LEN] = { 0 };
|
||||||
|
buf.write( header, sizeof(header));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::prepareBuffer(std::ostream& buf) const
|
||||||
|
{
|
||||||
|
if( !m_useV100Plus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
prepareBufferImpl( buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::eDisconnect()
|
||||||
|
{
|
||||||
|
if ( m_fd >= 0 )
|
||||||
|
// close socket
|
||||||
|
SocketClose( m_fd);
|
||||||
|
m_fd = -1;
|
||||||
|
|
||||||
|
eDisconnectBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::isSocketOK() const
|
||||||
|
{
|
||||||
|
return ( m_fd >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EClientSocket::fd() const
|
||||||
|
{
|
||||||
|
return m_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EClientSocket::receive(char* buf, size_t sz)
|
||||||
|
{
|
||||||
|
if( sz <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int nResult = ::recv( m_fd, buf, sz, 0);
|
||||||
|
|
||||||
|
if( nResult == -1 && !handleSocketError()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if( nResult == 0) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
if( nResult <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::serverVersion(int version, const char *time) {
|
||||||
|
m_serverVersion = version;
|
||||||
|
m_TwsTime = time;
|
||||||
|
|
||||||
|
if( usingV100Plus() ? (m_serverVersion < MIN_CLIENT_VER || m_serverVersion > MAX_CLIENT_VER) : m_serverVersion < MIN_SERVER_VER_SUPPORTED ) {
|
||||||
|
getWrapper()->error( NO_VALID_ID, UNSUPPORTED_VERSION.code(), UNSUPPORTED_VERSION.msg());
|
||||||
|
eDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_asyncEConnect)
|
||||||
|
startApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::redirect(const char *host, int port) {
|
||||||
|
// handle redirect
|
||||||
|
if( (m_hostNorm != this->host() || port != this->port())) {
|
||||||
|
if (!m_allowRedirect) {
|
||||||
|
getWrapper()->error(NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eDisconnect();
|
||||||
|
eConnectImpl( clientId(), extraAuth(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EClientSocket::handleSocketError()
|
||||||
|
{
|
||||||
|
// no error
|
||||||
|
if( errno == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Socket is already connected
|
||||||
|
if( errno == EISCONN) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( errno == EWOULDBLOCK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( errno == ECONNREFUSED) {
|
||||||
|
getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(),
|
||||||
|
SOCKET_EXCEPTION.msg() + strerror(errno));
|
||||||
|
}
|
||||||
|
// reset errno
|
||||||
|
errno = 0;
|
||||||
|
eDisconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// callbacks from socket
|
||||||
|
|
||||||
|
void EClientSocket::onSend()
|
||||||
|
{
|
||||||
|
if( !handleSocketError())
|
||||||
|
return;
|
||||||
|
|
||||||
|
getTransport()->sendBufferedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::onClose()
|
||||||
|
{
|
||||||
|
if( !handleSocketError())
|
||||||
|
return;
|
||||||
|
|
||||||
|
eDisconnect();
|
||||||
|
getWrapper()->connectionClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EClientSocket::onError()
|
||||||
|
{
|
||||||
|
handleSocketError();
|
||||||
|
}
|
70
vn.ib/ibapi/windows/client/EClientSocket.h
Normal file
70
vn.ib/ibapi/windows/client/EClientSocket.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef eposixclientsocket_def
|
||||||
|
#define eposixclientsocket_def
|
||||||
|
|
||||||
|
#include "EClient.h"
|
||||||
|
#include "EClientMsgSink.h"
|
||||||
|
#include "ESocket.h"
|
||||||
|
|
||||||
|
class EWrapper;
|
||||||
|
class EReaderSignal;
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EClientSocket : public EClient, public EClientMsgSink
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual void prepareBufferImpl(std::ostream&) const;
|
||||||
|
virtual void prepareBuffer(std::ostream&) const;
|
||||||
|
virtual bool closeAndSend(std::string msg, unsigned offset = 0);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit EClientSocket(EWrapper *ptr, EReaderSignal *pSignal = 0);
|
||||||
|
~EClientSocket();
|
||||||
|
|
||||||
|
bool eConnect( const char *host, unsigned int port, int clientId = 0, bool extraAuth = false);
|
||||||
|
// override virtual funcs from EClient
|
||||||
|
void eDisconnect();
|
||||||
|
|
||||||
|
bool isSocketOK() const;
|
||||||
|
int fd() const;
|
||||||
|
bool asyncEConnect() const;
|
||||||
|
void asyncEConnect(bool val);
|
||||||
|
ESocket *getTransport();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool eConnectImpl(int clientId, bool extraAuth, ConnState* stateOutPt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void encodeMsgLen(std::string& msg, unsigned offset) const;
|
||||||
|
public:
|
||||||
|
bool handleSocketError();
|
||||||
|
int receive( char* buf, size_t sz);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// callback from socket
|
||||||
|
void onSend();
|
||||||
|
void onError();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void onClose();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_fd;
|
||||||
|
bool m_allowRedirect;
|
||||||
|
const char* m_hostNorm;
|
||||||
|
bool m_asyncEConnect;
|
||||||
|
EReaderSignal *m_pSignal;
|
||||||
|
|
||||||
|
//EClientMsgSink implementation
|
||||||
|
public:
|
||||||
|
void serverVersion(int version, const char *time);
|
||||||
|
void redirect(const char *host, int port);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2076
vn.ib/ibapi/windows/client/EDecoder.cpp
Normal file
2076
vn.ib/ibapi/windows/client/EDecoder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
244
vn.ib/ibapi/windows/client/EDecoder.h
Normal file
244
vn.ib/ibapi/windows/client/EDecoder.h
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Contract.h"
|
||||||
|
|
||||||
|
|
||||||
|
//const int MIN_SERVER_VER_REAL_TIME_BARS = 34;
|
||||||
|
//const int MIN_SERVER_VER_SCALE_ORDERS = 35;
|
||||||
|
//const int MIN_SERVER_VER_SNAPSHOT_MKT_DATA = 35;
|
||||||
|
//const int MIN_SERVER_VER_SSHORT_COMBO_LEGS = 35;
|
||||||
|
//const int MIN_SERVER_VER_WHAT_IF_ORDERS = 36;
|
||||||
|
//const int MIN_SERVER_VER_CONTRACT_CONID = 37;
|
||||||
|
const int MIN_SERVER_VER_PTA_ORDERS = 39;
|
||||||
|
const int MIN_SERVER_VER_FUNDAMENTAL_DATA = 40;
|
||||||
|
const int MIN_SERVER_VER_UNDER_COMP = 40;
|
||||||
|
const int MIN_SERVER_VER_CONTRACT_DATA_CHAIN = 40;
|
||||||
|
const int MIN_SERVER_VER_SCALE_ORDERS2 = 40;
|
||||||
|
const int MIN_SERVER_VER_ALGO_ORDERS = 41;
|
||||||
|
const int MIN_SERVER_VER_EXECUTION_DATA_CHAIN = 42;
|
||||||
|
const int MIN_SERVER_VER_NOT_HELD = 44;
|
||||||
|
const int MIN_SERVER_VER_SEC_ID_TYPE = 45;
|
||||||
|
const int MIN_SERVER_VER_PLACE_ORDER_CONID = 46;
|
||||||
|
const int MIN_SERVER_VER_REQ_MKT_DATA_CONID = 47;
|
||||||
|
const int MIN_SERVER_VER_REQ_CALC_IMPLIED_VOLAT = 49;
|
||||||
|
const int MIN_SERVER_VER_REQ_CALC_OPTION_PRICE = 50;
|
||||||
|
const int MIN_SERVER_VER_CANCEL_CALC_IMPLIED_VOLAT = 50;
|
||||||
|
const int MIN_SERVER_VER_CANCEL_CALC_OPTION_PRICE = 50;
|
||||||
|
const int MIN_SERVER_VER_SSHORTX_OLD = 51;
|
||||||
|
const int MIN_SERVER_VER_SSHORTX = 52;
|
||||||
|
const int MIN_SERVER_VER_REQ_GLOBAL_CANCEL = 53;
|
||||||
|
const int MIN_SERVER_VER_HEDGE_ORDERS = 54;
|
||||||
|
const int MIN_SERVER_VER_REQ_MARKET_DATA_TYPE = 55;
|
||||||
|
const int MIN_SERVER_VER_OPT_OUT_SMART_ROUTING = 56;
|
||||||
|
const int MIN_SERVER_VER_SMART_COMBO_ROUTING_PARAMS = 57;
|
||||||
|
const int MIN_SERVER_VER_DELTA_NEUTRAL_CONID = 58;
|
||||||
|
const int MIN_SERVER_VER_SCALE_ORDERS3 = 60;
|
||||||
|
const int MIN_SERVER_VER_ORDER_COMBO_LEGS_PRICE = 61;
|
||||||
|
const int MIN_SERVER_VER_TRAILING_PERCENT = 62;
|
||||||
|
const int MIN_SERVER_VER_DELTA_NEUTRAL_OPEN_CLOSE = 66;
|
||||||
|
const int MIN_SERVER_VER_POSITIONS = 67;
|
||||||
|
const int MIN_SERVER_VER_ACCOUNT_SUMMARY = 67;
|
||||||
|
const int MIN_SERVER_VER_TRADING_CLASS = 68;
|
||||||
|
const int MIN_SERVER_VER_SCALE_TABLE = 69;
|
||||||
|
const int MIN_SERVER_VER_LINKING = 70;
|
||||||
|
const int MIN_SERVER_VER_ALGO_ID = 71;
|
||||||
|
const int MIN_SERVER_VER_OPTIONAL_CAPABILITIES = 72;
|
||||||
|
const int MIN_SERVER_VER_ORDER_SOLICITED = 73;
|
||||||
|
const int MIN_SERVER_VER_LINKING_AUTH = 74;
|
||||||
|
const int MIN_SERVER_VER_PRIMARYEXCH = 75;
|
||||||
|
const int MIN_SERVER_VER_RANDOMIZE_SIZE_AND_PRICE = 76;
|
||||||
|
const int MIN_SERVER_VER_FRACTIONAL_POSITIONS = 101;
|
||||||
|
const int MIN_SERVER_VER_PEGGED_TO_BENCHMARK = 102;
|
||||||
|
const int MIN_SERVER_VER_MODELS_SUPPORT = 103;
|
||||||
|
const int MIN_SERVER_VER_SEC_DEF_OPT_PARAMS_REQ = 104;
|
||||||
|
const int MIN_SERVER_VER_EXT_OPERATOR = 105;
|
||||||
|
const int MIN_SERVER_VER_SOFT_DOLLAR_TIER = 106;
|
||||||
|
|
||||||
|
/* 100+ messaging */
|
||||||
|
// 100 = enhanced handshake, msg length prefixes
|
||||||
|
|
||||||
|
const int MIN_CLIENT_VER = 100;
|
||||||
|
const int MAX_CLIENT_VER = MIN_SERVER_VER_SOFT_DOLLAR_TIER;
|
||||||
|
|
||||||
|
|
||||||
|
// incoming msg id's
|
||||||
|
const int TICK_PRICE = 1;
|
||||||
|
const int TICK_SIZE = 2;
|
||||||
|
const int ORDER_STATUS = 3;
|
||||||
|
const int ERR_MSG = 4;
|
||||||
|
const int OPEN_ORDER = 5;
|
||||||
|
const int ACCT_VALUE = 6;
|
||||||
|
const int PORTFOLIO_VALUE = 7;
|
||||||
|
const int ACCT_UPDATE_TIME = 8;
|
||||||
|
const int NEXT_VALID_ID = 9;
|
||||||
|
const int CONTRACT_DATA = 10;
|
||||||
|
const int EXECUTION_DATA = 11;
|
||||||
|
const int MARKET_DEPTH = 12;
|
||||||
|
const int MARKET_DEPTH_L2 = 13;
|
||||||
|
const int NEWS_BULLETINS = 14;
|
||||||
|
const int MANAGED_ACCTS = 15;
|
||||||
|
const int RECEIVE_FA = 16;
|
||||||
|
const int HISTORICAL_DATA = 17;
|
||||||
|
const int BOND_CONTRACT_DATA = 18;
|
||||||
|
const int SCANNER_PARAMETERS = 19;
|
||||||
|
const int SCANNER_DATA = 20;
|
||||||
|
const int TICK_OPTION_COMPUTATION = 21;
|
||||||
|
const int TICK_GENERIC = 45;
|
||||||
|
const int TICK_STRING = 46;
|
||||||
|
const int TICK_EFP = 47;
|
||||||
|
const int CURRENT_TIME = 49;
|
||||||
|
const int REAL_TIME_BARS = 50;
|
||||||
|
const int FUNDAMENTAL_DATA = 51;
|
||||||
|
const int CONTRACT_DATA_END = 52;
|
||||||
|
const int OPEN_ORDER_END = 53;
|
||||||
|
const int ACCT_DOWNLOAD_END = 54;
|
||||||
|
const int EXECUTION_DATA_END = 55;
|
||||||
|
const int DELTA_NEUTRAL_VALIDATION = 56;
|
||||||
|
const int TICK_SNAPSHOT_END = 57;
|
||||||
|
const int MARKET_DATA_TYPE = 58;
|
||||||
|
const int COMMISSION_REPORT = 59;
|
||||||
|
const int POSITION_DATA = 61;
|
||||||
|
const int POSITION_END = 62;
|
||||||
|
const int ACCOUNT_SUMMARY = 63;
|
||||||
|
const int ACCOUNT_SUMMARY_END = 64;
|
||||||
|
const int VERIFY_MESSAGE_API = 65;
|
||||||
|
const int VERIFY_COMPLETED = 66;
|
||||||
|
const int DISPLAY_GROUP_LIST = 67;
|
||||||
|
const int DISPLAY_GROUP_UPDATED = 68;
|
||||||
|
const int VERIFY_AND_AUTH_MESSAGE_API = 69;
|
||||||
|
const int VERIFY_AND_AUTH_COMPLETED = 70;
|
||||||
|
const int POSITION_MULTI = 71;
|
||||||
|
const int POSITION_MULTI_END = 72;
|
||||||
|
const int ACCOUNT_UPDATE_MULTI = 73;
|
||||||
|
const int ACCOUNT_UPDATE_MULTI_END = 74;
|
||||||
|
const int SECURITY_DEFINITION_OPTION_PARAMETER = 75;
|
||||||
|
const int SECURITY_DEFINITION_OPTION_PARAMETER_END = 76;
|
||||||
|
const int SOFT_DOLLAR_TIERS = 77;
|
||||||
|
|
||||||
|
const int HEADER_LEN = 4; // 4 bytes for msg length
|
||||||
|
const int MAX_MSG_LEN = 0xFFFFFF; // 16Mb - 1byte
|
||||||
|
const char API_SIGN[4] = { 'A', 'P', 'I', '\0' }; // "API"
|
||||||
|
|
||||||
|
|
||||||
|
// helper structures
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct BarData {
|
||||||
|
std::string date;
|
||||||
|
double open;
|
||||||
|
double high;
|
||||||
|
double low;
|
||||||
|
double close;
|
||||||
|
int volume;
|
||||||
|
double average;
|
||||||
|
std::string hasGaps;
|
||||||
|
int barCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScanData {
|
||||||
|
ContractDetails contract;
|
||||||
|
int rank;
|
||||||
|
std::string distance;
|
||||||
|
std::string benchmark;
|
||||||
|
std::string projection;
|
||||||
|
std::string legsStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of anonymous namespace
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// utility funcs
|
||||||
|
static std::string errMsg(std::exception e) {
|
||||||
|
// return the error associated with this exception
|
||||||
|
return std::string(e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
class EWrapper;
|
||||||
|
class EClient;
|
||||||
|
struct EClientMsgSink;
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EDecoder
|
||||||
|
{
|
||||||
|
EWrapper *m_pEWrapper;
|
||||||
|
int m_serverVersion;
|
||||||
|
EClientMsgSink *m_pClientMsgSink;
|
||||||
|
|
||||||
|
const char* processTickPriceMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickSizeMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickOptionComputationMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickGenericMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickStringMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickEfpMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processOrderStatusMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processErrMsgMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processOpenOrderMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAcctValueMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processPortfolioValueMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAcctUpdateTimeMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processNextValidIdMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processContractDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processBondContractDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processExecutionDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processMarketDepthMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processMarketDepthL2Msg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processNewsBulletinsMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processManagedAcctsMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processReceiveFaMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processHistoricalDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processScannerDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processScannerParametersMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processCurrentTimeMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processRealTimeBarsMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processFundamentalDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processContractDataEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processOpenOrderEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAcctDownloadEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processExecutionDataEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processDeltaNeutralValidationMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processTickSnapshotEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processMarketDataTypeMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processCommissionReportMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processPositionDataMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processPositionEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAccountSummaryMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAccountSummaryEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processVerifyMessageApiMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processVerifyCompletedMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processDisplayGroupListMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processDisplayGroupUpdatedMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processVerifyAndAuthMessageApiMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processVerifyAndAuthCompletedMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processPositionMultiMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processPositionMultiEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAccountUpdateMultiMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processAccountUpdateMultiEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processSecurityDefinitionOptionalParameterMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processSecurityDefinitionOptionalParameterEndMsg(const char* ptr, const char* endPtr);
|
||||||
|
const char* processSoftDollarTiersMsg(const char* ptr, const char* endPtr);
|
||||||
|
|
||||||
|
int processConnectAck(const char*& beginPtr, const char* endPtr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool CheckOffset(const char* ptr, const char* endPtr);
|
||||||
|
static const char* FindFieldEnd(const char* ptr, const char* endPtr);
|
||||||
|
// decoders
|
||||||
|
static bool DecodeField(bool&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeField(int&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeField(long&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeField(double&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeField(std::string&, const char*& ptr, const char* endPtr);
|
||||||
|
|
||||||
|
static bool DecodeFieldMax(int&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeFieldMax(long&, const char*& ptr, const char* endPtr);
|
||||||
|
static bool DecodeFieldMax(double&, const char*& ptr, const char* endPtr);
|
||||||
|
|
||||||
|
EDecoder(int serverVersion, EWrapper *callback, EClientMsgSink *clientMsgSink = 0);
|
||||||
|
|
||||||
|
int parseAndProcessMsg(const char*& beginPtr, const char* endPtr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DECODE_FIELD(x) if (!EDecoder::DecodeField(x, ptr, endPtr)) return 0;
|
||||||
|
#define DECODE_FIELD_MAX(x) if (!EDecoder::DecodeFieldMax(x, ptr, endPtr)) return 0;
|
20
vn.ib/ibapi/windows/client/EMessage.cpp
Normal file
20
vn.ib/ibapi/windows/client/EMessage.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "EMessage.h"
|
||||||
|
|
||||||
|
|
||||||
|
EMessage::EMessage(const std::vector<char> &data) {
|
||||||
|
this->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* EMessage::begin(void) const
|
||||||
|
{
|
||||||
|
return data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* EMessage::end(void) const
|
||||||
|
{
|
||||||
|
return data.data() + data.size();
|
||||||
|
}
|
13
vn.ib/ibapi/windows/client/EMessage.h
Normal file
13
vn.ib/ibapi/windows/client/EMessage.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
class TWSAPIDLLEXP EMessage
|
||||||
|
{
|
||||||
|
std::vector<char> data;
|
||||||
|
public:
|
||||||
|
EMessage(const std::vector<char> &data);
|
||||||
|
const char* begin(void) const;
|
||||||
|
const char* end(void) const;
|
||||||
|
};
|
||||||
|
|
59
vn.ib/ibapi/windows/client/EMutex.cpp
Normal file
59
vn.ib/ibapi/windows/client/EMutex.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "EMutex.h"
|
||||||
|
|
||||||
|
EMutex::EMutex()
|
||||||
|
{
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_init(&cs, NULL);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
InitializeCriticalSection(&cs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EMutex::~EMutex(void)
|
||||||
|
{
|
||||||
|
Leave();
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_destroy(&cs);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
DeleteCriticalSection(&cs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EMutex::TryEnter()
|
||||||
|
{
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
return pthread_mutex_trylock(&cs) == 0;
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
return TryEnterCriticalSection(&cs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void EMutex::Enter() {
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_lock(&cs);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
EnterCriticalSection(&cs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void EMutex::Leave() {
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_unlock(&cs);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
LeaveCriticalSection(&cs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
25
vn.ib/ibapi/windows/client/EMutex.h
Normal file
25
vn.ib/ibapi/windows/client/EMutex.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EMutex
|
||||||
|
{
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_t cs;
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
CRITICAL_SECTION cs;
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
EMutex();
|
||||||
|
~EMutex();
|
||||||
|
bool TryEnter();
|
||||||
|
void Enter();
|
||||||
|
void Leave();
|
||||||
|
};
|
||||||
|
|
65
vn.ib/ibapi/windows/client/EPosixClientSocketPlatform.h
Normal file
65
vn.ib/ibapi/windows/client/EPosixClientSocketPlatform.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef eposixclientsocketcommon_def
|
||||||
|
#define eposixclientsocketcommon_def
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
// includes
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
// defines
|
||||||
|
#if _MSC_VER < 1700
|
||||||
|
#define EISCONN WSAEISCONN
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define ECONNREFUSED WSAECONNREFUSED
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
inline bool SocketsInit( void) {
|
||||||
|
WSADATA data;
|
||||||
|
return ( !WSAStartup( MAKEWORD(2, 2), &data));
|
||||||
|
};
|
||||||
|
inline bool SocketsDestroy() { return ( !WSACleanup()); };
|
||||||
|
inline int SocketClose(int sockfd) { return closesocket( sockfd); };
|
||||||
|
|
||||||
|
inline bool SetSocketNonBlocking(int sockfd) {
|
||||||
|
unsigned long mode = 1;
|
||||||
|
return ( ioctlsocket( sockfd, FIONBIO, &mode) == 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
// LINUX
|
||||||
|
// includes
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
inline bool SocketsInit() { return true; };
|
||||||
|
inline bool SocketsDestroy() { return true; };
|
||||||
|
inline int SocketClose(int sockfd) { return close( sockfd); };
|
||||||
|
|
||||||
|
inline bool SetSocketNonBlocking(int sockfd) {
|
||||||
|
// get socket flags
|
||||||
|
int flags = fcntl(sockfd, F_GETFL);
|
||||||
|
if (flags == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// set non-blocking mode
|
||||||
|
return ( fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
290
vn.ib/ibapi/windows/client/EReader.cpp
Normal file
290
vn.ib/ibapi/windows/client/EReader.cpp
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "shared_ptr.h"
|
||||||
|
#include "Contract.h"
|
||||||
|
#include "EDecoder.h"
|
||||||
|
#include "EMutex.h"
|
||||||
|
#include "EReader.h"
|
||||||
|
#include "EClientSocket.h"
|
||||||
|
#include "EPosixClientSocketPlatform.h"
|
||||||
|
#include "EReaderSignal.h"
|
||||||
|
#include "EMessage.h"
|
||||||
|
#include "DefaultEWrapper.h"
|
||||||
|
|
||||||
|
#define IN_BUF_SIZE_DEFAULT 8192
|
||||||
|
|
||||||
|
static DefaultEWrapper defaultWrapper;
|
||||||
|
|
||||||
|
EReader::EReader(EClientSocket *clientSocket, EReaderSignal *signal)
|
||||||
|
: processMsgsDecoder_(clientSocket->EClient::serverVersion(), clientSocket->getWrapper(), clientSocket) {
|
||||||
|
m_isAlive = true;
|
||||||
|
m_pClientSocket = clientSocket;
|
||||||
|
m_pEReaderSignal = signal;
|
||||||
|
m_needsWriteSelect = false;
|
||||||
|
m_nMaxBufSize = IN_BUF_SIZE_DEFAULT;
|
||||||
|
m_buf.reserve(IN_BUF_SIZE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
EReader::~EReader(void) {
|
||||||
|
m_isAlive = false;
|
||||||
|
|
||||||
|
#if defined(IB_WIN32)
|
||||||
|
WaitForSingleObject(m_hReadThread, INFINITE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReader::checkClient() {
|
||||||
|
m_needsWriteSelect = !m_pClientSocket->getTransport()->isOutBufferEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReader::start() {
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create( &thread, &attr, readToQueueThread, this );
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
m_hReadThread = CreateThread(0, 0, readToQueueThread, this, 0, 0);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
void * EReader::readToQueueThread(void * lpParam)
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
DWORD WINAPI EReader::readToQueueThread(LPVOID lpParam)
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
EReader *pThis = reinterpret_cast<EReader *>(lpParam);
|
||||||
|
|
||||||
|
pThis->readToQueue();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReader::readToQueue() {
|
||||||
|
EMessage *msg = 0;
|
||||||
|
|
||||||
|
while (m_isAlive) {
|
||||||
|
if (m_buf.size() == 0 && !processNonBlockingSelect() && m_pClientSocket->isSocketOK())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!putMessageToQueue())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pClientSocket->handleSocketError();
|
||||||
|
m_pEReaderSignal->issueSignal(); //letting client know that socket was closed
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EReader::putMessageToQueue() {
|
||||||
|
EMessage *msg = 0;
|
||||||
|
|
||||||
|
if (m_pClientSocket->isSocketOK())
|
||||||
|
msg = readSingleMsg();
|
||||||
|
|
||||||
|
if (msg == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_csMsgQueue.Enter();
|
||||||
|
m_msgQueue.push_back(ibapi::shared_ptr<EMessage>(msg));
|
||||||
|
m_csMsgQueue.Leave();
|
||||||
|
m_pEReaderSignal->issueSignal();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EReader::processNonBlockingSelect() {
|
||||||
|
fd_set readSet, writeSet, errorSet;
|
||||||
|
struct timeval tval;
|
||||||
|
|
||||||
|
tval.tv_usec = 100 * 1000; //100 ms
|
||||||
|
tval.tv_sec = 0;
|
||||||
|
|
||||||
|
if( m_pClientSocket->fd() >= 0 ) {
|
||||||
|
|
||||||
|
FD_ZERO( &readSet);
|
||||||
|
errorSet = writeSet = readSet;
|
||||||
|
|
||||||
|
FD_SET( m_pClientSocket->fd(), &readSet);
|
||||||
|
|
||||||
|
if (m_needsWriteSelect)
|
||||||
|
FD_SET( m_pClientSocket->fd(), &writeSet);
|
||||||
|
|
||||||
|
FD_SET( m_pClientSocket->fd(), &errorSet);
|
||||||
|
|
||||||
|
int ret = select( m_pClientSocket->fd() + 1, &readSet, &writeSet, &errorSet, &tval);
|
||||||
|
|
||||||
|
if( ret == 0) { // timeout
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ret < 0) { // error
|
||||||
|
m_pClientSocket->eDisconnect();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pClientSocket->fd() < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( FD_ISSET( m_pClientSocket->fd(), &errorSet)) {
|
||||||
|
// error on socket
|
||||||
|
m_pClientSocket->onError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pClientSocket->fd() < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( FD_ISSET( m_pClientSocket->fd(), &writeSet)) {
|
||||||
|
// socket is ready for writing
|
||||||
|
onSend();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pClientSocket->fd() < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( FD_ISSET( m_pClientSocket->fd(), &readSet)) {
|
||||||
|
// socket is ready for reading
|
||||||
|
onReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReader::onSend() {
|
||||||
|
m_pEReaderSignal->issueSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReader::onReceive() {
|
||||||
|
int nOffset = m_buf.size();
|
||||||
|
|
||||||
|
m_buf.resize(m_nMaxBufSize);
|
||||||
|
|
||||||
|
int nRes = m_pClientSocket->receive(m_buf.data() + nOffset, m_buf.size() - nOffset);
|
||||||
|
|
||||||
|
if (nRes <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_buf.resize(nRes + nOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EReader::bufferedRead(char *buf, int size) {
|
||||||
|
while (size > 0) {
|
||||||
|
while (m_buf.size() < size && m_buf.size() < m_nMaxBufSize)
|
||||||
|
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int nBytes = min(m_nMaxBufSize, size);
|
||||||
|
|
||||||
|
std::copy(m_buf.begin(), m_buf.begin() + nBytes, buf);
|
||||||
|
std::copy(m_buf.begin() + nBytes, m_buf.end(), m_buf.begin());
|
||||||
|
m_buf.resize(m_buf.size() - nBytes);
|
||||||
|
|
||||||
|
size -= nBytes;
|
||||||
|
buf += nBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMessage * EReader::readSingleMsg() {
|
||||||
|
if (m_pClientSocket->usingV100Plus()) {
|
||||||
|
int msgSize;
|
||||||
|
|
||||||
|
if (!bufferedRead((char *)&msgSize, sizeof(msgSize)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
msgSize = htonl(msgSize);
|
||||||
|
|
||||||
|
if (msgSize <= 0 || msgSize > MAX_MSG_LEN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::vector<char> buf = std::vector<char>(msgSize);
|
||||||
|
|
||||||
|
if (!bufferedRead(buf.data(), buf.size()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return new EMessage(buf);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *pBegin = 0;
|
||||||
|
const char *pEnd = 0;
|
||||||
|
int msgSize = 0;
|
||||||
|
|
||||||
|
while (msgSize == 0)
|
||||||
|
{
|
||||||
|
if (m_buf.size() >= m_nMaxBufSize * 3/4)
|
||||||
|
m_nMaxBufSize *= 2;
|
||||||
|
|
||||||
|
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pBegin = m_buf.data();
|
||||||
|
pEnd = pBegin + m_buf.size();
|
||||||
|
msgSize = EDecoder(m_pClientSocket->EClient::serverVersion(), &defaultWrapper).parseAndProcessMsg(pBegin, pEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> msgData(msgSize);
|
||||||
|
|
||||||
|
if (!bufferedRead(msgData.data(), msgSize))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (m_buf.size() < IN_BUF_SIZE_DEFAULT && m_buf.capacity() > IN_BUF_SIZE_DEFAULT)
|
||||||
|
{
|
||||||
|
m_buf.resize(m_nMaxBufSize = IN_BUF_SIZE_DEFAULT);
|
||||||
|
m_buf.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
EMessage * msg = new EMessage(msgData);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ibapi::shared_ptr<EMessage> EReader::getMsg(void) {
|
||||||
|
m_csMsgQueue.Enter();
|
||||||
|
|
||||||
|
if (m_msgQueue.size() == 0) {
|
||||||
|
m_csMsgQueue.Leave();
|
||||||
|
|
||||||
|
return ibapi::shared_ptr<EMessage>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ibapi::shared_ptr<EMessage> msg = m_msgQueue.front();
|
||||||
|
|
||||||
|
m_msgQueue.pop_front();
|
||||||
|
m_csMsgQueue.Leave();
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EReader::processMsgs(void) {
|
||||||
|
m_pClientSocket->onSend();
|
||||||
|
checkClient();
|
||||||
|
|
||||||
|
ibapi::shared_ptr<EMessage> msg = getMsg();
|
||||||
|
|
||||||
|
if (!msg.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char *pBegin = msg->begin();
|
||||||
|
|
||||||
|
while (processMsgsDecoder_.parseAndProcessMsg(pBegin, msg->end()) > 0) {
|
||||||
|
msg = getMsg();
|
||||||
|
|
||||||
|
if (!msg.get())
|
||||||
|
break;
|
||||||
|
|
||||||
|
pBegin = msg->begin();
|
||||||
|
}
|
||||||
|
}
|
58
vn.ib/ibapi/windows/client/EReader.h
Normal file
58
vn.ib/ibapi/windows/client/EReader.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "EDecoder.h"
|
||||||
|
#include "EMutex.h"
|
||||||
|
#include "EReaderOSSignal.h"
|
||||||
|
|
||||||
|
class EClientSocket;
|
||||||
|
class EReaderSignal;
|
||||||
|
class EMessage;
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EReader
|
||||||
|
{
|
||||||
|
EClientSocket *m_pClientSocket;
|
||||||
|
EReaderSignal *m_pEReaderSignal;
|
||||||
|
EDecoder processMsgsDecoder_;
|
||||||
|
std::deque<ibapi::shared_ptr<EMessage>> m_msgQueue;
|
||||||
|
EMutex m_csMsgQueue;
|
||||||
|
std::vector<char> m_buf;
|
||||||
|
bool m_needsWriteSelect;
|
||||||
|
bool m_isAlive;
|
||||||
|
#if defined(IB_WIN32)
|
||||||
|
HANDLE m_hReadThread;
|
||||||
|
#endif
|
||||||
|
int m_nMaxBufSize;
|
||||||
|
|
||||||
|
void onReceive();
|
||||||
|
void onSend();
|
||||||
|
bool bufferedRead(char *buf, int size);
|
||||||
|
|
||||||
|
public:
|
||||||
|
EReader(EClientSocket *clientSocket, EReaderSignal *signal);
|
||||||
|
~EReader(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool processNonBlockingSelect();
|
||||||
|
ibapi::shared_ptr<EMessage> getMsg(void);
|
||||||
|
void readToQueue();
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
static void * readToQueueThread(void * lpParam);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
static DWORD WINAPI readToQueueThread(LPVOID lpParam);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EMessage * readSingleMsg();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void processMsgs(void);
|
||||||
|
void checkClient();
|
||||||
|
bool putMessageToQueue();
|
||||||
|
void start();
|
||||||
|
};
|
||||||
|
|
73
vn.ib/ibapi/windows/client/EReaderOSSignal.cpp
Normal file
73
vn.ib/ibapi/windows/client/EReaderOSSignal.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "EReaderOSSignal.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MS_IN_SEC 1000
|
||||||
|
|
||||||
|
|
||||||
|
EReaderOSSignal::EReaderOSSignal(unsigned long waitTimeout) throw (std::runtime_error)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
m_waitTimeout = waitTimeout;
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
int rc1 = pthread_mutex_init(&m_mutex, NULL);
|
||||||
|
int rc2 = pthread_cond_init(&m_evMsgs, NULL);
|
||||||
|
ok = rc1 == 0 && rc2 == 0;
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
m_evMsgs = CreateEvent(0, false, false, 0);
|
||||||
|
ok = (NULL != m_evMsgs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
if (!ok)
|
||||||
|
throw std::runtime_error("Failed to create event");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EReaderOSSignal::~EReaderOSSignal(void)
|
||||||
|
{
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_cond_destroy(&m_evMsgs);
|
||||||
|
pthread_mutex_destroy(&m_mutex);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
CloseHandle(m_evMsgs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EReaderOSSignal::issueSignal() {
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
pthread_cond_signal(&m_evMsgs);
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
SetEvent(m_evMsgs);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReaderOSSignal::waitForSignal() {
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_mutex_lock(&m_mutex);
|
||||||
|
if ( m_waitTimeout == INFINITE ) {
|
||||||
|
pthread_cond_wait(&m_evMsgs, &m_mutex);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = m_waitTimeout/MS_IN_SEC;
|
||||||
|
ts.tv_nsec = (m_waitTimeout%MS_IN_SEC)*1000/*us/ms*/*1000/*ns/us*/;
|
||||||
|
pthread_cond_timedwait(&m_evMsgs, &m_mutex, &ts);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&m_mutex);
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
WaitForSingleObject(m_evMsgs, m_waitTimeout);
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
33
vn.ib/ibapi/windows/client/EReaderOSSignal.h
Normal file
33
vn.ib/ibapi/windows/client/EReaderOSSignal.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "EReaderSignal.h"
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#if !defined(INFINITE)
|
||||||
|
#define INFINITE ((unsigned long)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TWSAPIDLLEXP EReaderOSSignal :
|
||||||
|
public EReaderSignal
|
||||||
|
{
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
pthread_cond_t m_evMsgs;
|
||||||
|
pthread_mutex_t m_mutex;
|
||||||
|
#elif defined(IB_WIN32)
|
||||||
|
HANDLE m_evMsgs;
|
||||||
|
#else
|
||||||
|
# error "Not implemented on this platform"
|
||||||
|
#endif
|
||||||
|
unsigned long m_waitTimeout; // in milliseconds
|
||||||
|
|
||||||
|
public:
|
||||||
|
EReaderOSSignal(unsigned long waitTimeout = INFINITE) throw (std::runtime_error);
|
||||||
|
~EReaderOSSignal(void);
|
||||||
|
|
||||||
|
virtual void issueSignal();
|
||||||
|
virtual void waitForSignal();
|
||||||
|
};
|
||||||
|
|
10
vn.ib/ibapi/windows/client/EReaderSignal.h
Normal file
10
vn.ib/ibapi/windows/client/EReaderSignal.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
struct EReaderSignal
|
||||||
|
{
|
||||||
|
virtual void issueSignal() = 0;
|
||||||
|
virtual void waitForSignal() = 0;
|
||||||
|
};
|
||||||
|
|
25
vn.ib/ibapi/windows/client/EReaderWMSignal.cpp
Normal file
25
vn.ib/ibapi/windows/client/EReaderWMSignal.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#if defined(IB_WIN32)
|
||||||
|
#include "EReaderWMSignal.h"
|
||||||
|
|
||||||
|
|
||||||
|
EReaderWMSignal::EReaderWMSignal(HWND hWnd, int wmUserOffset) {
|
||||||
|
m_hWnd = hWnd;
|
||||||
|
m_msg = WM_USER + wmUserOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReaderWMSignal::issueSignal() {
|
||||||
|
if (IsWindow(m_hWnd))
|
||||||
|
PostMessage(m_hWnd, m_msg, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EReaderWMSignal::waitForSignal() {
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
if (GetMessage(&msg, 0, m_msg, m_msg))
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
#endif
|
19
vn.ib/ibapi/windows/client/EReaderWMSignal.h
Normal file
19
vn.ib/ibapi/windows/client/EReaderWMSignal.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms
|
||||||
|
* and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "ereadersignal.h"
|
||||||
|
|
||||||
|
class EReaderWMSignal :
|
||||||
|
public EReaderSignal
|
||||||
|
{
|
||||||
|
HWND m_hWnd;
|
||||||
|
int m_msg;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EReaderWMSignal(HWND hWnd, int msg);
|
||||||
|
|
||||||
|
virtual void issueSignal();
|
||||||
|
virtual void waitForSignal();
|
||||||
|
};
|
||||||
|
|
102
vn.ib/ibapi/windows/client/ESocket.cpp
Normal file
102
vn.ib/ibapi/windows/client/ESocket.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "EMessage.h"
|
||||||
|
#include "ESocket.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if defined(IB_POSIX)
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESocket::ESocket() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESocket::fd(int fd) {
|
||||||
|
m_fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESocket::~ESocket(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESocket::send(EMessage *pMsg) {
|
||||||
|
return bufferedSend(pMsg->begin(), pMsg->end() - pMsg->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESocket::bufferedSend(const char* buf, size_t sz)
|
||||||
|
{
|
||||||
|
if( sz <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( !m_outBuffer.empty()) {
|
||||||
|
m_outBuffer.insert( m_outBuffer.end(), buf, buf + sz);
|
||||||
|
return sendBufferedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nResult = send(buf, sz);
|
||||||
|
|
||||||
|
if( nResult < (int)sz) {
|
||||||
|
int sent = (std::max)( nResult, 0);
|
||||||
|
m_outBuffer.insert( m_outBuffer.end(), buf + sent, buf + sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESocket::sendBufferedData()
|
||||||
|
{
|
||||||
|
if( m_outBuffer.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int nResult = send( &m_outBuffer[0], m_outBuffer.size());
|
||||||
|
if( nResult <= 0) {
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
CleanupBuffer( m_outBuffer, nResult);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESocket::send(const char* buf, size_t sz)
|
||||||
|
{
|
||||||
|
if( sz <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int nResult = ::send( m_fd, buf, sz, 0);
|
||||||
|
|
||||||
|
if( nResult == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if( nResult <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t BufferSizeHighMark = 1 * 1024 * 1024; // 1Mb
|
||||||
|
|
||||||
|
void ESocket::CleanupBuffer(std::vector<char>& buffer, int processed)
|
||||||
|
{
|
||||||
|
assert( buffer.empty() || processed <= (int)buffer.size());
|
||||||
|
|
||||||
|
if( buffer.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( processed <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( (size_t)processed == buffer.size()) {
|
||||||
|
if( buffer.capacity() >= BufferSizeHighMark) {
|
||||||
|
std::vector<char>().swap(buffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
buffer.erase( buffer.begin(), buffer.begin() + processed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ESocket::isOutBufferEmpty() const
|
||||||
|
{
|
||||||
|
return m_outBuffer.empty();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user