/* 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 #include #include #include #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 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 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 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(std::ostream& os, bool); template<> void EClient::EncodeField(std::ostream& os, double); #define ENCODE_FIELD(x) EClient::EncodeField(msg, x); #define ENCODE_FIELD_MAX(x) EClient::EncodeFieldMax(msg, x); #endif