├── TwsApiC++ ├── Test │ ├── _cygwin │ │ ├── run │ │ ├── debug │ │ │ └── .gitignore │ │ ├── compile │ │ └── makefile │ ├── _linux │ │ ├── run │ │ ├── debug │ │ │ └── .gitignore │ │ ├── compile │ │ └── makefile │ ├── Src │ │ ├── Empty.cpp │ │ ├── Clients.cpp │ │ ├── Bars.cpp │ │ ├── History.cpp │ │ └── Test.cpp │ ├── CMakeLists.txt │ └── _win32 │ │ └── Test.vcproj ├── _cygwin │ ├── debug │ │ └── .gitignore │ └── makefile ├── _linux │ ├── debug │ │ └── .gitignore │ └── makefile ├── Src │ ├── afxwin.h │ └── TwsApiL0.cpp ├── Api │ ├── CMakeLists.txt │ ├── Enumerations.h │ └── TwsApiL0.h ├── CMakeLists.txt ├── _win32 │ ├── TwsApi.sln │ └── TwsApi.vcproj └── Readme.txt ├── .gitignore ├── source └── PosixClient │ ├── src │ ├── EClientSocketBase.cpp │ ├── EPosixClientSocket.h │ ├── EPosixClientSocketPlatform.h │ └── EPosixClientSocket.cpp │ └── Shared │ ├── StdAfx.h │ ├── TagValue.h │ ├── CommissionReport.h │ ├── OrderState.h │ ├── CommonDefs.h │ ├── Execution.h │ ├── ScannerSubscription.h │ ├── IBString.h │ ├── TwsSocketClientErrors.h │ ├── shared_ptr.h │ ├── EClient.h │ ├── Contract.h │ ├── EWrapper.h │ ├── EClientSocketBase.h │ └── Order.h └── README.md /TwsApiC++/Test/_cygwin/run: -------------------------------------------------------------------------------- 1 | ./compile 2 | ./debug/test.exe -------------------------------------------------------------------------------- /TwsApiC++/Test/_linux/run: -------------------------------------------------------------------------------- 1 | # Test run 2 | #!/bin/sh 3 | ./compile 4 | ./debug/test.exe 5 | -------------------------------------------------------------------------------- /TwsApiC++/_cygwin/debug/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /TwsApiC++/_linux/debug/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /TwsApiC++/Test/_cygwin/debug/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /TwsApiC++/Test/_linux/debug/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.obj 2 | *.exe 3 | *.a 4 | source/PosixClient/Shared/HScrollListBox.cpp 5 | source/PosixClient/Shared/HScrollListBox.h 6 | *.suo -------------------------------------------------------------------------------- /TwsApiC++/Test/_cygwin/compile: -------------------------------------------------------------------------------- 1 | Echo === Making lib === 2 | cd ../../_cygwin 3 | make 4 | echo 5 | echo 6 | echo 7 | Echo === Making test === 8 | cd ../test/_cygwin 9 | make all 10 | -------------------------------------------------------------------------------- /source/PosixClient/src/EClientSocketBase.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #include "EClientSocketBaseImpl.h" 5 | 6 | -------------------------------------------------------------------------------- /TwsApiC++/Test/_linux/compile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Compile the linux library first 3 | # then compile the tests 4 | echo === Making lib === 5 | echo cd ../../_linux 6 | cd ../../_linux 7 | echo make 8 | /usr/bin/make 9 | echo 10 | echo === Making test === 11 | echo cd ../Test/_linux 12 | cd ../Test/_linux 13 | echo make 14 | /usr/bin/make 15 | 16 | -------------------------------------------------------------------------------- /TwsApiC++/Src/afxwin.h: -------------------------------------------------------------------------------- 1 | #ifndef _afxwin_h_ 2 | #define _afxwin_h_ 3 | //---------------------------------------------------------------------------- 4 | // Replacement for the windows afxwin.h include file 5 | //---------------------------------------------------------------------------- 6 | #define CorrectAfxWinIncluded 7 | 8 | // To cut the windows specific paths in EClientSocketBaseImpl.h 9 | #undef _MSC_VER 10 | 11 | #endif _afxwin_h_ 12 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/StdAfx.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef DLLEXP 5 | #define DLLEXP __declspec( dllexport ) 6 | #endif 7 | 8 | #ifdef _MSC_VER 9 | 10 | #define assert ASSERT 11 | #define snprintf _snprintf 12 | 13 | #include 14 | 15 | #endif 16 | 17 | -------------------------------------------------------------------------------- /TwsApiC++/Test/Src/Empty.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // TwsApi Empty 3 | //============================================================================ 4 | #include "TwsApiL0.h" 5 | //#include "TwsApiDefs.h" 6 | //using namespace TwsApi; 7 | 8 | class MyEWrapper: public EWrapperL0 9 | { 10 | }; 11 | 12 | 13 | 14 | int main( void ) 15 | { 16 | MyEWrapper MW; 17 | EClientL0* EC = EClientL0::New( &MW ); 18 | 19 | delete EC; 20 | } 21 | -------------------------------------------------------------------------------- /TwsApiC++/Api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(TWSAPI VERSION 9.71.0) 2 | 3 | set(LIBRARY_NAME tws_cpp_api) 4 | 5 | set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../Src) 6 | 7 | file(GLOB SOURCES ${SRC_DIR}/*.cpp) 8 | 9 | add_definitions(-D_REENTRANT -D_DEBUG) 10 | 11 | include_directories(${API_INCLUDE_DIR} ${SRC_DIR} 12 | ${IB_POSIX_CLIENT_INCLUDE_DIR} ${IB_POSIX_CLIENT_SOURCE_DIR}) 13 | 14 | add_library(${LIBRARY_NAME} ${API_INCLUDES} ${SOURCES} 15 | ${IB_POSIX_CLIENT_SOURCES} ${IB_POSIX_CLIENT_INCLUDES}) 16 | set_source_files_properties(${API_INCLUDES} ${IB_POSIX_CLIENT_INCLUDES} ${IB_POSIX_CLIENT_SOURCES} 17 | PROPERTIES HEADER_FILE_ONLY TRUE) 18 | target_compile_options(${LIBRARY_NAME} PRIVATE -Wall PUBLIC -std=gnu++0x) 19 | -------------------------------------------------------------------------------- /TwsApiC++/_cygwin/makefile: -------------------------------------------------------------------------------- 1 | # TwsApiC++ Debug Version 2 | 3 | CC = gcc 4 | INCLUDE = -I../Api -I../Src -I../../source/PosixClient/Shared -I../../source/PosixClient/src 5 | CFLAGS = -mthreads -D_REENTRANT -D_DEBUG 6 | 7 | ../Api/libTwsApiL0D.a: ../Api/TwsApiL0.h ../Api/TwsApiDefs.h ../Api/Enumerations.h ../Src/afxwin.h ../Src/TwsApiL0.cpp ../../source/PosixClient/src/EClientSocketBase.cpp ../../source/PosixClient/src/EPosixClientSocket.cpp ../../source/PosixClient/src/EPosixClientSocket.h ../../source/PosixClient/src/EPosixClientSocketPlatform.h 8 | $(CC) $(INCLUDE) $(CFLAGS) -c ../Src/TwsApiL0.cpp -o ./debug/TwsApiL0.o 9 | ar rcs ../Api/libTwsApiL0D.a ./debug/TwsApiL0.o 10 | 11 | clean: 12 | rm -f ../Api/libTwsApiL0D.a ./debug/TwsApiL0.o 13 | -------------------------------------------------------------------------------- /TwsApiC++/_linux/makefile: -------------------------------------------------------------------------------- 1 | # TwsApiC++ Debug Version 2 | 3 | CC = gcc 4 | INCLUDE = -I../Api -I../Src -I../../source/PosixClient/Shared -I../../source/PosixClient/src 5 | CFLAGS = -D_REENTRANT -D_DEBUG -ggdb -std=gnu++0x -Wall 6 | 7 | ../Api/libTwsApiL0D.a: ../Api/TwsApiL0.h ../Api/TwsApiDefs.h ../Api/Enumerations.h ../Src/TwsApiL0.cpp ../../source/PosixClient/src/EClientSocketBase.cpp ../../source/PosixClient/src/EPosixClientSocket.cpp ../../source/PosixClient/src/EPosixClientSocket.h ../../source/PosixClient/src/EPosixClientSocketPlatform.h 8 | $(CC) $(INCLUDE) $(CFLAGS) -c ../Src/TwsApiL0.cpp -o ./debug/TwsApiL0.o 9 | ar rcs ../Api/libTwsApiL0D.a ./debug/TwsApiL0.o 10 | 11 | clean: 12 | rm -f ../Api/libTwsApiL0D.a ./debug/TwsApiL0.o 13 | 14 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/TagValue.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef tagvalue_def 5 | #define tagvalue_def 6 | 7 | #include "shared_ptr.h" 8 | #include "IBString.h" 9 | 10 | #include 11 | 12 | struct TagValue 13 | { 14 | TagValue() {} 15 | TagValue(const IBString& p_tag, const IBString& p_value) 16 | : tag(p_tag), value(p_value) 17 | {} 18 | 19 | IBString tag; 20 | IBString value; 21 | }; 22 | 23 | typedef shared_ptr TagValueSPtr; 24 | typedef std::vector TagValueList; 25 | typedef shared_ptr TagValueListSPtr; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/CommissionReport.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef commissionreport_def 5 | #define commissionreport_def 6 | 7 | #include "IBString.h" 8 | 9 | struct CommissionReport 10 | { 11 | CommissionReport() 12 | { 13 | commission = 0; 14 | realizedPNL = 0; 15 | yield = 0; 16 | yieldRedemptionDate = 0; 17 | } 18 | 19 | // commission report fields 20 | IBString execId; 21 | double commission; 22 | IBString currency; 23 | double realizedPNL; 24 | double yield; 25 | int yieldRedemptionDate; // YYYYMMDD format 26 | }; 27 | 28 | #endif // commissionreport_def 29 | -------------------------------------------------------------------------------- /TwsApiC++/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.1.0) 2 | 3 | #---------------------------- 4 | # CMAKE DEBUGING 5 | #---------------------------- 6 | 7 | # Display a variable. 8 | macro(display var) 9 | message(STATUS "${var}: " ${${var}}) 10 | endmacro() 11 | 12 | #---------------------------- 13 | 14 | set(API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Api) 15 | set(IB_POSIX_CLIENT_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../source/PosixClient) 16 | set(IB_POSIX_CLIENT_INCLUDE_DIR ${IB_POSIX_CLIENT_SRC}/Shared) 17 | set(IB_POSIX_CLIENT_SOURCE_DIR ${IB_POSIX_CLIENT_SRC}/src) 18 | 19 | file(GLOB IB_POSIX_CLIENT_SOURCES ${IB_POSIX_CLIENT_SOURCE_DIR}/*) 20 | file(GLOB IB_POSIX_CLIENT_INCLUDES ${IB_POSIX_CLIENT_INCLUDE_DIR}/*.h) 21 | file(GLOB API_INCLUDES ${API_INCLUDE_DIR}/*.h) 22 | 23 | add_subdirectory(Api) 24 | add_subdirectory(Test) -------------------------------------------------------------------------------- /source/PosixClient/Shared/OrderState.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef ORDER_STATE_H__INCLUDED 5 | #define ORDER_STATE_H__INCLUDED 6 | 7 | #include "Order.h" 8 | 9 | struct OrderState { 10 | 11 | explicit OrderState() 12 | : 13 | commission(UNSET_DOUBLE), 14 | minCommission(UNSET_DOUBLE), 15 | maxCommission(UNSET_DOUBLE) 16 | {} 17 | 18 | IBString status; 19 | 20 | IBString initMargin; 21 | IBString maintMargin; 22 | IBString equityWithLoan; 23 | 24 | double commission; 25 | double minCommission; 26 | double maxCommission; 27 | IBString commissionCurrency; 28 | 29 | IBString warningText; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /TwsApiC++/Test/_linux/makefile: -------------------------------------------------------------------------------- 1 | # TwsApiC++ Debug Version 2 | 3 | CC = gcc 4 | INCLUDE = -I../../Api -I../../../source/PosixClient/Shared 5 | CFLAGS = -D_REENTRANT -D_DEBUG -ggdb -Wall 6 | LIBS = -L../../Api -lTwsApiL0D -lstdc++ -lpthread 7 | 8 | Test: ../Src/Test.cpp ../../Api/libTwsApiL0D.a 9 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Test.cpp $(LIBS) -o ./debug/Test 10 | 11 | History: ../Src/History.cpp ../../Api/libTwsApiL0D.a 12 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/History.cpp $(LIBS) -o ./debug/History 13 | 14 | Bars: ../Src/Bars.cpp ../../Api/libTwsApiL0D.a 15 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Bars.cpp $(LIBS) -o ./debug/Bars 16 | 17 | Clients: ../Src/Clients.cpp ../../Api/libTwsApiL0D.a 18 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Clients.cpp $(LIBS) -o ./debug/Clients 19 | 20 | all: Test History Bars Clients 21 | 22 | clean: 23 | rm -f ./debug/* -------------------------------------------------------------------------------- /TwsApiC++/Test/_cygwin/makefile: -------------------------------------------------------------------------------- 1 | # Test Debug Version 2 | 3 | CC = gcc 4 | INCLUDE = -I../../Api -I../../../source/PosixClient/Shared 5 | CFLAGS = -mthreads -mconsole -D_REENTRANT -D_DEBUG 6 | LIBS = -L../../Api -lTwsApiL0D -lstdc++ 7 | 8 | Test: ../Src/Test.cpp ../../Api/libTwsApiL0D.a 9 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Test.cpp $(LIBS) -o ./debug/Test.exe 10 | 11 | History: ../Src/History.cpp ../../Api/libTwsApiL0D.a 12 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/History.cpp $(LIBS) -o ./debug/History.exe 13 | 14 | Bars: ../Src/Bars.cpp ../../Api/libTwsApiL0D.a 15 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Bars.cpp $(LIBS) -o ./debug/Bars.exe 16 | 17 | Clients: ../Src/Clients.cpp ../../Api/libTwsApiL0D.a 18 | $(CC) $(INCLUDE) $(CFLAGS) ../Src/Clients.cpp $(LIBS) -o ./debug/Clients.exe 19 | 20 | all: Test History Bars Clients 21 | 22 | clean: 23 | rm -f ./debug/* -------------------------------------------------------------------------------- /source/PosixClient/Shared/CommonDefs.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef common_defs_h_INCLUDED 5 | #define common_defs_h_INCLUDED 6 | 7 | typedef long TickerId; 8 | typedef long OrderId; 9 | 10 | enum faDataType { GROUPS=1, PROFILES, ALIASES } ; 11 | 12 | inline const char* faDataTypeStr ( faDataType pFaDataType ) 13 | { 14 | switch (pFaDataType) { 15 | case GROUPS: 16 | return "GROUPS" ; 17 | break ; 18 | case PROFILES: 19 | return "PROFILES" ; 20 | break ; 21 | case ALIASES: 22 | return "ALIASES" ; 23 | break ; 24 | } 25 | return 0 ; 26 | } 27 | 28 | enum MarketDataType { 29 | REALTIME = 1, 30 | FROZEN = 2 31 | }; 32 | 33 | #endif /* common_defs_h_INCLUDED */ 34 | -------------------------------------------------------------------------------- /TwsApiC++/Test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(TWSAPICPP_TEST VERSION 1.0.0) 2 | 3 | set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Src) 4 | 5 | add_definitions(-D_REENTRANT -D_DEBUG) 6 | 7 | set(THREADS_PREFER_PTHREAD_FLAG ON) 8 | find_package(Threads REQUIRED) 9 | 10 | include_directories(${API_INCLUDE_DIR} ${IB_POSIX_CLIENT_INCLUDE_DIR}) 11 | 12 | add_executable(Test ${SOURCE_DIR}/Test.cpp) 13 | target_link_libraries(Test tws_cpp_api Threads::Threads) 14 | target_compile_options(Test PRIVATE -Wall) 15 | 16 | add_executable(History ${SOURCE_DIR}/History.cpp) 17 | target_link_libraries(History tws_cpp_api Threads::Threads) 18 | target_compile_options(History PRIVATE -Wall) 19 | 20 | add_executable(Bars ${SOURCE_DIR}/Bars.cpp) 21 | target_link_libraries(Bars tws_cpp_api Threads::Threads) 22 | target_compile_options(Bars PRIVATE -Wall) 23 | 24 | add_executable(Clients ${SOURCE_DIR}/Clients.cpp) 25 | target_link_libraries(Clients tws_cpp_api Threads::Threads) 26 | target_compile_options(Clients PRIVATE -Wall) -------------------------------------------------------------------------------- /source/PosixClient/Shared/Execution.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef execution_def 5 | #define execution_def 6 | 7 | #include "IBString.h" 8 | 9 | struct Execution 10 | { 11 | Execution() 12 | { 13 | shares = 0; 14 | price = 0; 15 | permId = 0; 16 | clientId = 0; 17 | orderId = 0; 18 | cumQty = 0; 19 | avgPrice = 0; 20 | evMultiplier = 0; 21 | } 22 | 23 | IBString execId; 24 | IBString time; 25 | IBString acctNumber; 26 | IBString exchange; 27 | IBString side; 28 | int shares; 29 | double price; 30 | int permId; 31 | long clientId; 32 | long orderId; 33 | int liquidation; 34 | int cumQty; 35 | double avgPrice; 36 | IBString orderRef; 37 | IBString evRule; 38 | double evMultiplier; 39 | }; 40 | 41 | struct ExecutionFilter 42 | { 43 | ExecutionFilter() 44 | : m_clientId(0) 45 | { 46 | } 47 | 48 | // Filter fields 49 | long m_clientId; 50 | IBString m_acctCode; 51 | IBString m_time; 52 | IBString m_symbol; 53 | IBString m_secType; 54 | IBString m_exchange; 55 | IBString m_side; 56 | }; 57 | 58 | #endif // execution_def 59 | -------------------------------------------------------------------------------- /source/PosixClient/src/EPosixClientSocket.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef eposixclientsocket_def 5 | #define eposixclientsocket_def 6 | 7 | #include "EClientSocketBase.h" 8 | 9 | class EWrapper; 10 | 11 | class EPosixClientSocket : public EClientSocketBase 12 | { 13 | public: 14 | 15 | //(4 march 2013) JBOO: give access to private members; replaces '#define private public' in TwsApiL0.cpp 16 | friend struct EClientL0Impl; 17 | 18 | explicit EPosixClientSocket( EWrapper *ptr); 19 | ~EPosixClientSocket(); 20 | 21 | // override virtual funcs from EClient 22 | bool eConnect( const char *host, unsigned int port, int clientId = 0, bool extraAuth = false); 23 | void eDisconnect(); 24 | 25 | bool isSocketOK() const; 26 | int fd() const; 27 | 28 | private: 29 | 30 | int send( const char* buf, size_t sz); 31 | int receive( char* buf, size_t sz); 32 | 33 | public: 34 | // callback from socket 35 | void onReceive(); 36 | void onSend(); 37 | void onError(); 38 | 39 | private: 40 | 41 | void onConnect(); 42 | void onClose(); 43 | 44 | public: 45 | // helper 46 | bool handleSocketError(); 47 | 48 | private: 49 | 50 | int m_fd; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/ScannerSubscription.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef scanner_def 5 | #define scanner_def 6 | 7 | #include 8 | #include 9 | 10 | #include "IBString.h" 11 | 12 | #define UNSET_DOUBLE DBL_MAX 13 | #define UNSET_INTEGER INT_MAX 14 | #define NO_ROW_NUMBER_SPECIFIED -1; 15 | 16 | struct ScannerSubscription { 17 | ScannerSubscription() { 18 | numberOfRows = NO_ROW_NUMBER_SPECIFIED; 19 | abovePrice = DBL_MAX; 20 | belowPrice = DBL_MAX; 21 | aboveVolume = INT_MAX; 22 | marketCapAbove = DBL_MAX; 23 | marketCapBelow = DBL_MAX; 24 | couponRateAbove = DBL_MAX; 25 | couponRateBelow = DBL_MAX; 26 | excludeConvertible = 0; 27 | averageOptionVolumeAbove = 0; 28 | } 29 | int numberOfRows; 30 | IBString instrument; 31 | IBString locationCode; 32 | IBString scanCode; 33 | double abovePrice; 34 | double belowPrice; 35 | int aboveVolume; 36 | double marketCapAbove; 37 | double marketCapBelow; 38 | IBString moodyRatingAbove; 39 | IBString moodyRatingBelow; 40 | IBString spRatingAbove; 41 | IBString spRatingBelow; 42 | IBString maturityDateAbove; 43 | IBString maturityDateBelow; 44 | double couponRateAbove; 45 | double couponRateBelow; 46 | int excludeConvertible; 47 | int averageOptionVolumeAbove; 48 | IBString scannerSettingPairs; 49 | IBString stockTypeFilter; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/IBString.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef ibstring_h__INCLUDED 5 | #define ibstring_h__INCLUDED 6 | 7 | #ifdef IB_USE_STD_STRING 8 | #include 9 | typedef std::string IBString; 10 | #else 11 | #include 12 | typedef CString IBString; 13 | #endif 14 | 15 | #include 16 | 17 | inline bool IsEmpty(const IBString& str) 18 | { 19 | #ifdef IB_USE_STD_STRING 20 | return str.empty(); 21 | #else 22 | return str.IsEmpty(); 23 | #endif 24 | }; 25 | 26 | inline void Empty(IBString& str) 27 | { 28 | #ifdef IB_USE_STD_STRING 29 | str.erase(); 30 | #else 31 | str.Empty(); 32 | #endif 33 | }; 34 | 35 | inline bool Compare(IBString str, const char* strToCompare) 36 | { 37 | #ifdef IB_USE_STD_STRING 38 | return str.compare(strToCompare); 39 | #else 40 | return str.CompareNoCase(strToCompare); 41 | #endif 42 | }; 43 | 44 | inline bool Compare(IBString str, IBString strToCompare) 45 | { 46 | #ifdef IB_USE_STD_STRING 47 | return str.compare(strToCompare); 48 | #else 49 | return str.CompareNoCase(strToCompare); 50 | #endif 51 | }; 52 | 53 | inline double Atof(IBString str) 54 | { 55 | #ifdef IB_USE_STD_STRING 56 | return atof(str.c_str()); 57 | #else 58 | return atof(str); 59 | #endif 60 | }; 61 | 62 | inline int Atoi(IBString str) 63 | { 64 | #ifdef IB_USE_STD_STRING 65 | return atoi(str.c_str()); 66 | #else 67 | return atoi(str); 68 | #endif 69 | }; 70 | 71 | #endif 72 | 73 | 74 | -------------------------------------------------------------------------------- /TwsApiC++/_win32/TwsApi.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2013 3 | VisualStudioVersion = 12.0.31101.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "..\Test\_win32\Test.vcproj", "{41D54FBD-2C52-4D65-9D0D-04413CA894B0}" 6 | ProjectSection(ProjectDependencies) = postProject 7 | {C03E5CCA-3552-42F2-B865-494FAD99974C} = {C03E5CCA-3552-42F2-B865-494FAD99974C} 8 | EndProjectSection 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TwsApi", "TwsApi.vcproj", "{C03E5CCA-3552-42F2-B865-494FAD99974C}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Win32 = Debug|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {41D54FBD-2C52-4D65-9D0D-04413CA894B0}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {41D54FBD-2C52-4D65-9D0D-04413CA894B0}.Debug|Win32.Build.0 = Debug|Win32 20 | {41D54FBD-2C52-4D65-9D0D-04413CA894B0}.Release|Win32.ActiveCfg = Release|Win32 21 | {41D54FBD-2C52-4D65-9D0D-04413CA894B0}.Release|Win32.Build.0 = Release|Win32 22 | {C03E5CCA-3552-42F2-B865-494FAD99974C}.Debug|Win32.ActiveCfg = Debug|Win32 23 | {C03E5CCA-3552-42F2-B865-494FAD99974C}.Debug|Win32.Build.0 = Debug|Win32 24 | {C03E5CCA-3552-42F2-B865-494FAD99974C}.Release|Win32.ActiveCfg = Release|Win32 25 | {C03E5CCA-3552-42F2-B865-494FAD99974C}.Release|Win32.Build.0 = Release|Win32 26 | EndGlobalSection 27 | GlobalSection(SolutionProperties) = preSolution 28 | HideSolutionNode = FALSE 29 | EndGlobalSection 30 | EndGlobal 31 | -------------------------------------------------------------------------------- /source/PosixClient/src/EPosixClientSocketPlatform.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef eposixclientsocketcommon_def 5 | #define eposixclientsocketcommon_def 6 | 7 | #ifdef _WIN32 8 | // Windows 9 | // includes 10 | #include 11 | #include 12 | 13 | // defines 14 | #define EISCONN WSAEISCONN 15 | #define EWOULDBLOCK WSAEWOULDBLOCK 16 | #define ECONNREFUSED WSAECONNREFUSED 17 | 18 | // helpers 19 | inline bool SocketsInit( void) { 20 | WSADATA data; 21 | return ( !WSAStartup( MAKEWORD(2, 2), &data)); 22 | }; 23 | inline bool SocketsDestroy() { return ( !WSACleanup()); }; 24 | inline int SocketClose(int sockfd) { return closesocket( sockfd); }; 25 | 26 | inline bool SetSocketNonBlocking(int sockfd) { 27 | unsigned long mode = 1; 28 | return ( ioctlsocket( sockfd, FIONBIO, &mode) == 0); 29 | }; 30 | 31 | #else 32 | // LINUX 33 | // includes 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | // helpers 41 | inline bool SocketsInit() { return true; }; 42 | inline bool SocketsDestroy() { return true; }; 43 | inline int SocketClose(int sockfd) { return close( sockfd); }; 44 | 45 | inline bool SetSocketNonBlocking(int sockfd) { 46 | // get socket flags 47 | int flags = fcntl(sockfd, F_GETFL); 48 | if (flags == -1) 49 | return false; 50 | 51 | // set non-blocking mode 52 | return ( fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == 0); 53 | }; 54 | 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/TwsSocketClientErrors.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef tswsocketclienterrors_def 5 | #define tswsocketclienterrors_def 6 | 7 | static const int NO_VALID_ID = -1; 8 | static const int NO_VALID_ERROR_CODE = 0; 9 | static const int SYSTEM_ERROR = 600; 10 | 11 | class CodeMsgPair { 12 | public: 13 | CodeMsgPair(int code, IBString msg) : m_errorCode(code), m_errorMsg(msg) { 14 | } 15 | private: 16 | int m_errorCode; 17 | IBString m_errorMsg; 18 | public: 19 | int code() const { return m_errorCode; } 20 | const IBString& msg() const { return m_errorMsg; } 21 | }; 22 | 23 | static const CodeMsgPair ALREADY_CONNECTED(501, "Already connected."); 24 | static const CodeMsgPair CONNECT_FAIL(502, "Couldn't connect to TWS. Confirm that \"Enable ActiveX and Socket Clients\" is enabled on the TWS \"Configure->API\" menu."); 25 | static const CodeMsgPair UPDATE_TWS(503, "The TWS is out of date and must be upgraded."); 26 | static const CodeMsgPair NOT_CONNECTED(504, "Not connected"); 27 | static const CodeMsgPair UNKNOWN_ID(505, "Fatal Error: Unknown message id."); 28 | static const CodeMsgPair ZERO_BYTE_READ(506, "Unexplained zero bytes read."); 29 | static const CodeMsgPair NULL_STRING_READ(507, "Null string read when expecting integer"); 30 | static const CodeMsgPair NO_BYTES_READ(508, "Error: no bytes read or no null terminator found"); 31 | static const CodeMsgPair SOCKET_EXCEPTION(509, "Exception caught while reading socket - "); 32 | static const CodeMsgPair FAIL_CREATE_SOCK(520, "Failed to create socket"); 33 | static const CodeMsgPair FAIL_CONNECT_TWS(521, "Couldn't connect to TWS."); 34 | static const CodeMsgPair FAIL_SEND_FA_REQUEST(522, "FA Information Request Sending Error - "); 35 | static const CodeMsgPair FAIL_SEND_FA_REPLACE(523, "FA Information Replace Sending Error - "); 36 | static const CodeMsgPair FAIL_SEND_REQSCANNER(524, "Request Scanner Subscription Sending Error - "); 37 | static const CodeMsgPair FAIL_SEND_CANSCANNER(525, "Cancel Scanner Subscription Sending Error - "); 38 | static const CodeMsgPair FAIL_SEND_REQSCANNERPARAMETERS(526, "Request Scanner Parameter Sending Error - "); 39 | static const CodeMsgPair FAIL_SEND_REQHISTDATA(527, "Request Historical Data Sending Error - "); 40 | static const CodeMsgPair FAIL_SEND_CANHISTDATA(528, "Cancel Historical Data Sending Error - "); 41 | static const CodeMsgPair FAIL_SEND_REQRTBARS(529, "Request Real-time Bar Data Sending Error - "); 42 | static const CodeMsgPair FAIL_SEND_CANRTBARS(530, "Cancel Real-time Bar Data Sending Error - "); 43 | static const CodeMsgPair FAIL_SEND_REQCURRTIME(531, "Request Current Time Sending Error - "); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/shared_ptr.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef shared_ptr_h_INCLUDED 5 | #define shared_ptr_h_INCLUDED 6 | 7 | // 8 | // Implements a subset of shared_prt found at www.boost.org. 9 | // Uses a singly linked circular list instead of a reference counter. 10 | // Avoids extra heap allocation needed to get a shared reference counter, 11 | // but sizeof(shared_ptr) == sizeof(void*) * 3 compared to sizeof(void*) * 2 12 | // 13 | // See "Handles and Exception Safety, Part 4: Tracking References without Counters" 14 | // by Andrew Koenig and Barbara E. Moo, Feb. 2003 C++ Users Journal 15 | // 16 | namespace shared_ptr_defs { 17 | 18 | class Use { 19 | public: 20 | 21 | Use() { forward_ = this; back_ = this; } 22 | ~Use() { remove(); } 23 | 24 | Use(const Use& u) { insert(u); } 25 | Use& operator=(const Use& u) 26 | { 27 | if (this != &u) { 28 | remove(); 29 | insert(u); 30 | } 31 | return *this; 32 | } 33 | bool only() const { return this == this->forward_; } 34 | private: 35 | mutable const Use *forward_; 36 | mutable const Use *back_; 37 | 38 | void insert(const Use& u) const { 39 | this->back_ = &u; 40 | this->forward_ = u.forward_; 41 | u.forward_->back_ = this; 42 | u.forward_ = this; 43 | } 44 | 45 | void remove() const { 46 | this->forward_->back_ = this->back_; 47 | this->back_->forward_ = this->forward_; 48 | } 49 | }; 50 | 51 | } // end of namespace shared_ptr_defs 52 | 53 | template class shared_ptr { 54 | public: 55 | 56 | typedef shared_ptr_defs::Use Use; 57 | 58 | template friend class shared_ptr; 59 | 60 | explicit shared_ptr(X* ptr = 0) : ptr_(ptr) {} 61 | 62 | ~shared_ptr() { if (use_.only()) delete ptr_; } 63 | 64 | template 65 | shared_ptr(const shared_ptr& other) 66 | : ptr_(other.ptr_), 67 | use_(other.use_) 68 | {} 69 | 70 | shared_ptr& operator=(const shared_ptr& other) { 71 | if ( &use_ == &other.use_ ) { return *this; } 72 | if ( use_.only() ) { delete ptr_; } 73 | use_ = other.use_; 74 | ptr_ = other.ptr_; 75 | return *this; 76 | } 77 | 78 | X& operator*() const { return *ptr_; } 79 | X* operator->() const { return ptr_; } 80 | X* get() const { return ptr_; } 81 | bool only() const { return use_.only(); } 82 | 83 | void reset(X* ptr = 0) { 84 | if ( use_.only() ) { delete ptr_; } 85 | ptr_ = ptr; 86 | use_ = Use(); 87 | } 88 | 89 | private: 90 | 91 | X *ptr_; 92 | Use use_; 93 | }; 94 | 95 | #endif /* shared_ptr_h_INCLUDED */ 96 | -------------------------------------------------------------------------------- /TwsApiC++/Test/Src/Clients.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // TwsApi Test 3 | //============================================================================ 4 | #include "TwsApiL0.h" 5 | #include "TwsApiDefs.h" 6 | using namespace TwsApi; 7 | 8 | #ifdef WIN32 9 | #include // Sleep(), in miliseconds 10 | #include 11 | #define CurrentThreadId GetCurrentThreadId 12 | #else 13 | #include // usleep(), in microseconds 14 | #define Sleep( m ) usleep( m*1000 ) 15 | #include 16 | #define CurrentThreadId pthread_self 17 | #endif 18 | 19 | #define PrintProcessId printf("%-8ld ", CurrentThreadId() ) 20 | 21 | #include 22 | 23 | //---------------------------------------------------------------------------- 24 | // MyEWrapper 25 | //---------------------------------------------------------------------------- 26 | class MyEWrapper: public EWrapperL0 27 | { 28 | public: 29 | 30 | MyEWrapper( bool CalledFromThread = true ): EWrapperL0( CalledFromThread ) {} 31 | 32 | virtual void tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute ) 33 | { 34 | time_t _t; time(&_t); 35 | struct tm* _tm = localtime( &_t ); 36 | PrintProcessId,printf 37 | ( "TP: %4ld %02d:%02d:%02d %10s %5.3f\n" 38 | , tickerId 39 | , _tm->tm_hour, _tm->tm_min, _tm->tm_sec 40 | , *(TickTypes::ENUMS)field, price 41 | ); 42 | } 43 | 44 | virtual void winError( const IBString& str, int lastError ) 45 | { 46 | PrintProcessId,printf( "WinError: %d = %s\n", lastError, (const char*)str ); 47 | } 48 | 49 | virtual void connectionClosed() 50 | { 51 | PrintProcessId,printf( "Connection Closed\n"); 52 | } 53 | 54 | virtual void error( const int id, const int errorCode, const IBString errorString ) 55 | { 56 | PrintProcessId,printf( "Error for id=%d: %d = %s\n", id, errorCode, (const char*)errorString ); 57 | } 58 | 59 | virtual void connectionOpened( void ) 60 | { 61 | PrintProcessId,printf( "Connection Opened\n"); 62 | } 63 | 64 | }; 65 | 66 | //---------------------------------------------------------------------------- 67 | // main 68 | //---------------------------------------------------------------------------- 69 | int main( void ) 70 | { 71 | #define NR_CONNECTIONS 8 // 8 is maximum allowed by TWS 72 | 73 | Contract C; 74 | C.symbol = "MSFT"; 75 | C.secType = *SecType::STK; //"STK" 76 | C.currency = "USD"; 77 | C.exchange = *Exchange::IB_SMART; //"SMART"; 78 | 79 | 80 | 81 | // 82 | // messages checked in this thread 83 | // 84 | if( true ){ 85 | MyEWrapper MW(false); 86 | EClientL0* EC[NR_CONNECTIONS]; 87 | 88 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x] = EClientL0::New( &MW ); 89 | 90 | bool connected = true; 91 | for(int x = 0; x < NR_CONNECTIONS; x++ ) connected = connected && EC[x]->eConnect( "", 7496, 100+x ); 92 | 93 | PrintProcessId,printf( "ServerVersion = %d\n", EC[0]->serverVersion() ); 94 | 95 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x]->reqMktData( x, C, "", false ); 96 | 97 | time_t t1; time(&t1); 98 | time_t t2; time(&t2); 99 | while(time(&t2),(t2-t1) < 20) 100 | { 101 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x]->checkMessages(); 102 | } 103 | 104 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x]->eDisconnect(); 105 | 106 | for(int x = 0; x < NR_CONNECTIONS; x++ ) delete EC[x]; 107 | } 108 | 109 | 110 | 111 | 112 | printf( "\n\n\n\n" ); 113 | 114 | 115 | 116 | 117 | // 118 | // messages checked automatically in thread 119 | // 120 | if( true ) 121 | { 122 | MyEWrapper MW; 123 | EClientL0* EC[NR_CONNECTIONS]; 124 | 125 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x] = EClientL0::New( &MW ); 126 | 127 | bool connected = true; 128 | for(int x = 0; x < NR_CONNECTIONS; x++ ) connected = connected && EC[x]->eConnect( "", 7496, 100+x ); 129 | 130 | PrintProcessId,printf( "ServerVersion = %d\n", EC[0]->serverVersion() ); 131 | 132 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x]->reqMktData( x, C, "", false ); 133 | 134 | Sleep(20*1000); 135 | 136 | for(int x = 0; x < NR_CONNECTIONS; x++ ) EC[x]->eDisconnect(); 137 | 138 | for(int x = 0; x < NR_CONNECTIONS; x++ ) delete EC[x]; 139 | } 140 | 141 | printf("\n"); 142 | 143 | 144 | PrintProcessId,printf( "Press return to end\n" ); char s[10]; gets(s); 145 | 146 | return 0; 147 | } 148 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/EClient.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef eclient_def 5 | #define eclient_def 6 | 7 | #include "CommonDefs.h" 8 | #include "IBString.h" 9 | #include "TagValue.h" 10 | 11 | struct Contract; 12 | struct Order; 13 | struct ExecutionFilter; 14 | struct ScannerSubscription; 15 | 16 | class EClient 17 | { 18 | public: 19 | virtual ~EClient() {} 20 | virtual bool eConnect( const char *host, unsigned int port, int clientId = 0, bool extraAuth = 0) = 0; 21 | virtual void eDisconnect() = 0; 22 | virtual int serverVersion() = 0; 23 | virtual IBString TwsConnectionTime() = 0; 24 | virtual void reqMktData( TickerId id, const Contract &contract, 25 | const IBString& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions) = 0; 26 | virtual void cancelMktData( TickerId id) = 0; 27 | virtual void placeOrder( OrderId id, const Contract &contract, const Order &order) = 0; 28 | virtual void cancelOrder( OrderId id) = 0; 29 | virtual void reqOpenOrders() = 0; 30 | virtual void reqAccountUpdates(bool subscribe, const IBString& acctCode) = 0; 31 | virtual void reqExecutions(int reqId, const ExecutionFilter& filter) = 0; 32 | virtual void reqIds( int numIds) = 0; 33 | virtual bool checkMessages() = 0; 34 | virtual void reqContractDetails( int reqId, const Contract &contract) = 0; 35 | virtual void reqMktDepth( TickerId id, const Contract &contract, int numRows, const TagValueListSPtr& mktDepthOptions) = 0; 36 | virtual void cancelMktDepth( TickerId id) = 0; 37 | virtual void reqNewsBulletins( bool allMsgs) = 0; 38 | virtual void cancelNewsBulletins() = 0; 39 | virtual void setServerLogLevel(int level) = 0; 40 | virtual void reqAutoOpenOrders(bool bAutoBind) = 0; 41 | virtual void reqAllOpenOrders() = 0; 42 | virtual void reqManagedAccts() = 0; 43 | virtual void requestFA(faDataType pFaDataType) = 0; 44 | virtual void replaceFA(faDataType pFaDataType, const IBString& cxml) = 0; 45 | virtual void reqHistoricalData( TickerId id, const Contract &contract, 46 | const IBString &endDateTime, const IBString &durationStr, const IBString &barSizeSetting, 47 | const IBString &whatToShow, int useRTH, int formatDate, const TagValueListSPtr& chartOptions) = 0; 48 | virtual void exerciseOptions( TickerId id, const Contract &contract, 49 | int exerciseAction, int exerciseQuantity, const IBString &account, int override) = 0; 50 | virtual void cancelHistoricalData( TickerId tickerId ) = 0; 51 | virtual void reqRealTimeBars( TickerId id, const Contract &contract, int barSize, 52 | const IBString &whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions) = 0; 53 | virtual void cancelRealTimeBars( TickerId tickerId) = 0; 54 | virtual void cancelScannerSubscription( int tickerId) = 0; 55 | virtual void reqScannerParameters() = 0; 56 | virtual void reqScannerSubscription( int tickerId, const ScannerSubscription &subscription, const TagValueListSPtr& scannerSubscriptionOptions) = 0; 57 | virtual void reqCurrentTime() = 0; 58 | virtual void reqFundamentalData( TickerId reqId, const Contract&, const IBString& reportType) = 0; 59 | virtual void cancelFundamentalData( TickerId reqId) = 0; 60 | virtual void calculateImpliedVolatility( TickerId reqId, const Contract &contract, double optionPrice, double underPrice) = 0; 61 | virtual void calculateOptionPrice( TickerId reqId, const Contract &contract, double volatility, double underPrice) = 0; 62 | virtual void cancelCalculateImpliedVolatility( TickerId reqId) = 0; 63 | virtual void cancelCalculateOptionPrice( TickerId reqId) = 0; 64 | virtual void reqGlobalCancel() = 0; 65 | virtual void reqMarketDataType( int marketDataType) = 0; 66 | virtual void reqPositions() = 0; 67 | virtual void cancelPositions() = 0; 68 | virtual void reqAccountSummary( int reqId, const IBString& groupName, const IBString& tags) = 0; 69 | virtual void cancelAccountSummary( int reqId) = 0; 70 | virtual void verifyRequest( const IBString& apiName, const IBString& apiVersion) = 0; 71 | virtual void verifyMessage( const IBString& apiData) = 0; 72 | virtual void queryDisplayGroups( int reqId) = 0; 73 | virtual void subscribeToGroupEvents( int reqId, int groupId) = 0; 74 | virtual void updateDisplayGroup( int reqId, const IBString& contractInfo) = 0; 75 | virtual void unsubscribeFromGroupEvents( int reqId) = 0; 76 | 77 | private: 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /TwsApiC++/Test/Src/Bars.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // TwsApi Test 3 | //============================================================================ 4 | #include "TwsApiL0.h" 5 | #include "TwsApiDefs.h" 6 | using namespace TwsApi; 7 | 8 | // to use the Sleep function 9 | #ifdef WIN32 10 | #include // Sleep(), in miliseconds 11 | #include 12 | #define CurrentThreadId GetCurrentThreadId 13 | #else 14 | #include // usleep(), in microseconds 15 | #define Sleep( m ) usleep( m*1000 ) 16 | #include 17 | #define CurrentThreadId pthread_self 18 | #endif 19 | 20 | #define PrintProcessId printf("%ld ", CurrentThreadId() ) 21 | 22 | #include 23 | 24 | 25 | //---------------------------------------------------------------------------- 26 | // 27 | //---------------------------------------------------------------------------- 28 | struct OHLC 29 | { 30 | double O, H, L, C; 31 | 32 | OHLC() { Reset(); } 33 | void Reset() { O = 0, C = 0, L = 0, C = 0; } 34 | }; 35 | 36 | //---------------------------------------------------------------------------- 37 | // MyEWrapper 38 | //---------------------------------------------------------------------------- 39 | class MyEWrapper: public EWrapperL0 40 | { 41 | public: 42 | MyEWrapper( bool CalledFromThread = true ): EWrapperL0( CalledFromThread ) {} 43 | 44 | virtual void tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute ) 45 | { 46 | time_t _t; time(&_t); 47 | struct tm* _tm = localtime( &_t ); 48 | switch( field ) 49 | { 50 | case TickTypes::Open: 51 | case TickTypes::High: 52 | case TickTypes::Low: 53 | case TickTypes::Close: 54 | case TickTypes::Last: 55 | printf 56 | ( "TP: %4ld %02d:%02d:%02d %15s %5.3f\n" 57 | , tickerId 58 | , _tm->tm_hour, _tm->tm_min, _tm->tm_sec 59 | , *(TickTypes::ENUMS)field, price 60 | ); 61 | default:{} 62 | } 63 | } 64 | 65 | virtual void tickSize( TickerId tickerId, TickType field, int size ) 66 | { 67 | time_t _t; time(&_t); 68 | struct tm* _tm = localtime( &_t ); 69 | switch( field ) 70 | { 71 | case TickTypes::LastSize: 72 | printf 73 | ( "TP: %4ld %02d:%02d:%02d %15s %5d\n" 74 | , tickerId 75 | , _tm->tm_hour, _tm->tm_min, _tm->tm_sec 76 | , *(TickTypes::ENUMS)field, size 77 | ); 78 | default:{} 79 | } 80 | } 81 | 82 | virtual void tickString( TickerId tickerId, TickType tickType, const IBString& value ) 83 | { 84 | time_t _t; time(&_t); 85 | struct tm _tm = *localtime( &_t ); 86 | time_t _t1 = atol((const char*)value); 87 | struct tm _tm1= *localtime( &_t1 ); 88 | 89 | switch( tickType ) 90 | { 91 | case TickTypes::LastTimestamp: 92 | printf 93 | ( "TP: %4ld %02d:%02d:%02d %15s %02d:%02d:%02d\n" 94 | , tickerId 95 | , _tm.tm_hour, _tm.tm_min, _tm.tm_sec 96 | , *(TickTypes::ENUMS)tickType 97 | , _tm1.tm_hour, _tm1.tm_min, _tm1.tm_sec 98 | ); 99 | default:{} 100 | } 101 | } 102 | 103 | virtual void winError( const IBString& str, int lastError ) 104 | { 105 | printf( "WinError: %d = %s\n", lastError, (const char*)str ); 106 | } 107 | 108 | virtual void error( const int id, const int errorCode, const IBString errorString ) 109 | { 110 | printf( "Error for id=%d: %d = %s\n", id, errorCode, (const char*)errorString ); 111 | } 112 | 113 | }; 114 | 115 | 116 | //---------------------------------------------------------------------------- 117 | //---------------------------------------------------------------------------- 118 | 119 | //---------------------------------------------------------------------------- 120 | // main 121 | //---------------------------------------------------------------------------- 122 | int main( void ) 123 | { 124 | // TestEnums(); 125 | 126 | Contract C; 127 | C.symbol = "C"; 128 | C.secType = *SecType::STK; //"STK" 129 | C.currency = "USD"; 130 | C.exchange = *Exchange::IB_SMART; //"SMART"; 131 | // C.primaryExchange = *Exchange::AMEX; 132 | 133 | MyEWrapper MW( false ); // no thread 134 | EClientL0* EC = EClientL0::New( &MW ); 135 | 136 | printf( "ClientVersion = %d\n", EC->clientVersion() ); 137 | 138 | if( EC->eConnect( "", 7496, 100 ) ) 139 | { 140 | 141 | EC->reqMktData( 100, C, "", false ); 142 | 143 | time_t t1; time(&t1); 144 | time_t t2; time(&t2); 145 | while(time(&t2),(t2-t1) < 200) 146 | { 147 | EC->checkMessages(); 148 | } 149 | 150 | } 151 | 152 | 153 | EC->eDisconnect(); 154 | 155 | delete EC; 156 | 157 | { PrintProcessId,printf( "Press return to end\n" ); char s[10]; gets(s); } 158 | return 0; 159 | } 160 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/Contract.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef contract_def 5 | #define contract_def 6 | 7 | #include "TagValue.h" 8 | 9 | /* 10 | SAME_POS = open/close leg value is same as combo 11 | OPEN_POS = open 12 | CLOSE_POS = close 13 | UNKNOWN_POS = unknown 14 | */ 15 | enum LegOpenClose { SAME_POS, OPEN_POS, CLOSE_POS, UNKNOWN_POS }; 16 | 17 | struct ComboLeg 18 | { 19 | ComboLeg() 20 | : conId(0) 21 | , ratio(0) 22 | , openClose(0) 23 | , shortSaleSlot(0) 24 | , exemptCode(-1) 25 | { 26 | } 27 | 28 | long conId; 29 | long ratio; 30 | IBString action; //BUY/SELL/SSHORT 31 | 32 | IBString exchange; 33 | long openClose; // LegOpenClose enum values 34 | 35 | // for stock legs when doing short sale 36 | long shortSaleSlot; // 1 = clearing broker, 2 = third party 37 | IBString designatedLocation; 38 | int exemptCode; 39 | 40 | bool operator==( const ComboLeg &other) const 41 | { 42 | return (conId == other.conId && 43 | ratio == other.ratio && 44 | openClose == other.openClose && 45 | shortSaleSlot == other.shortSaleSlot && 46 | (Compare(action, other.action) == 0) && 47 | (Compare(exchange, other.exchange) == 0) && 48 | (Compare(designatedLocation, other.designatedLocation) == 0) && 49 | exemptCode == other.exemptCode); 50 | } 51 | }; 52 | 53 | struct UnderComp 54 | { 55 | UnderComp() 56 | : conId(0) 57 | , delta(0) 58 | , price(0) 59 | {} 60 | 61 | long conId; 62 | double delta; 63 | double price; 64 | }; 65 | 66 | typedef shared_ptr ComboLegSPtr; 67 | 68 | struct Contract 69 | { 70 | Contract() 71 | : conId(0) 72 | , strike(0) 73 | , includeExpired(false) 74 | , comboLegs(NULL) 75 | , underComp(NULL) 76 | { 77 | } 78 | 79 | long conId; 80 | IBString symbol; 81 | IBString secType; 82 | IBString expiry; 83 | double strike; 84 | IBString right; 85 | IBString multiplier; 86 | IBString exchange; 87 | IBString primaryExchange; // pick an actual (ie non-aggregate) exchange that the contract trades on. DO NOT SET TO SMART. 88 | IBString currency; 89 | IBString localSymbol; 90 | IBString tradingClass; 91 | bool includeExpired; 92 | IBString secIdType; // CUSIP;SEDOL;ISIN;RIC 93 | IBString secId; 94 | 95 | // COMBOS 96 | IBString comboLegsDescrip; // received in open order 14 and up for all combos 97 | 98 | // combo legs 99 | typedef std::vector ComboLegList; 100 | typedef shared_ptr ComboLegListSPtr; 101 | 102 | ComboLegListSPtr comboLegs; 103 | 104 | // delta neutral 105 | UnderComp* underComp; 106 | 107 | public: 108 | 109 | // Helpers 110 | static void CloneComboLegs(ComboLegListSPtr& dst, const ComboLegListSPtr& src); 111 | }; 112 | 113 | struct ContractDetails 114 | { 115 | ContractDetails() 116 | : minTick(0) 117 | , priceMagnifier(0) 118 | , underConId(0) 119 | , evMultiplier(0) 120 | , callable(false) 121 | , putable(false) 122 | , coupon(0) 123 | , convertible(false) 124 | , nextOptionPartial(false) 125 | { 126 | } 127 | 128 | Contract summary; 129 | IBString marketName; 130 | double minTick; 131 | IBString orderTypes; 132 | IBString validExchanges; 133 | long priceMagnifier; 134 | int underConId; 135 | IBString longName; 136 | IBString contractMonth; 137 | IBString industry; 138 | IBString category; 139 | IBString subcategory; 140 | IBString timeZoneId; 141 | IBString tradingHours; 142 | IBString liquidHours; 143 | IBString evRule; 144 | double evMultiplier; 145 | 146 | TagValueListSPtr secIdList; 147 | 148 | // BOND values 149 | IBString cusip; 150 | IBString ratings; 151 | IBString descAppend; 152 | IBString bondType; 153 | IBString couponType; 154 | bool callable; 155 | bool putable; 156 | double coupon; 157 | bool convertible; 158 | IBString maturity; 159 | IBString issueDate; 160 | IBString nextOptionDate; 161 | IBString nextOptionType; 162 | bool nextOptionPartial; 163 | IBString notes; 164 | }; 165 | 166 | inline void 167 | Contract::CloneComboLegs(ComboLegListSPtr& dst, const ComboLegListSPtr& src) 168 | { 169 | if (!src.get()) 170 | return; 171 | 172 | dst->reserve(src->size()); 173 | 174 | ComboLegList::const_iterator iter = src->begin(); 175 | const ComboLegList::const_iterator iterEnd = src->end(); 176 | 177 | for (; iter != iterEnd; ++iter) { 178 | const ComboLeg* leg = iter->get(); 179 | if (!leg) 180 | continue; 181 | dst->push_back(ComboLegSPtr(new ComboLeg(*leg))); 182 | } 183 | } 184 | 185 | 186 | #endif 187 | -------------------------------------------------------------------------------- /TwsApiC++/Test/Src/History.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // TwsApi Test 3 | //============================================================================ 4 | #include "TwsApiL0.h" 5 | #include "TwsApiDefs.h" 6 | using namespace TwsApi; 7 | 8 | bool EndOfHistoricalData = false; 9 | bool ErrorForRequest = false; 10 | 11 | //---------------------------------------------------------------------------- 12 | // MyEWrapper 13 | //---------------------------------------------------------------------------- 14 | class MyEWrapper: public EWrapperL0 15 | { 16 | public: 17 | 18 | MyEWrapper( bool CalledFromThread = true ) : EWrapperL0( CalledFromThread ) {} 19 | 20 | virtual void winError( const IBString& str, int lastError ) 21 | { 22 | fprintf( stderr, "WinError: %d = %s\n", lastError, (const char*)str ); 23 | ErrorForRequest = true; 24 | } 25 | 26 | virtual void error( const int id, const int errorCode, const IBString errorString ) 27 | { 28 | fprintf( stderr, "Error for id=%d: %d = %s\n", id, errorCode, (const char*)errorString ); 29 | ErrorForRequest = (id > 0); 30 | // id == -1 are 'system' messages, not for user requests 31 | // as a test, set year to 2010 in the reqHistoricalData 32 | } 33 | 34 | virtual void historicalData( TickerId reqId, const IBString& date, double open, double high, double low, double close, int volume, int barCount, double WAP, int hasGaps ) 35 | { 36 | if( IsEndOfHistoricalData(date) ) 37 | { 38 | EndOfHistoricalData = true; 39 | return; 40 | } 41 | 42 | fprintf( stdout, "%10s, %5.3f, %5.3f, %5.3f, %5.3f, %7d\n", (const char*)date, open, high, low, close, volume ); 43 | } 44 | 45 | }; 46 | 47 | 48 | //---------------------------------------------------------------------------- 49 | // DUMP_DEFS 50 | // Dumps the list of valid values for enum E 51 | //---------------------------------------------------------------------------- 52 | // The iterator has a similar interface as the of the std::map 53 | #define DUMP_DEFS( E ) \ 54 | for( E::iterator i = E::begin(); i != E::end(); ++i ) { \ 55 | printf( "\'%s\'\n", i->second ); } 56 | 57 | //---------------------------------------------------------------------------- 58 | // ARGV 59 | // Checks whether V is valid value for enum E 60 | // Whn invalid, prints list of the valid values via DUMP_DEFS 61 | //---------------------------------------------------------------------------- 62 | #define CHECK_VAR( E, V ) {\ 63 | E::ENUMS e; \ 64 | if( !(e *= V) ) { \ 65 | printf("Error in argument '%s': value '%s' is not recognised.\nFollowing are valid values:\n", #E, V); \ 66 | DUMP_DEFS( E ) \ 67 | return 1; \ 68 | } } 69 | 70 | 71 | //---------------------------------------------------------------------------- 72 | // main 73 | //---------------------------------------------------------------------------- 74 | int main( int argc, const char* argv[] ) 75 | { 76 | Contract C; 77 | C.symbol = "MSFT"; 78 | C.secType = *SecType::STK; //"STK" 79 | C.currency = "USD"; 80 | C.exchange = *Exchange::IB_SMART; //"SMART"; 81 | C.primaryExchange = *Exchange::AMEX; 82 | 83 | 84 | int EDTY = 2014; 85 | int EDTM = 8; 86 | int EDTD = 4; 87 | IBString DS = DurationStr(1, *DurationHorizon::Months); 88 | IBString BSS = *BarSizeSetting::_1_day; 89 | IBString WTS = *WhatToShow::TRADES; 90 | 91 | if( argc > 1 ) 92 | { 93 | if( argc < 8 ) 94 | { 95 | printf ( "args are: symbol end-date duration barsize what-to-show.\n" 96 | " i.e. MSFT 20140804 10 D 1 day TRADES\n" 97 | ); 98 | return 1; 99 | } 100 | 101 | C.symbol = argv[1]; 102 | IBString EDT = argv[2]; 103 | if( EDT.size() != 8 ) 104 | { 105 | printf ( "end-date should be 8 characters: YYYYMMDD\n" 106 | " i.e. 20140804\n" 107 | ); 108 | return 1; 109 | } 110 | EDTY = atoi( EDT.substr(0,4).data() ); 111 | EDTM = atoi( EDT.substr(4,2).data() ); 112 | EDTD = atoi( EDT.substr(6,2).data() ); 113 | 114 | CHECK_VAR( DurationHorizon, argv[4] ) // DurationHorizon 115 | DS = DurationStr(atoi(argv[3]), argv[4] ); 116 | 117 | IBString bss = argv[5]; bss = bss + " " + argv[6]; 118 | CHECK_VAR( BarSizeSetting, (const char*)bss ) // BarSizeSetting 119 | BSS = bss; 120 | 121 | CHECK_VAR( WhatToShow, argv[7] ) // WhatToShow 122 | WTS = argv[7]; 123 | } 124 | 125 | 126 | MyEWrapper MW( false ); 127 | EClientL0* EC = EClientL0::New( &MW ); 128 | 129 | if( EC->eConnect( "", 7496, 100 ) ) 130 | { 131 | EC->reqHistoricalData 132 | ( 20 133 | , C 134 | , EndDateTime(EDTY,EDTM,EDTD) // Attention: for IB, this means last day will be 2013,02,19 135 | , DS // DurationStr(1, *DurationHorizon::Months) 136 | , BSS // *BarSizeSetting::_1_day 137 | , WTS // *WhatToShow::TRADES 138 | , UseRTH::AllTradingData // or use OnlyRegularTradingData 139 | , FormatDate::AsDate 140 | // , TagValueListSPtr() // solved by default parameter in EClientL0 141 | ); 142 | 143 | while( !EndOfHistoricalData && !ErrorForRequest ) 144 | EC->checkMessages(); 145 | } 146 | 147 | EC->eDisconnect(); 148 | delete EC; 149 | 150 | return ErrorForRequest; 151 | } 152 | -------------------------------------------------------------------------------- /source/PosixClient/src/EPosixClientSocket.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #include "EPosixClientSocket.h" 5 | 6 | #include "EPosixClientSocketPlatform.h" 7 | #include "TwsSocketClientErrors.h" 8 | #include "EWrapper.h" 9 | 10 | #include 11 | 12 | /////////////////////////////////////////////////////////// 13 | // member funcs 14 | EPosixClientSocket::EPosixClientSocket( EWrapper *ptr) : EClientSocketBase( ptr) 15 | { 16 | m_fd = -1; 17 | } 18 | 19 | EPosixClientSocket::~EPosixClientSocket() 20 | { 21 | } 22 | 23 | bool EPosixClientSocket::eConnect( const char *host, unsigned int port, int clientId, bool extraAuth) 24 | { 25 | // reset errno 26 | errno = 0; 27 | 28 | // already connected? 29 | if( m_fd >= 0) { 30 | errno = EISCONN; 31 | getWrapper()->error( NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg()); 32 | return false; 33 | } 34 | 35 | // initialize Winsock DLL (only for Windows) 36 | if ( !SocketsInit()) { 37 | return false; 38 | } 39 | 40 | // create socket 41 | m_fd = socket(AF_INET, SOCK_STREAM, 0); 42 | 43 | // cannot create socket 44 | if( m_fd < 0) { 45 | // uninitialize Winsock DLL (only for Windows) 46 | SocketsDestroy(); 47 | getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg()); 48 | return false; 49 | } 50 | 51 | // use local machine if no host passed in 52 | if ( !( host && *host)) { 53 | host = "127.0.0.1"; 54 | } 55 | 56 | // starting to connect to server 57 | struct sockaddr_in sa; 58 | memset( &sa, 0, sizeof(sa)); 59 | sa.sin_family = AF_INET; 60 | sa.sin_port = htons( port); 61 | sa.sin_addr.s_addr = inet_addr( host); 62 | 63 | // try to connect 64 | if( (connect( m_fd, (struct sockaddr *) &sa, sizeof( sa))) < 0) { 65 | // error connecting 66 | SocketClose( m_fd); 67 | m_fd = -1; 68 | // uninitialize Winsock DLL (only for Windows) 69 | SocketsDestroy(); 70 | getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); 71 | return false; 72 | } 73 | 74 | // set client id 75 | setClientId( clientId); 76 | setExtraAuth( extraAuth); 77 | 78 | onConnectBase(); 79 | 80 | while( isSocketOK() && !isConnected()) { 81 | if ( !checkMessages()) { 82 | // uninitialize Winsock DLL (only for Windows) 83 | SocketsDestroy(); 84 | getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); 85 | return false; 86 | } 87 | } 88 | 89 | 90 | // set socket to non-blocking state 91 | if ( !SetSocketNonBlocking(m_fd)){ 92 | // error setting socket to non-blocking 93 | SocketsDestroy(); 94 | getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); 95 | return false; 96 | } 97 | 98 | // successfully connected 99 | return true; 100 | } 101 | 102 | void EPosixClientSocket::eDisconnect() 103 | { 104 | if ( m_fd >= 0 ) 105 | // close socket 106 | SocketClose( m_fd); 107 | m_fd = -1; 108 | // uninitialize Winsock DLL (only for Windows) 109 | SocketsDestroy(); 110 | eDisconnectBase(); 111 | } 112 | 113 | bool EPosixClientSocket::isSocketOK() const 114 | { 115 | return ( m_fd >= 0); 116 | } 117 | 118 | int EPosixClientSocket::fd() const 119 | { 120 | return m_fd; 121 | } 122 | 123 | int EPosixClientSocket::send(const char* buf, size_t sz) 124 | { 125 | if( sz <= 0) 126 | return 0; 127 | 128 | int nResult = ::send( m_fd, buf, sz, 0); 129 | 130 | if( nResult == -1 && !handleSocketError()) { 131 | return -1; 132 | } 133 | if( nResult <= 0) { 134 | return 0; 135 | } 136 | return nResult; 137 | } 138 | 139 | int EPosixClientSocket::receive(char* buf, size_t sz) 140 | { 141 | if( sz <= 0) 142 | return 0; 143 | 144 | int nResult = ::recv( m_fd, buf, sz, 0); 145 | 146 | if( nResult == -1 && !handleSocketError()) { 147 | return -1; 148 | } 149 | if( nResult <= 0) { 150 | return 0; 151 | } 152 | return nResult; 153 | } 154 | 155 | /////////////////////////////////////////////////////////// 156 | // callbacks from socket 157 | 158 | void EPosixClientSocket::onConnect() 159 | { 160 | if( !handleSocketError()) 161 | return; 162 | 163 | onConnectBase(); 164 | } 165 | 166 | void EPosixClientSocket::onReceive() 167 | { 168 | if( !handleSocketError()) 169 | return; 170 | 171 | checkMessages(); 172 | } 173 | 174 | void EPosixClientSocket::onSend() 175 | { 176 | if( !handleSocketError()) 177 | return; 178 | 179 | sendBufferedData(); 180 | } 181 | 182 | void EPosixClientSocket::onClose() 183 | { 184 | if( !handleSocketError()) 185 | return; 186 | 187 | eDisconnect(); 188 | getWrapper()->connectionClosed(); 189 | } 190 | 191 | void EPosixClientSocket::onError() 192 | { 193 | handleSocketError(); 194 | } 195 | 196 | /////////////////////////////////////////////////////////// 197 | // helper 198 | bool EPosixClientSocket::handleSocketError() 199 | { 200 | // no error 201 | if( errno == 0) 202 | return true; 203 | 204 | // Socket is already connected 205 | if( errno == EISCONN) { 206 | return true; 207 | } 208 | 209 | if( errno == EWOULDBLOCK) 210 | return false; 211 | 212 | if( errno == ECONNREFUSED) { 213 | getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); 214 | } 215 | else { 216 | getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(), 217 | SOCKET_EXCEPTION.msg() + strerror(errno)); 218 | } 219 | // reset errno 220 | errno = 0; 221 | eDisconnect(); 222 | return false; 223 | } 224 | -------------------------------------------------------------------------------- /TwsApiC++/Api/Enumerations.h: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------------------------- 2 | // Enumerations 3 | // By Jan Boonen 4 | //---------------------------------------------------------------------------- 5 | #include "string.h" 6 | 7 | #undef ENUM_N 8 | #undef ENUM_V 9 | #undef ENUM_S 10 | #undef ENUMVS 11 | #undef ENUMValues 12 | #undef ENUMFunctions 13 | 14 | #ifndef ENUMImplementation 15 | #define ENUMValues( Name ) \ 16 | struct Name \ 17 | { \ 18 | enum ENUMS { 19 | 20 | #define ENUM_N( N ) N , // enumerator id is Name and compilers assigns value (default) 21 | #define ENUM_V( N, V ) N = V , // idem but user assigns own value V 22 | #define ENUM_S( N, S ) N , // idem as ENUM_N 23 | #define ENUMVS( N, V, S ) N = V , // idem as ENUM_V 24 | 25 | #define ENUMFunctions( Name ) _INVALID_ };\ 26 | private: typedef struct { ENUMS first; const char* second; } STRINGS; \ 27 | public: typedef STRINGS* iterator; \ 28 | private: static iterator get_iterator( bool GetBeginIterator ); \ 29 | public: \ 30 | static inline iterator begin(void) { return get_iterator( true ); } \ 31 | static inline iterator end (void) { return get_iterator( false ); } \ 32 | static inline iterator find (ENUMS e) { iterator it; for( it = begin(); it != end(); ++it ){if( it->first == e ) return it;} return it; } \ 33 | static inline iterator find (const char* s) { iterator it; for( it = begin(); it != end(); ++it ){if(!strcmp(it->second,s)) return it;} return it; } \ 34 | static inline bool IsValid( iterator it ) { return (it >= begin() && it < end()); } \ 35 | \ 36 | inline Name( void ) :m_it( end() ) {} \ 37 | inline Name( const ENUMS e ) :m_it(find(e)) {} \ 38 | inline Name( const char* s ) :m_it(find(s)) {} \ 39 | inline ENUMS operator* ( void ) const { return m_it->first; } \ 40 | inline operator ENUMS ( void ) const { return m_it->first; } \ 41 | inline const char* str ( void ) const { return m_it->second; } \ 42 | private: const iterator m_it; \ 43 | }; \ 44 | \ 45 | inline static const char* operator * ( const Name::ENUMS e ) { return ( Name::find(e)->second); } \ 46 | inline static const char* operator *= ( const char *&s, const Name::ENUMS e ) { return (s = Name::find(e)->second); } \ 47 | inline static bool operator *= ( Name::ENUMS& e, const char* s ) { return (Name::_INVALID_ != (e = Name::find(s)->first)); } 48 | 49 | #else 50 | #define ENUMValues( Name ) \ 51 | Name::iterator Name::get_iterator( bool GetBeginIterator ) \ 52 | { \ 53 | static STRINGS S[] = { 54 | 55 | #define ENUM_N( N ) { N, #N } , // string value equals name (default) 56 | #define ENUM_V( N, V ) { N, #N } , // idem as ENUM_N 57 | #define ENUM_S( N, S ) { N, S } , // string value equals parameter S (exception) 58 | #define ENUMVS( N, V, S ) { N, S } , // idem as ENUM_S 59 | 60 | #define ENUMFunctions( Name ) { _INVALID_, "_INVALID_" } };\ 61 | static iterator begin = &S[0]; \ 62 | static iterator end = &S[ (sizeof(S)/sizeof(STRINGS)) - 1 ]; \ 63 | return GetBeginIterator ?begin :end; \ 64 | } 65 | #endif 66 | 67 | 68 | 69 | #if 0 70 | // The following is an example of a definition of an enum and the generated 71 | // code by this set of macro's. 72 | ENUMValues( Player ) // enum Player 73 | ENUM_V( First , 13 ) // First , 13, "First" 74 | ENUM_N( Second ) // Second, 14, "Second" 75 | ENUM_V( Third , 30 ) // Third , 30, "Third" 76 | ENUM_S( Fourth , "!Surprice!" ) // Fourth, 31, "!Surprice!" 77 | ENUM_N( Fifth ) // Fifth , 32, "Fifth" 78 | ENUM_VS(Sixth , 60 , "LastOne" ) // Sixth , 60, "LastOne" 79 | ENUMFunctions( Player ) 80 | 81 | // When including the definitions the first time 82 | struct Player 83 | { 84 | enum ENUMS 85 | { First = 13 86 | , Second 87 | , Third = 30 88 | , Fourth 89 | , Fifth 90 | , Sixth = 60 91 | , _INVALID_ 92 | }; 93 | 94 | typedef struct { 95 | ENUMS first; 96 | const char* second; 97 | } STRINGS, * iterator; 98 | 99 | static iterator get_iterator( bool GetBeginIterator ); // implemented where ENUMImplementation is defined 100 | 101 | static inline iterator begin(void) 102 | { 103 | return get_iterator( true ); 104 | } 105 | 106 | static inline iterator end(void) 107 | { 108 | return get_iterator( false ); 109 | } 110 | 111 | static inline iterator find (ENUMS e) 112 | { 113 | iterator it; 114 | for( it = begin(); it != end(); ++it ) 115 | { 116 | if( it->first == e ) 117 | return it; 118 | } 119 | return it; 120 | } 121 | 122 | static inline iterator find (const char* s) 123 | { 124 | iterator it; 125 | for( it = begin(); it != end(); ++it ) 126 | { 127 | if(!strcmp(it->second,s)) 128 | return it; 129 | } 130 | return it; 131 | } 132 | 133 | static inline bool IsValid( iterator it ) 134 | { 135 | return (it >= begin() && it < end()); 136 | } 137 | 138 | inline Name( const ENUMS e ) :m_it(find(e)) {} 139 | inline Name( const char* s ) :m_it(find(s)) {} 140 | 141 | inline ENUMS operator* ( void ) const { return m_it->first; } 142 | inline operator ENUMS ( void ) const { return m_it->first; } 143 | inline const char* str ( void ) const { return m_it->second; } 144 | 145 | private: 146 | const iterator m_it; 147 | }; 148 | 149 | 150 | inline static const char* operator * ( const Name::ENUMS e ) 151 | { 152 | return Name::find(e)->second; 153 | } 154 | 155 | inline static const char* operator *= ( const char *&s, const Name::ENUMS e ) 156 | { 157 | return s = Name::find(e)->second; 158 | } 159 | 160 | inline static bool operator *= ( Name::ENUMS& e, const char* s ) 161 | { 162 | return Name::_INVALID_ != ( e = Name::find(s)->first ); 163 | } 164 | 165 | 166 | // When including the definitions the second time (only once in the project) 167 | 168 | Player::iterator Player::get_iterator( bool GetBeginIterator ) 169 | { 170 | static STRINGS S[] = 171 | { { First , "First" } 172 | , { Second , "Second" } 173 | , { Third , "Thisrd" } 174 | , { Fourth , "!Surprice!" } 175 | , { Fifth , "Fifth" } 176 | , { Sixth , "LastOne" } 177 | , { _INVALID_ , "_INVALID_" } 178 | }; 179 | static iterator begin = &S[0]; 180 | static iterator end = &S[ (sizeof S)/(sizeof STRINGS) - 1 ]; // points to _INVALID_ 181 | 182 | return GetBeginIterator ?begin :end; 183 | } 184 | 185 | #endif 186 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/EWrapper.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef ewrapper_def 5 | #define ewrapper_def 6 | 7 | #include "CommonDefs.h" 8 | #include "IBString.h" 9 | 10 | enum TickType { BID_SIZE, BID, ASK, ASK_SIZE, LAST, LAST_SIZE, 11 | HIGH, LOW, VOLUME, CLOSE, 12 | BID_OPTION_COMPUTATION, 13 | ASK_OPTION_COMPUTATION, 14 | LAST_OPTION_COMPUTATION, 15 | MODEL_OPTION, 16 | OPEN, 17 | LOW_13_WEEK, 18 | HIGH_13_WEEK, 19 | LOW_26_WEEK, 20 | HIGH_26_WEEK, 21 | LOW_52_WEEK, 22 | HIGH_52_WEEK, 23 | AVG_VOLUME, 24 | OPEN_INTEREST, 25 | OPTION_HISTORICAL_VOL, 26 | OPTION_IMPLIED_VOL, 27 | OPTION_BID_EXCH, 28 | OPTION_ASK_EXCH, 29 | OPTION_CALL_OPEN_INTEREST, 30 | OPTION_PUT_OPEN_INTEREST, 31 | OPTION_CALL_VOLUME, 32 | OPTION_PUT_VOLUME, 33 | INDEX_FUTURE_PREMIUM, 34 | BID_EXCH, 35 | ASK_EXCH, 36 | AUCTION_VOLUME, 37 | AUCTION_PRICE, 38 | AUCTION_IMBALANCE, 39 | MARK_PRICE, 40 | BID_EFP_COMPUTATION, 41 | ASK_EFP_COMPUTATION, 42 | LAST_EFP_COMPUTATION, 43 | OPEN_EFP_COMPUTATION, 44 | HIGH_EFP_COMPUTATION, 45 | LOW_EFP_COMPUTATION, 46 | CLOSE_EFP_COMPUTATION, 47 | LAST_TIMESTAMP, 48 | SHORTABLE, 49 | FUNDAMENTAL_RATIOS, 50 | RT_VOLUME, 51 | HALTED, 52 | BID_YIELD, 53 | ASK_YIELD, 54 | LAST_YIELD, 55 | CUST_OPTION_COMPUTATION, 56 | TRADE_COUNT, 57 | TRADE_RATE, 58 | VOLUME_RATE, 59 | LAST_RTH_TRADE, 60 | NOT_SET }; 61 | 62 | inline bool isPrice( TickType tickType) { 63 | return tickType == BID || tickType == ASK || tickType == LAST; 64 | } 65 | 66 | struct Contract; 67 | struct ContractDetails; 68 | struct Order; 69 | struct OrderState; 70 | struct Execution; 71 | struct UnderComp; 72 | struct CommissionReport; 73 | 74 | class EWrapper 75 | { 76 | public: 77 | virtual ~EWrapper() {}; 78 | 79 | virtual void tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) = 0; 80 | virtual void tickSize( TickerId tickerId, TickType field, int size) = 0; 81 | virtual void tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta, 82 | double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) = 0; 83 | virtual void tickGeneric(TickerId tickerId, TickType tickType, double value) = 0; 84 | virtual void tickString(TickerId tickerId, TickType tickType, const IBString& value) = 0; 85 | virtual void tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const IBString& formattedBasisPoints, 86 | double totalDividends, int holdDays, const IBString& futureExpiry, double dividendImpact, double dividendsToExpiry) = 0; 87 | virtual void orderStatus( OrderId orderId, const IBString &status, int filled, 88 | int remaining, double avgFillPrice, int permId, int parentId, 89 | double lastFillPrice, int clientId, const IBString& whyHeld) = 0; 90 | virtual void openOrder( OrderId orderId, const Contract&, const Order&, const OrderState&) = 0; 91 | virtual void openOrderEnd() = 0; 92 | virtual void winError( const IBString &str, int lastError) = 0; 93 | virtual void connectionClosed() = 0; 94 | virtual void updateAccountValue(const IBString& key, const IBString& val, 95 | const IBString& currency, const IBString& accountName) = 0; 96 | virtual void updatePortfolio( const Contract& contract, int position, 97 | double marketPrice, double marketValue, double averageCost, 98 | double unrealizedPNL, double realizedPNL, const IBString& accountName) = 0; 99 | virtual void updateAccountTime(const IBString& timeStamp) = 0; 100 | virtual void accountDownloadEnd(const IBString& accountName) = 0; 101 | virtual void nextValidId( OrderId orderId) = 0; 102 | virtual void contractDetails( int reqId, const ContractDetails& contractDetails) = 0; 103 | virtual void bondContractDetails( int reqId, const ContractDetails& contractDetails) = 0; 104 | virtual void contractDetailsEnd( int reqId) = 0; 105 | virtual void execDetails( int reqId, const Contract& contract, const Execution& execution) =0; 106 | virtual void execDetailsEnd( int reqId) =0; 107 | virtual void error(const int id, const int errorCode, const IBString errorString) = 0; 108 | virtual void updateMktDepth(TickerId id, int position, int operation, int side, 109 | double price, int size) = 0; 110 | virtual void updateMktDepthL2(TickerId id, int position, IBString marketMaker, int operation, 111 | int side, double price, int size) = 0; 112 | virtual void updateNewsBulletin(int msgId, int msgType, const IBString& newsMessage, const IBString& originExch) = 0; 113 | virtual void managedAccounts( const IBString& accountsList) = 0; 114 | virtual void receiveFA(faDataType pFaDataType, const IBString& cxml) = 0; 115 | virtual void historicalData(TickerId reqId, const IBString& date, double open, double high, 116 | double low, double close, int volume, int barCount, double WAP, int hasGaps) = 0; 117 | virtual void scannerParameters(const IBString &xml) = 0; 118 | virtual void scannerData(int reqId, int rank, const ContractDetails &contractDetails, 119 | const IBString &distance, const IBString &benchmark, const IBString &projection, 120 | const IBString &legsStr) = 0; 121 | virtual void scannerDataEnd(int reqId) = 0; 122 | virtual void realtimeBar(TickerId reqId, long time, double open, double high, double low, double close, 123 | long volume, double wap, int count) = 0; 124 | virtual void currentTime(long time) = 0; 125 | virtual void fundamentalData(TickerId reqId, const IBString& data) = 0; 126 | virtual void deltaNeutralValidation(int reqId, const UnderComp& underComp) = 0; 127 | virtual void tickSnapshotEnd( int reqId) = 0; 128 | virtual void marketDataType( TickerId reqId, int marketDataType) = 0; 129 | virtual void commissionReport( const CommissionReport &commissionReport) = 0; 130 | virtual void position( const IBString& account, const Contract& contract, int position, double avgCost) = 0; 131 | virtual void positionEnd() = 0; 132 | virtual void accountSummary( int reqId, const IBString& account, const IBString& tag, const IBString& value, const IBString& curency) = 0; 133 | virtual void accountSummaryEnd( int reqId) = 0; 134 | virtual void verifyMessageAPI( const IBString& apiData) = 0; 135 | virtual void verifyCompleted( bool isSuccessful, const IBString& errorText) = 0; 136 | virtual void displayGroupList( int reqId, const IBString& groups) = 0; 137 | virtual void displayGroupUpdated( int reqId, const IBString& contractInfo) = 0; 138 | }; 139 | 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/EClientSocketBase.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef eclientsocketbase_h__INCLUDED 5 | #define eclientsocketbase_h__INCLUDED 6 | 7 | #include "EClient.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class EWrapper; 14 | 15 | class EClientSocketBase : public EClient 16 | { 17 | public: 18 | 19 | //(4 march 2013) JBOO: give access to private members; replaces '#define private public' in TwsApiL0.cpp 20 | friend struct EClientL0Impl; 21 | 22 | explicit EClientSocketBase(EWrapper *ptr); 23 | ~EClientSocketBase(); 24 | 25 | virtual bool eConnect(const char *host, unsigned int port, int clientId = 0, bool extraAuth = false) = 0; 26 | virtual void eDisconnect() = 0; 27 | 28 | int clientId() const { return m_clientId; } 29 | 30 | protected: 31 | 32 | void eConnectBase(); 33 | void eDisconnectBase(); 34 | 35 | public: 36 | 37 | // connection state 38 | bool isConnected() const; 39 | 40 | protected: 41 | 42 | // access to protected variables 43 | EWrapper * getWrapper() const; 44 | void setClientId( int clientId); 45 | void setExtraAuth( bool extraAuth); 46 | 47 | public: 48 | 49 | bool isInBufferEmpty() const; 50 | bool isOutBufferEmpty() const; 51 | 52 | // override virtual funcs from EClient 53 | int serverVersion(); 54 | IBString TwsConnectionTime(); 55 | void reqMktData(TickerId id, const Contract &contract, 56 | const IBString &genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions); 57 | void cancelMktData(TickerId id); 58 | void placeOrder(OrderId id, const Contract &contract, const Order &order); 59 | void cancelOrder(OrderId id) ; 60 | void reqOpenOrders(); 61 | void reqAccountUpdates(bool subscribe, const IBString& acctCode); 62 | void reqExecutions(int reqId, const ExecutionFilter& filter); 63 | void reqIds(int numIds); 64 | bool checkMessages(); 65 | void reqContractDetails(int reqId, const Contract &contract); 66 | void reqMktDepth(TickerId tickerId, const Contract &contract, int numRows, const TagValueListSPtr& mktDepthOptions); 67 | void cancelMktDepth(TickerId tickerId); 68 | void reqNewsBulletins(bool allMsgs); 69 | void cancelNewsBulletins(); 70 | void setServerLogLevel(int level); 71 | void reqAutoOpenOrders(bool bAutoBind); 72 | void reqAllOpenOrders(); 73 | void reqManagedAccts(); 74 | void requestFA(faDataType pFaDataType); 75 | void replaceFA(faDataType pFaDataType, const IBString& cxml); 76 | void reqHistoricalData( TickerId id, const Contract &contract, 77 | const IBString &endDateTime, const IBString &durationStr, 78 | const IBString & barSizeSetting, const IBString &whatToShow, 79 | int useRTH, int formatDate, const TagValueListSPtr& chartOptions); 80 | void exerciseOptions(TickerId tickerId, const Contract &contract, 81 | int exerciseAction, int exerciseQuantity, 82 | const IBString &account, int override); 83 | void cancelHistoricalData(TickerId tickerId ); 84 | void reqRealTimeBars(TickerId id, const Contract &contract, int barSize, 85 | const IBString &whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions); 86 | void cancelRealTimeBars(TickerId tickerId ); 87 | void cancelScannerSubscription(int tickerId); 88 | void reqScannerParameters(); 89 | void reqScannerSubscription(int tickerId, const ScannerSubscription &subscription, const TagValueListSPtr& scannerSubscriptionOptions); 90 | void reqCurrentTime(); 91 | void reqFundamentalData(TickerId reqId, const Contract&, const IBString& reportType); 92 | void cancelFundamentalData(TickerId reqId); 93 | void calculateImpliedVolatility(TickerId reqId, const Contract &contract, double optionPrice, double underPrice); 94 | void calculateOptionPrice(TickerId reqId, const Contract &contract, double volatility, double underPrice); 95 | void cancelCalculateImpliedVolatility(TickerId reqId); 96 | void cancelCalculateOptionPrice(TickerId reqId); 97 | void reqGlobalCancel(); 98 | void reqMarketDataType(int marketDataType); 99 | void reqPositions(); 100 | void cancelPositions(); 101 | void reqAccountSummary( int reqId, const IBString& groupName, const IBString& tags); 102 | void cancelAccountSummary( int reqId); 103 | void verifyRequest( const IBString& apiName, const IBString& apiVersion); 104 | void verifyMessage( const IBString& apiData); 105 | void queryDisplayGroups( int reqId); 106 | void subscribeToGroupEvents( int reqId, int groupId); 107 | void updateDisplayGroup( int reqId, const IBString& contractInfo); 108 | void unsubscribeFromGroupEvents( int reqId); 109 | 110 | private: 111 | 112 | virtual int send(const char* buf, size_t sz) = 0; 113 | virtual int receive(char* buf, size_t sz) = 0; 114 | 115 | protected: 116 | 117 | int sendBufferedData(); 118 | 119 | private: 120 | 121 | int bufferedSend(const char* buf, size_t sz); 122 | int bufferedSend(const std::string& msg); 123 | 124 | // read and buffer what's available 125 | int bufferedRead(); 126 | 127 | // try to process connection request ack 128 | int processConnectAck(const char*& ptr, const char* endPtr); 129 | 130 | // try to process single msg 131 | int processMsg(const char*& ptr, const char* endPtr); 132 | 133 | void startApi(); 134 | 135 | static bool CheckOffset(const char* ptr, const char* endPtr); 136 | static const char* FindFieldEnd(const char* ptr, const char* endPtr); 137 | 138 | // decoders 139 | static bool DecodeField(bool&, const char*& ptr, const char* endPtr); 140 | static bool DecodeField(int&, const char*& ptr, const char* endPtr); 141 | static bool DecodeField(long&, const char*& ptr, const char* endPtr); 142 | static bool DecodeField(double&, const char*& ptr, const char* endPtr); 143 | static bool DecodeField(IBString&, const char*& ptr, const char* endPtr); 144 | 145 | static bool DecodeFieldMax(int&, const char*& ptr, const char* endPtr); 146 | static bool DecodeFieldMax(long&, const char*& ptr, const char* endPtr); 147 | static bool DecodeFieldMax(double&, const char*& ptr, const char* endPtr); 148 | 149 | // encoders 150 | template static void EncodeField(std::ostream&, T); 151 | 152 | // "max" encoders 153 | static void EncodeFieldMax(std::ostream& os, int); 154 | static void EncodeFieldMax(std::ostream& os, double); 155 | 156 | // socket state 157 | virtual bool isSocketOK() const = 0; 158 | 159 | protected: 160 | 161 | void onConnectBase(); 162 | 163 | private: 164 | 165 | typedef std::vector BytesVec; 166 | 167 | private: 168 | 169 | static void CleanupBuffer(BytesVec&, int processed); 170 | 171 | private: 172 | 173 | EWrapper *m_pEWrapper; 174 | 175 | BytesVec m_inBuffer; 176 | BytesVec m_outBuffer; 177 | 178 | int m_clientId; 179 | 180 | bool m_connected; 181 | bool m_extraAuth; 182 | int m_serverVersion; 183 | IBString m_TwsTime; 184 | 185 | }; 186 | 187 | template<> void EClientSocketBase::EncodeField(std::ostream& os, bool); 188 | template<> void EClientSocketBase::EncodeField(std::ostream& os, double); 189 | 190 | #endif 191 | -------------------------------------------------------------------------------- /TwsApiC++/Test/_win32/Test.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 27 | 30 | 33 | 36 | 39 | 44 | 61 | 64 | 69 | 72 | 83 | 86 | 89 | 92 | 97 | 100 | 103 | 106 | 107 | 117 | 120 | 123 | 126 | 129 | 134 | 149 | 152 | 157 | 160 | 172 | 175 | 178 | 181 | 186 | 189 | 192 | 195 | 196 | 197 | 198 | 199 | 200 | 204 | 207 | 211 | 214 | 215 | 219 | 222 | 223 | 224 | 227 | 231 | 234 | 235 | 239 | 242 | 243 | 244 | 247 | 251 | 254 | 255 | 259 | 262 | 263 | 264 | 267 | 270 | 273 | 274 | 277 | 280 | 281 | 282 | 285 | 289 | 292 | 293 | 297 | 300 | 301 | 302 | 305 | 309 | 312 | 313 | 317 | 320 | 321 | 322 | 323 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | -------------------------------------------------------------------------------- /TwsApiC++/_win32/TwsApi.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 59 | 62 | 67 | 70 | 75 | 78 | 81 | 86 | 89 | 92 | 93 | 103 | 106 | 109 | 112 | 115 | 118 | 133 | 136 | 141 | 144 | 149 | 152 | 155 | 160 | 163 | 166 | 167 | 168 | 169 | 170 | 171 | 175 | 178 | 179 | 182 | 185 | 190 | 191 | 194 | 199 | 200 | 201 | 202 | 206 | 209 | 210 | 213 | 214 | 217 | 218 | 219 | 222 | 225 | 229 | 232 | 233 | 237 | 240 | 241 | 242 | 245 | 249 | 252 | 253 | 257 | 260 | 261 | 262 | 265 | 266 | 269 | 270 | 271 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 314 | 317 | 318 | 321 | 322 | 325 | 326 | 329 | 330 | 333 | 334 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | -------------------------------------------------------------------------------- /source/PosixClient/Shared/Order.h: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Interactive Brokers LLC. All rights reserved. This code is subject to the terms 2 | * and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. */ 3 | 4 | #ifndef order_def 5 | #define order_def 6 | 7 | #include "TagValue.h" 8 | 9 | #include 10 | #include 11 | 12 | #define UNSET_DOUBLE DBL_MAX 13 | #define UNSET_INTEGER INT_MAX 14 | 15 | enum Origin { CUSTOMER, 16 | FIRM, 17 | UNKNOWN }; 18 | 19 | enum AuctionStrategy { AUCTION_UNSET = 0, 20 | AUCTION_MATCH = 1, 21 | AUCTION_IMPROVEMENT = 2, 22 | AUCTION_TRANSPARENT = 3 }; 23 | 24 | struct OrderComboLeg 25 | { 26 | OrderComboLeg() 27 | { 28 | price = UNSET_DOUBLE; 29 | } 30 | 31 | double price; 32 | 33 | bool operator==( const OrderComboLeg &other) const 34 | { 35 | return (price == other.price); 36 | } 37 | }; 38 | 39 | typedef shared_ptr OrderComboLegSPtr; 40 | 41 | struct Order 42 | { 43 | Order() 44 | { 45 | // order identifier 46 | orderId = 0; 47 | clientId = 0; 48 | permId = 0; 49 | 50 | // main order fields 51 | totalQuantity = 0; 52 | lmtPrice = UNSET_DOUBLE; 53 | auxPrice = UNSET_DOUBLE; 54 | 55 | // extended order fields 56 | activeStartTime = ""; 57 | activeStopTime = ""; 58 | ocaType = 0; 59 | transmit = true; 60 | parentId = 0; 61 | blockOrder = false; 62 | sweepToFill = false; 63 | displaySize = 0; 64 | triggerMethod = 0; 65 | outsideRth = false; 66 | hidden = false; 67 | allOrNone = false; 68 | minQty = UNSET_INTEGER; 69 | percentOffset = UNSET_DOUBLE; 70 | overridePercentageConstraints = false; 71 | trailStopPrice = UNSET_DOUBLE; 72 | trailingPercent = UNSET_DOUBLE; 73 | 74 | // institutional (ie non-cleared) only 75 | openClose = "O"; 76 | origin = CUSTOMER; 77 | shortSaleSlot = 0; 78 | exemptCode = -1; 79 | 80 | // SMART routing only 81 | discretionaryAmt = 0; 82 | eTradeOnly = true; 83 | firmQuoteOnly = true; 84 | nbboPriceCap = UNSET_DOUBLE; 85 | optOutSmartRouting = false; 86 | 87 | // BOX exchange orders only 88 | auctionStrategy = AUCTION_UNSET; 89 | startingPrice = UNSET_DOUBLE; 90 | stockRefPrice = UNSET_DOUBLE; 91 | delta = UNSET_DOUBLE; 92 | 93 | // pegged to stock and VOL orders only 94 | stockRangeLower = UNSET_DOUBLE; 95 | stockRangeUpper = UNSET_DOUBLE; 96 | 97 | // VOLATILITY ORDERS ONLY 98 | volatility = UNSET_DOUBLE; 99 | volatilityType = UNSET_INTEGER; // 1=daily, 2=annual 100 | deltaNeutralOrderType = ""; 101 | deltaNeutralAuxPrice = UNSET_DOUBLE; 102 | deltaNeutralConId = 0; 103 | deltaNeutralSettlingFirm = ""; 104 | deltaNeutralClearingAccount = ""; 105 | deltaNeutralClearingIntent = ""; 106 | deltaNeutralOpenClose = ""; 107 | deltaNeutralShortSale = false; 108 | deltaNeutralShortSaleSlot = 0; 109 | deltaNeutralDesignatedLocation = ""; 110 | continuousUpdate = false; 111 | referencePriceType = UNSET_INTEGER; // 1=Average, 2 = BidOrAsk 112 | 113 | // COMBO ORDERS ONLY 114 | basisPoints = UNSET_DOUBLE; // EFP orders only 115 | basisPointsType = UNSET_INTEGER; // EFP orders only 116 | 117 | // SCALE ORDERS ONLY 118 | scaleInitLevelSize = UNSET_INTEGER; 119 | scaleSubsLevelSize = UNSET_INTEGER; 120 | scalePriceIncrement = UNSET_DOUBLE; 121 | scalePriceAdjustValue = UNSET_DOUBLE; 122 | scalePriceAdjustInterval = UNSET_INTEGER; 123 | scaleProfitOffset = UNSET_DOUBLE; 124 | scaleAutoReset = false; 125 | scaleInitPosition = UNSET_INTEGER; 126 | scaleInitFillQty = UNSET_INTEGER; 127 | scaleRandomPercent = false; 128 | scaleTable = ""; 129 | 130 | // What-if 131 | whatIf = false; 132 | 133 | // Not Held 134 | notHeld = false; 135 | } 136 | 137 | // order identifier 138 | long orderId; 139 | long clientId; 140 | long permId; 141 | 142 | // main order fields 143 | IBString action; 144 | long totalQuantity; 145 | IBString orderType; 146 | double lmtPrice; 147 | double auxPrice; 148 | 149 | // extended order fields 150 | IBString tif; // "Time in Force" - DAY, GTC, etc. 151 | IBString activeStartTime; // for GTC orders 152 | IBString activeStopTime; // for GTC orders 153 | IBString ocaGroup; // one cancels all group name 154 | int ocaType; // 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK 155 | IBString orderRef; // order reference 156 | bool transmit; // if false, order will be created but not transmited 157 | long parentId; // Parent order Id, to associate Auto STP or TRAIL orders with the original order. 158 | bool blockOrder; 159 | bool sweepToFill; 160 | int displaySize; 161 | int triggerMethod; // 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point 162 | bool outsideRth; 163 | bool hidden; 164 | IBString goodAfterTime; // Format: 20060505 08:00:00 {time zone} 165 | IBString goodTillDate; // Format: 20060505 08:00:00 {time zone} 166 | IBString rule80A; // Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N' 167 | bool allOrNone; 168 | int minQty; 169 | double percentOffset; // REL orders only 170 | bool overridePercentageConstraints; 171 | double trailStopPrice; // TRAILLIMIT orders only 172 | double trailingPercent; 173 | 174 | // financial advisors only 175 | IBString faGroup; 176 | IBString faProfile; 177 | IBString faMethod; 178 | IBString faPercentage; 179 | 180 | // institutional (ie non-cleared) only 181 | IBString openClose; // O=Open, C=Close 182 | Origin origin; // 0=Customer, 1=Firm 183 | int shortSaleSlot; // 1 if you hold the shares, 2 if they will be delivered from elsewhere. Only for Action="SSHORT 184 | IBString designatedLocation; // set when slot=2 only. 185 | int exemptCode; 186 | 187 | // SMART routing only 188 | double discretionaryAmt; 189 | bool eTradeOnly; 190 | bool firmQuoteOnly; 191 | double nbboPriceCap; 192 | bool optOutSmartRouting; 193 | 194 | // BOX exchange orders only 195 | int auctionStrategy; // AUCTION_MATCH, AUCTION_IMPROVEMENT, AUCTION_TRANSPARENT 196 | double startingPrice; 197 | double stockRefPrice; 198 | double delta; 199 | 200 | // pegged to stock and VOL orders only 201 | double stockRangeLower; 202 | double stockRangeUpper; 203 | 204 | // VOLATILITY ORDERS ONLY 205 | double volatility; 206 | int volatilityType; // 1=daily, 2=annual 207 | IBString deltaNeutralOrderType; 208 | double deltaNeutralAuxPrice; 209 | long deltaNeutralConId; 210 | IBString deltaNeutralSettlingFirm; 211 | IBString deltaNeutralClearingAccount; 212 | IBString deltaNeutralClearingIntent; 213 | IBString deltaNeutralOpenClose; 214 | bool deltaNeutralShortSale; 215 | int deltaNeutralShortSaleSlot; 216 | IBString deltaNeutralDesignatedLocation; 217 | bool continuousUpdate; 218 | int referencePriceType; // 1=Average, 2 = BidOrAsk 219 | 220 | // COMBO ORDERS ONLY 221 | double basisPoints; // EFP orders only 222 | int basisPointsType; // EFP orders only 223 | 224 | // SCALE ORDERS ONLY 225 | int scaleInitLevelSize; 226 | int scaleSubsLevelSize; 227 | double scalePriceIncrement; 228 | double scalePriceAdjustValue; 229 | int scalePriceAdjustInterval; 230 | double scaleProfitOffset; 231 | bool scaleAutoReset; 232 | int scaleInitPosition; 233 | int scaleInitFillQty; 234 | bool scaleRandomPercent; 235 | IBString scaleTable; 236 | 237 | // HEDGE ORDERS 238 | IBString hedgeType; // 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair 239 | IBString hedgeParam; // 'beta=X' value for beta hedge, 'ratio=Y' for pair hedge 240 | 241 | // Clearing info 242 | IBString account; // IB account 243 | IBString settlingFirm; 244 | IBString clearingAccount; // True beneficiary of the order 245 | IBString clearingIntent; // "" (Default), "IB", "Away", "PTA" (PostTrade) 246 | 247 | // ALGO ORDERS ONLY 248 | IBString algoStrategy; 249 | 250 | TagValueListSPtr algoParams; 251 | TagValueListSPtr smartComboRoutingParams; 252 | 253 | IBString algoId; 254 | 255 | // What-if 256 | bool whatIf; 257 | 258 | // Not Held 259 | bool notHeld; 260 | 261 | // order combo legs 262 | typedef std::vector OrderComboLegList; 263 | typedef shared_ptr OrderComboLegListSPtr; 264 | 265 | OrderComboLegListSPtr orderComboLegs; 266 | 267 | TagValueListSPtr orderMiscOptions; 268 | 269 | public: 270 | 271 | // Helpers 272 | static void CloneOrderComboLegs(OrderComboLegListSPtr& dst, const OrderComboLegListSPtr& src); 273 | }; 274 | 275 | inline void 276 | Order::CloneOrderComboLegs(OrderComboLegListSPtr& dst, const OrderComboLegListSPtr& src) 277 | { 278 | if (!src.get()) 279 | return; 280 | 281 | dst->reserve(src->size()); 282 | 283 | OrderComboLegList::const_iterator iter = src->begin(); 284 | const OrderComboLegList::const_iterator iterEnd = src->end(); 285 | 286 | for (; iter != iterEnd; ++iter) { 287 | const OrderComboLeg* leg = iter->get(); 288 | if (!leg) 289 | continue; 290 | dst->push_back(OrderComboLegSPtr(new OrderComboLeg(*leg))); 291 | } 292 | } 293 | 294 | #endif 295 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TwsApiC++ 2 | 3 | TwsApiC++ is a library build on top of the IB POSIX C++ library and makes programming with the IB api more easy and more robust. 4 | * it exposes only the 'trading functionality' available in [directory Shared](https://github.com/JanBoonen/TwsApiCpp/tree/master/source/PosixClient/Shared) 5 | * it hides all other non-trading functionality (i.e. sockets) 6 | * it resolves many issues left in the IB POSIX library in a safe and robust way and protects the programmer from hard to discover pitfalls hidden in the IB code. 7 | 8 | See the [wiki history](https://github.com/JanBoonen/TwsApiCpp/wiki/History) page for a more detailed description and why it was created. It will be true for the upcoming version 9.72 as well. 9 | 10 | See [what makes the use of twsapic worthwile](https://github.com/JanBoonen/TwsApiCpp/blob/master/README.md#what-makes-the-use-of-twsapic-worthwile) for a more detailed description of the issues TwsApiC++ resolves. 11 | 12 | TwsApiC++ is availble freely since 2008 in [Yahoo's Interactive Brokers TWS APIDiscussion Groups](https://groups.yahoo.com/neo/groups/TWSAPI/files/C%2B%2B%20Code/TwsApiC%2B%2B%20Directory/). Versions 9.71 and up will be available only via this Github. 13 | 14 | TwsApiC++ is a ‘closed’ library on purpose. This means you cannot derive from its EClient (EClientL0) class and overwrites its methods. That guarantees the library remains robust and solid and prevents its inner workings are broken by accident. And why would you? Your trading system **uses** the EClient to achieve it's goal and **is not** an EClient. So use it as a member of your trading class. 15 | 16 | 17 | ## Compiling and execution 18 | This project includes all necessary IB POSIX C++ source files, no need to install the IB api first. 19 | 20 | TwsApiC++ has been installed and compiled on many different platforms. Unix/linux make files and Visual Studio project files are included. 21 | * directory TwsApiC++ contains the specific non IB sources code for this library 22 | * directory source/PosixClient contains the copy of the IB POSIX C++ sources. 23 | * sub-directories _cygwin, _linux and _win32 contain the make/project files respectivey 24 | It should normaly compile 'out of the box' and the compiled libraries are written into TwsApiCpp/TwsApiC++/Api/ and can be linked from there. 25 | 26 | The footprint of the library is small and fast. 27 | 28 | ## Examples programs 29 | There are some examples programs included in the delivery in the [TwsApiC++/Test/Src](https://github.com/JanBoonen/TwsApiCpp/tree/master/TwsApiC%2B%2B/Test/Src) directory. 30 | 31 | An simple example that demonstrates some strengths of the library is [Retrieve History](https://github.com/JanBoonen/TwsApiCpp/wiki/Example:-Retrieve-History) in the wiki pages. 32 | 33 | ## What makes the use of TwsApiC++ worthwile 34 | 35 | * **Easy access to ful functionality** 36 | 37 | Including **TwsApiL0.h** is all it takes to have access to the full functionality. 38 | 39 | * **No knowledge of sockets programming required** 40 | 41 | It reinstates the **EClient** and **EWrapper** in combination with the other classes (Contract, Order, Execution, etc) in the **[Shared](https://github.com/JanBoonen/TwsApiCpp/tree/master/source/PosixClient/Shared)** directory as the interface to all the functionality offered by IB 42 | 43 | To achieve that, TwsApiC++ takes care of the specific POSIX classes in source/PosixClient/src and these socket low level programming features one should not bothered with. These were inroduced in version 9.62. See the [wiki history](https://github.com/JanBoonen/TwsApiCpp/wiki/Home---History) page for a more lengthy explanation. 44 | 45 | 46 | * **Resolves socket connection related issues left to the programmer in the IB POSIX implementation** 47 | 48 | TwsApiC++ ensures no data is stuck in the internal buffer of the IB api when the first attempt to send it to the TWS fails for some reason. Otherwise, it would sit there until the next EClient call is executed. 49 | 50 | 51 | * **Provides default empty method for each EWrapper method** 52 | 53 | This means that you don't have to implement each EWrapper methods for yourself. TwsApiC++ does that for you. 54 | 55 | * **Notifies when default empty EWrapper is called** 56 | 57 | When starting with the api, it might not always be clear from the documentation what events (methods in the EWrapper) are involved (called). The default methods therefore print a warning message (see #define EWRAPPERL0_DEFAULT) when called to ensure each method involved gets it implementation. 58 | 59 | Another situation might be that you made a mistake in definition of the method, or that the method signature got changed in the newer version. In that case, the default methods is called instead of yours. The notification will alert you. 60 | 61 | Only in debug mode. 62 | 63 | 64 | * **Provides 'EReader'** 65 | 66 | TwsApiC++ implements EReader functionality as found in the Java api and in the MS Windows based version of the C++ api. It runs in a separate thread and sits there waiting for incoming data to be processed without any delay (calling your EWrapper). 67 | 68 | Can be switched off simply by passing a parameter when instantiating the EWrapper class. In that case repetitive calling the non-blocking EClient::checkMessages() (see below) is necessarily to check for incoming events (data) send by the TWS. 69 | 70 | See [Example: With or without the 'EReader'](https://github.com/JanBoonen/TwsApiCpp/wiki/Example:-With-or-without-the-'EReader') 71 | 72 | 73 | * **Provides non-blocking EClient::checkMessages()** 74 | 75 | The IB's implementation of EClient::checkMessage() call halts the programs until data is send to the client. TwsApiC++ overloads this method as a non-blocking call that waits for maximum 1 millisecond and which is safe to call in an endless loop without cpu usage penalty: when no data is received. 76 | 77 | See the example [Clients.cpp](https://github.com/JanBoonen/TwsApiCpp/blob/master/TwsApiC++/Test/Src/Clients.cpp?ts=4). It makes 8 connections simultaneously (maximum possible per client) and calls each of the 8 checkMessages() in a loop, or uses the EReader for each connection. 78 | 79 | 80 | * **Provides help with the many textual and numeric parameter values** 81 | 82 | As a programmer, you need to pass a lot of textual parameters into the EClient methods parameters and you have to compare incomings strings parameters in the EWrapper to interprete them. This is a big issue because these values are not always very well documented and making a typo can be hard to detect at runtime. 83 | 84 | TwsApiC++ has predefined these values: 85 | * allows them to use as named parameters what enables the compiler to check 86 | * definitions are grouped per parameter, can be used in if statements and switch statementt 87 | * all numeric values have a string value what makes reading code a lot easier, and can be printed out in the program as such 88 | * unknown parameter values received in EWrapper can be recognised and and can be printed i.e. 89 | 90 | A quick example: 91 | ```C++ 92 | // Just imagine you wrote 93 | if( key == "LookaheadAvailableFunds" ) { ... } // hmm, will never be executed 94 | // => because correct spelling is 95 | if( key == "LookAheadAvailableFunds" ) { ... } 96 | 97 | // instead you can write 98 | if( UpdateAccountValueKey(key) == UpdateAccountValueKey::LookAheadAvailableFunds ) { ... } 99 | // or 100 | switch( UpdateAccountValueKey(key) ) { 101 | case UpdateAccountValueKey::LookAheadAvailableFunds: 102 | break; 103 | ... 104 | case UpdateAccountValueKey::_INVALID_: // key was not recognised - missing - report it!! 105 | break; 106 | 107 | default: 108 | break; 109 | } 110 | 111 | // and the following would raise a compiling error 112 | if( UpdateAccountValueKey(key) == UpdateAccountValueKey::LookaheadAvailableFunds ) { ... } 113 | 114 | // while the following doesn't, but does not work at runtime either! 115 | if( key == "LookaheadAvailableFunds" ) { ... } // Ahead with capital A! 116 | ``` 117 | 118 | See for [more explanation](https://github.com/JanBoonen/TwsApiCpp/wiki/TwsApiDefs.h) or for all [definitions](https://github.com/JanBoonen/TwsApiCpp/blob/master/TwsApiC++/Api/TwsApiDefs.h?ts=4). 119 | 120 | 121 | * **Protects the original IB code from uncatched exceptions thrown from the users EWrapper code** 122 | 123 | TwsApiC++ protects the inner workings of the IB library against exceptions thrown inadvertently from within the user code statements in the derived EWrapper methods. Otherwise, these woud raise error *509, "Exception caught while reading socket - "* and parsing the incoming data would be halted. 124 | 125 | TwsApiC++ extends EWrapper with the method **onCatch( const char* MethodName, const long Id )** and calls it when it intercepts such exception. 126 | 127 | 128 | * **Protects the user against unintentionally concurrent use of its internal data** 129 | 130 | Calling the same instance of EClient simultaniously could lead to the loss of requests send to the TWS, i.e. when the automatic ‘EReader’ thread is used and both the main thread and the EWrapper call methods of EClient. 131 | 132 | TwsApiC++ uses critical sections to prevents this situation. 133 | 134 | 135 | * **‘closed’ library by design** 136 | 137 | You cannot derive from its EClient class directly and overwrites its methods. This will ensure the integrity of the whole safety measures build into this library. 138 | 139 | 140 | * **EWRapper::connectionClosed()** 141 | 142 | TwsApiC++ garantees the EWRapper::connectionClosed() is called when the connection is closed for any reason, on purpose (eDisconnect()) or not. Every second a ‘heartbeat’ is send over the socket to check the status of the connection. This ensures the proper closing of the connection in case something went wrong. 143 | 144 | Note: There is no automatic reconnection 145 | -------------------------------------------------------------------------------- /TwsApiC++/Test/Src/Test.cpp: -------------------------------------------------------------------------------- 1 | //============================================================================ 2 | // TwsApi Test 3 | //============================================================================ 4 | #include "TwsApiL0.h" 5 | #include "TwsApiDefs.h" 6 | using namespace TwsApi; 7 | 8 | // to use the Sleep function 9 | #ifdef WIN32 10 | #include // Sleep(), in miliseconds 11 | #include 12 | #define CurrentThreadId GetCurrentThreadId 13 | #else 14 | #include // usleep(), in microseconds 15 | #define Sleep( m ) usleep( m*1000 ) 16 | #include 17 | #define CurrentThreadId pthread_self 18 | #endif 19 | 20 | #define PrintProcessId printf("%ld ", CurrentThreadId() ) 21 | 22 | #include 23 | 24 | 25 | 26 | //---------------------------------------------------------------------------- 27 | // MyEWrapper 28 | //---------------------------------------------------------------------------- 29 | class MyEWrapper: public EWrapperL0 30 | { 31 | public: 32 | MyEWrapper( bool CalledFromThread = true ): EWrapperL0( CalledFromThread ) {} 33 | 34 | virtual void tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute ) 35 | { 36 | /// int id = 10, y = 0; id = id/y; // Divide by zero to test EWrapperL0Protected 37 | /// int *id = 0; *id = 100; 38 | 39 | /// throw(0); 40 | 41 | // time_t _t = GetEventTime(); // !! from L1 42 | time_t _t; time(&_t); 43 | struct tm* _tm = localtime( &_t ); 44 | PrintProcessId,printf 45 | ( "TP: %4ld %02d:%02d:%02d %10s %5.3f\n" 46 | , tickerId 47 | , _tm->tm_hour, _tm->tm_min, _tm->tm_sec 48 | , *(TickTypes::ENUMS)field, price 49 | ); 50 | } 51 | 52 | virtual void tickSize( TickerId tickerId, TickType field, int size ) 53 | { 54 | // time_t _t = GetEventTime(); // !! from L1 55 | time_t _t; time(&_t); 56 | struct tm* _tm = localtime( &_t ); 57 | PrintProcessId,printf 58 | ( "TS: %4ld %02d:%02d:%02d %10s %5d\n" 59 | , tickerId 60 | , _tm->tm_hour, _tm->tm_min, _tm->tm_sec 61 | , *(TickTypes::ENUMS)field, size 62 | ); 63 | } 64 | 65 | virtual void winError( const IBString& str, int lastError ) 66 | { 67 | PrintProcessId,printf( "WinError: %d = %s\n", lastError, (const char*)str ); 68 | } 69 | 70 | virtual void connectionClosed() 71 | { 72 | PrintProcessId,printf( "Connection Closed\n"); 73 | } 74 | 75 | virtual void updateAccountValue( const IBString& key, const IBString& val, const IBString& currency, const IBString& accountName ) 76 | { 77 | UpdateAccountValueKey::ENUMS UAVK; 78 | if( UAVK *= key ) 79 | PrintProcessId,printf( "AC: %s %5s %-30s %s\n", (const char*)accountName, (const char*)currency, *UAVK, (const char*)val ); 80 | else 81 | PrintProcessId,printf( "AC: %s %5s ? %-30s %s\n", (const char*)accountName, (const char*)currency, (const char*)key, (const char*)val ); 82 | } 83 | 84 | virtual void accountDownloadEnd( const IBString& accountName ) 85 | { 86 | PrintProcessId,printf( "AC: %s end\n", (const char*)accountName ); 87 | } 88 | 89 | virtual void nextValidId( OrderId orderId ) 90 | { 91 | PrintProcessId,printf( "nextValidId = %ld\n", orderId ); 92 | } 93 | 94 | virtual void contractDetails( const ContractDetails& contractDetails ) 95 | { 96 | const Contract& C = contractDetails.summary; 97 | 98 | PrintProcessId,printf ( "CD: %10s %5s %8s, %5.2f\n", (const char*)C.localSymbol, (const char*)C.secType, (const char*)C.expiry, C.strike ); 99 | } 100 | 101 | virtual void error( const int id, const int errorCode, const IBString errorString ) 102 | { 103 | PrintProcessId,printf( "Error for id=%d: %d = %s\n", id, errorCode, (const char*)errorString ); 104 | } 105 | 106 | virtual void historicalData( TickerId reqId, const IBString& date, double open, double high, double low, double close, int volume, int barCount, double WAP, int hasGaps ) 107 | { 108 | if( IsEndOfHistoricalData(date) ) 109 | { 110 | PrintProcessId,printf( "HD: %s\n", Finished() ); 111 | return; 112 | } 113 | 114 | PrintProcessId,printf( "HD: %4ld %10s %5.3f %5.3f %5.3f %5.3f %7d %7d\n", reqId, (const char*)date, open, high, low, close, volume, barCount ); 115 | } 116 | 117 | virtual void updateMktDepth(TickerId id, int position, int operation, int side, double price, int size ) 118 | { 119 | PrintProcessId,printf 120 | ( "MD: %4ld %2d %10s %5s %7.2f %5d\n" 121 | , id 122 | , position 123 | , *(MktDepthOperation::ENUMS) operation 124 | , *(MktDeptSide::ENUMS)side 125 | , price 126 | , size 127 | ); 128 | } 129 | 130 | virtual void updateMktDepthL2(TickerId id, int position, IBString marketMaker, int operation, int side, double price, int size ) 131 | { 132 | } 133 | 134 | 135 | virtual void connectionOpened( void ) 136 | { 137 | PrintProcessId,printf( "Connection Opened\n"); 138 | } 139 | 140 | virtual void checkMessagesStarted( void ) 141 | { 142 | PrintProcessId,printf( ">>> checkMessagesStarted\n"); 143 | } 144 | 145 | virtual void checkMessagesStopped( void ) 146 | { 147 | PrintProcessId,printf( "<<< checkMessagesStopped\n"); 148 | } 149 | }; 150 | 151 | //---------------------------------------------------------------------------- 152 | // TestEnums 153 | //---------------------------------------------------------------------------- 154 | void TestEnums( void ) 155 | { 156 | IBString id = *TickTypes::Bid; 157 | id = *OrderStatus::PendingCancel; 158 | 159 | IBString y; 160 | y = *TriggerMethod::LastPrice; 161 | 162 | OrderStatus::ENUMS e; 163 | if( e *= "PendingCancel" ) 164 | { printf("OK\t"); } 165 | else 166 | { printf("NOK\t"); } 167 | printf( "%4d %s\n", e, *e ); 168 | 169 | 170 | if( e *= "not a status" ) 171 | { printf("OK\t"); } 172 | else 173 | { printf("NOK\t"); } 174 | printf( "%4d %s\n", e, *e ); 175 | 176 | switch( OrderStatus("PendingCancelxxxx") ) 177 | { 178 | case OrderStatus::PendingCancel: 179 | { printf("OK\n"); } break; 180 | case OrderStatus::_INVALID_: 181 | { printf("NOK\n"); } break; 182 | default: 183 | { printf("??\n"); } break; 184 | } 185 | 186 | // The iterator has a similar interface as the of the std::map 187 | for( UpdateAccountValueKey::iterator ac = UpdateAccountValueKey::begin(); ac != UpdateAccountValueKey::end(); ++ac ) 188 | printf( "%4d %s\n", ac->first, ac->second ); 189 | 190 | } 191 | 192 | 193 | 194 | //---------------------------------------------------------------------------- 195 | // Marco TEST 196 | // Prints out the statement before executing it. 197 | // Used just to demonstrate the api: you see the statement, and then the result 198 | // i.e.: TEST(id, EC->reqMktData( id, C, "", false ) ); 199 | // Without TEST: EC->reqMktData( id, C, "", false ); 200 | //---------------------------------------------------------------------------- 201 | #define TEST( T, X ) ( printf( "T%7d %s\n", T, #X ), X ) 202 | 203 | //---------------------------------------------------------------------------- 204 | // main 205 | //---------------------------------------------------------------------------- 206 | 207 | 208 | struct Contract_ : public Contract 209 | { 210 | Contract_( IBString sb, IBString st, IBString cr, IBString ex, IBString pr_ex ) 211 | : Contract() 212 | { 213 | symbol = sb; 214 | secType = st; //"STK" 215 | currency = cr; 216 | exchange = ex; //"SMART"; 217 | primaryExchange = pr_ex; //"ISLAND"; 218 | } 219 | }; 220 | 221 | Contract_ C( "MSFT", *SecType::STK, "USD", *Exchange::IB_SMART, *Exchange::ISLAND ); 222 | 223 | int main( void ) 224 | { 225 | printf( "APIVersion = %s\n", EClientL0::apiVersion() ); 226 | 227 | // TestEnums(); 228 | 229 | //Contract_ C( "MSFT", *SecType::STK, "USD", *Exchange::IB_SMART ); 230 | 231 | /* 232 | Contract C; 233 | C.symbol = "MSFT"; 234 | C.secType = *SecType::STK; //"STK" 235 | C.currency = "USD"; 236 | C.exchange = *Exchange::IB_SMART; //"SMART"; 237 | // C.primaryExchange = *Exchange::AMEX; 238 | */ 239 | // from version 9.63 on, the protected ewrapper is active by default 240 | MyEWrapper MW; 241 | EClientL0* EC = EClientL0::New( &MW ); 242 | 243 | printf( "ClientVersion = %d\n", EC->clientVersion() ); 244 | 245 | TEST(0, EC->eDisconnect() ); // only for test purposes 246 | 247 | if( TEST(0, EC->eConnect( "", 7496, 100 )) ) 248 | { 249 | PrintProcessId,printf( "ServerVersion = %d\n", EC->serverVersion() ); 250 | 251 | // EC->reqNewsBulletins( true ); 252 | // EC->reqNewsBulletins( true ); 253 | /* 254 | TEST( 0, EC->reqAccountUpdates( true, "" ) ); 255 | */ 256 | 257 | // for( int i = 0; i < 60; i++ ) 258 | TEST( 100, EC->reqMktData( 100, C, "", false ) ); 259 | /* 260 | EC->reqMktDepth( 11, C, 3 ); 261 | */ 262 | EC->reqHistoricalData 263 | ( 20 264 | , C 265 | , EndDateTime(2014,8,4) 266 | , DurationStr(1, *DurationHorizon::Days) 267 | , *BarSizeSetting::_1_hour 268 | , *WhatToShow::TRADES 269 | , true 270 | , FormatDate::AsDate 271 | ); 272 | /* 273 | // EC->reqMktData( 20, C, false ); 274 | EC->reqHistoricalData 275 | ( 20//EC->GetNextValidId() 276 | , C 277 | , EndDateTime(2006,10,03), DurationStr(1, DH_Days), *BarSizeSetting::_1_secs 278 | , *WS_TRADES 279 | , true 280 | , FD_AsDate 281 | ); 282 | */ 283 | { 284 | Contract C; 285 | C.symbol = "C"; 286 | C.secType = *SecType::OPT; //"STK" 287 | C.currency = "USD"; 288 | C.exchange = *Exchange::IB_SMART; //"SMART"; 289 | EC->reqContractDetails( 25, C ); 290 | 291 | 292 | // EC->reqContractDetails( C ); 293 | } 294 | /* QQQQ 295 | C.symbol = "DNEX"; 296 | EC->reqContractDetails( C ); 297 | 298 | C.symbol = "MSFT"; 299 | EC->reqContractDetails( C ); 300 | */ 301 | } 302 | 303 | int id = 1; 304 | while( id++ < 1000 ) 305 | { 306 | // if( !MW.IsCalledFromThread() ) EC->checkMessages(); 307 | Sleep( 100 ); 308 | 309 | /* for 'stress' testing */ 310 | if( 0 == id%50) 311 | TEST(id, EC->reqMktData( id, C, "", false ) ); 312 | /**/ 313 | if( 30 == id) 314 | TEST(id, EC->eDisconnect() ); 315 | /**/ 316 | if( 40 == id) 317 | TEST(id, EC->eDisconnect() ); 318 | 319 | 320 | if( 60 == id || 70 == id ) 321 | TEST(id, EC->reqMktData( id, C, "", false ) ); // will fail of course 322 | 323 | 324 | if( 130 == id) 325 | TEST(id, EC->eConnect( "", 7496, 10 ) ); 326 | 327 | if( 150 == id) 328 | TEST(id, EC->eConnect( "", 7496, 10 ) ); // raises already connected error 329 | 330 | if( 190 == id ) 331 | TEST(id, 332 | EC->reqHistoricalData 333 | ( id 334 | , C 335 | , EndDateTime(2013,02,20), DurationStr(1, *DurationHorizon::Days), *BarSizeSetting::_1_hour 336 | , *WhatToShow::TRADES 337 | , true 338 | , FormatDate::AsDate 339 | ) 340 | ); 341 | 342 | if( 200 == id ) 343 | TEST(id, EC->reqMktData( id, C, "", false ) ); 344 | 345 | /**/ 346 | if( 800 == id) 347 | TEST(id, EC->cancelMktData( 200 ) ); 348 | /**/ 349 | } 350 | 351 | 352 | TEST( 0, EC->eDisconnect() ); 353 | 354 | delete EC; 355 | 356 | { PrintProcessId,printf( "Press return to end\n" ); char s[10]; gets(s); } 357 | return 0; 358 | } 359 | -------------------------------------------------------------------------------- /TwsApiC++/Api/TwsApiL0.h: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | TwsApiL0.h 3 | 4 | Provide a portable and a platform/vendor independant C++ API based on the 5 | POSIX C++ API provided by IB, that is backward compatible with version 9.60 6 | and before. 7 | 8 | In the default mode, a seperate thread reads the incoming data from TWS and 9 | calls the EWrapper events automatically. Calling checkMessages() is not 10 | needed and doing so would make no difference. 11 | 12 | Changing this default mode is possible, see constructor of EWrapperL0, and 13 | in that case, checkMessages() MUST be called periodically. 14 | 15 | EWrapperL0 extends EWrapper with a connectionOpened() event for reasons of 16 | symmetry with connectionClosed(). It is called just before eConnect() returns 17 | if the connection was established successfuly. 18 | 19 | Each EWrapperL0 event has a default empty implementation for convenience. 20 | 21 | Internally, a layer protects the TwsApi from untrapped exceptions thrown by 22 | the user implemented EWrapper methods. When such exception is trapped, this 23 | internal layer calls the new method EWrapper::OnCatch(). 24 | 25 | EClientL0 extends EClient with clientVersion() that returns the client version 26 | currently in use, this in symmetry with serverVersion(). 27 | 28 | \*===========================================================================*/ 29 | #ifndef _TwsApiL0_h 30 | #define _TwsApiL0_h 31 | 32 | //---------------------------------------------------------------------------- 33 | // Add some C necessirites (for linux) 34 | //---------------------------------------------------------------------------- 35 | #include 36 | #include 37 | 38 | //---------------------------------------------------------------------------- 39 | // IBString is extended for downward compatibility 40 | // and to make the TwsApiDefs special operators work 41 | //---------------------------------------------------------------------------- 42 | #define IB_USE_STD_STRING 43 | /**/ 44 | #define IBString _IBString 45 | #include "IBString.h" 46 | #undef IBString 47 | 48 | struct IBString: public _IBString 49 | { 50 | IBString( void ) { reserve(32); } 51 | IBString( const char* s ) { this->assign(s); } 52 | IBString( const std::string& s ) { this->assign(s.data()); } 53 | 54 | operator const char* (void) const{ return data(); } 55 | }; 56 | /**/ 57 | 58 | // The other includes from shared 59 | #include "EWrapper.h" 60 | #include "EClient.h" 61 | #include "Contract.h" 62 | #include "Execution.h" 63 | #include "OrderState.h" // includes order.h 64 | #include "ScannerSubscription.h" 65 | #include "CommissionReport.h" 66 | 67 | #include "TwsSocketClientErrors.h" 68 | 69 | // An extra error to indicate a thread couldn't start during eConnect when asked for 70 | static const CodeMsgPair COULD_NOT_START_THREAD( 700, "Couldn't start thread to read incomming messages." ); 71 | 72 | //---------------------------------------------------------------------------- 73 | // EClientL0 74 | //---------------------------------------------------------------------------- 75 | class EClientL0: public EClient 76 | { 77 | public: 78 | 79 | // A static member that allocates an instance of this EClientL0 80 | static EClientL0* New( class EWrapperL0* Wrapper ); 81 | 82 | // A static member that returns the api version 83 | static const char* apiVersion( void ) { return (const char*)"9.71"; } 84 | 85 | // See all members declared in EClient 86 | 87 | // set the last parameter "const TagValueListSPtr&" to an empty as it is only for IB internal use! 88 | virtual void reqMktData( TickerId id, const Contract &contract, const IBString& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions = TagValueListSPtr()) = 0; 89 | virtual void reqMktDepth( TickerId id, const Contract &contract, int numRows, const TagValueListSPtr& mktDepthOptions = TagValueListSPtr()) = 0; 90 | virtual void reqHistoricalData( TickerId id, const Contract &contract, const IBString &endDateTime, const IBString &durationStr, const IBString &barSizeSetting, const IBString &whatToShow, int useRTH, int formatDate, const TagValueListSPtr& chartOptions = TagValueListSPtr()) = 0; 91 | virtual void reqRealTimeBars( TickerId id, const Contract &contract, int barSize, const IBString &whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions = TagValueListSPtr()) = 0; 92 | virtual void reqScannerSubscription( int tickerId, const ScannerSubscription &subscription, const TagValueListSPtr& scannerSubscriptionOptions = TagValueListSPtr()) = 0; 93 | 94 | //---- Extra Methods ----------------------------------------------------- 95 | 96 | // Access to the EWrapper 97 | virtual EWrapper* GetEWrapper( void ) = 0; 98 | 99 | // Besides a Server version, there is a client version as well 100 | virtual int clientVersion( void ) = 0; 101 | 102 | // Returns true when the Api is connected to TWS. 103 | virtual bool IsConnected( void ) = 0; 104 | }; 105 | 106 | //---------------------------------------------------------------------------- 107 | // EWrapperL0 108 | // The posix implementation never calls winError. 109 | //---------------------------------------------------------------------------- 110 | #define EWRAPPERL0_DEFAULT(id, name) 111 | #if 1 // set to 0 to prevent this warning message in debug mode 112 | #ifdef _DEBUG 113 | #undef EWRAPPERL0_DEFAULT 114 | #define EWRAPPERL0_DEFAULT(id, name) printf( "#warning: empty default method EWrapperL0::%s(id=%ld) was called!\n", name, static_cast(id) ); 115 | #endif 116 | #endif 117 | 118 | class EWrapperL0: public EWrapper 119 | { 120 | public: 121 | // Default empty implementations for each method in the callback class 122 | virtual void tickPrice ( TickerId tickerId, TickType field, double price, int canAutoExecute ) { EWRAPPERL0_DEFAULT( tickerId, "tickPrice" ) } 123 | virtual void tickSize ( TickerId tickerId, TickType field, int size ) { EWRAPPERL0_DEFAULT( tickerId, "tickSize" ) } 124 | virtual void tickOptionComputation ( TickerId tickerId, TickType tickType, double impliedVol, double delta, double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) { EWRAPPERL0_DEFAULT( tickerId, "tickOptionComputation" ) } 125 | virtual void tickGeneric ( TickerId tickerId, TickType tickType, double value ) { EWRAPPERL0_DEFAULT( tickerId, "tickGeneric" ) } 126 | virtual void tickString ( TickerId tickerId, TickType tickType, const IBString& value ) { EWRAPPERL0_DEFAULT( tickerId, "tickString" ) } 127 | virtual void tickEFP ( TickerId tickerId, TickType tickType, double basisPoints, const IBString& formattedBasisPoints, double totalDividends, int holdDays, const IBString& futureExpiry, double dividendImpact, double dividendsToExpiry) { EWRAPPERL0_DEFAULT( tickerId, "tickEFP" ) } 128 | virtual void orderStatus ( OrderId orderId, const IBString& status, int filled, int remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, const IBString& whyHeld ) { EWRAPPERL0_DEFAULT( orderId, "orderStatus" ) } 129 | virtual void openOrder ( OrderId orderId, const Contract& contract, const Order& order, const OrderState& orderState ) { EWRAPPERL0_DEFAULT( orderId, "openOrder" ) } 130 | virtual void openOrderEnd () { EWRAPPERL0_DEFAULT( NO_VALID_ID, "openOrderEnd" ) } 131 | virtual void winError ( const IBString& str, int lastError ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "winError" ) } 132 | virtual void connectionClosed () { EWRAPPERL0_DEFAULT( NO_VALID_ID, "connectionClosed" ) } 133 | virtual void updateAccountValue ( const IBString& key, const IBString& val, const IBString& currency, const IBString& accountName ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "updateAccountValue" ) } 134 | virtual void updatePortfolio ( const Contract& contract, int position, double marketPrice, double marketValue, double averageCost, double unrealizedPNL, double realizedPNL, const IBString& accountName ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "updatePortfolio" ) } 135 | virtual void updateAccountTime ( const IBString& timeStamp ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "updateAccountTime" ) } 136 | virtual void accountDownloadEnd ( const IBString& accountName ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "accountDownloadEnd" ) } 137 | virtual void nextValidId ( OrderId orderId ) { EWRAPPERL0_DEFAULT( orderId, "nextValidId" ) } 138 | virtual void contractDetails ( int reqId, const ContractDetails& contractDetails ) { EWRAPPERL0_DEFAULT( reqId, "contractDetails" ) } 139 | virtual void bondContractDetails ( int reqId, const ContractDetails& contractDetails ) { EWRAPPERL0_DEFAULT( reqId, "bondContractDetails" ) } 140 | virtual void contractDetailsEnd ( int reqId ) { EWRAPPERL0_DEFAULT( reqId, "contractDetailsEnd" ) } 141 | virtual void execDetails ( int reqId, const Contract& contract, const Execution& execution ) { EWRAPPERL0_DEFAULT( reqId, "execDetails" ) } 142 | virtual void execDetailsEnd ( int reqId ) { EWRAPPERL0_DEFAULT( reqId, "execDetailsEnd" ) } 143 | virtual void error ( const int id, const int errorCode, const IBString errorString ) { EWRAPPERL0_DEFAULT( id, "error" ) } 144 | virtual void updateMktDepth ( TickerId id, int position, int operation, int side, double price, int size ) { EWRAPPERL0_DEFAULT( id, "updateMktDepth" ) } 145 | virtual void updateMktDepthL2 ( TickerId id, int position, IBString marketMaker, int operation, int side, double price, int size ) { EWRAPPERL0_DEFAULT( id, "updateMktDepthL2" ) } 146 | virtual void updateNewsBulletin ( int msgId, int msgType, const IBString& newsMessage, const IBString& originExch ) { EWRAPPERL0_DEFAULT( msgId, "updateNewsBulletin" ) } 147 | virtual void managedAccounts ( const IBString& accountsList ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "managedAccounts" ) } 148 | virtual void receiveFA ( faDataType pFaDataType, const IBString& cxml ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "receiveFA" ) } 149 | virtual void historicalData ( TickerId reqId, const IBString& date, double open, double high, double low, double close, int volume, int barCount, double WAP, int hasGaps ) { EWRAPPERL0_DEFAULT( reqId, "historicalData" ) } 150 | virtual void scannerParameters ( const IBString& xml ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "scannerParameters" ) } 151 | virtual void scannerData ( int reqId, int rank, const ContractDetails &contractDetails, const IBString &distance, const IBString &benchmark, const IBString &projection, const IBString &legsStr) { EWRAPPERL0_DEFAULT( reqId, "scannerData" ) } 152 | virtual void scannerDataEnd ( int reqId) { EWRAPPERL0_DEFAULT( reqId, "scannerDataEnd" ) } 153 | virtual void realtimeBar ( TickerId reqId, long time, double open, double high, double low, double close, long volume, double wap, int count) { EWRAPPERL0_DEFAULT( reqId, "realtimeBar" ) } 154 | virtual void currentTime ( long time ) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "currentTime" ) } 155 | virtual void fundamentalData ( TickerId reqId, const IBString& data ) { EWRAPPERL0_DEFAULT( reqId, "fundamentalData" ) } 156 | virtual void deltaNeutralValidation( int reqId, const UnderComp& underComp ) { EWRAPPERL0_DEFAULT( reqId, "deltaNeutralValidation") } 157 | virtual void tickSnapshotEnd ( int reqId ) { EWRAPPERL0_DEFAULT( reqId, "tickSnapshotEnd" ) } 158 | virtual void marketDataType ( TickerId reqId, int marketDataType) { EWRAPPERL0_DEFAULT( reqId, "marketDataType" ) } 159 | virtual void commissionReport ( const CommissionReport &commissionReport) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "commissionReport" ) } 160 | virtual void position ( const IBString& account, const Contract& contract, int position, double avgCost) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "position" ) } 161 | virtual void positionEnd () { EWRAPPERL0_DEFAULT( NO_VALID_ID, "positionEnd" ) } 162 | virtual void accountSummary ( int reqId, const IBString& account, const IBString& tag, const IBString& value, const IBString& curency) { EWRAPPERL0_DEFAULT( reqId, "accountSummary" ) } 163 | virtual void accountSummaryEnd ( int reqId) { EWRAPPERL0_DEFAULT( reqId, "accountSummaryEnd" ) } 164 | virtual void verifyMessageAPI ( const IBString& apiData) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "verifyMessageAPI" ) } 165 | virtual void verifyCompleted ( bool isSuccessful, const IBString& errorText) { EWRAPPERL0_DEFAULT( NO_VALID_ID, "verifyCompleted" ) } 166 | virtual void displayGroupList ( int reqId, const IBString& groups) { EWRAPPERL0_DEFAULT( reqId, "displayGroupList" ) } 167 | virtual void displayGroupUpdated ( int reqId, const IBString& contractInfo) { EWRAPPERL0_DEFAULT( reqId, "displayGroupUpdated" ) } 168 | //---- Extra Methods ----------------------------------------------------- 169 | 170 | // To keep symmetry with other requests that have an End method: 171 | // openOrderEnd, accountDownloadEnd, contractDetailsEnd, execDetailsEnd, scannerDataEnd, tickSnapshotEnd 172 | // virtual void historicalDataEnd ( TickerId reqId ) {} 173 | 174 | // To keep symmetry with connectionClosed(). 175 | // Is called just before the eConnect returns when connecting succeeded. 176 | virtual void connectionOpened( void ) {} 177 | 178 | static const char* Finished( void ) { return "finished"; } 179 | 180 | // The flow of historical data ends with a row holding a date field == 'finished' 181 | static bool IsEndOfHistoricalData( const IBString& Date ) 182 | { 183 | return 0 == strncmp( (const char*)Date.data(), Finished(), 8 ); 184 | } 185 | 186 | // The internal protection system reports via this method an unhandled exception 187 | // The Id is the tickerId, the orderId, or the reqId, or -1 when no id known 188 | virtual void OnCatch( const char* MethodName, const long Id ) 189 | { 190 | fprintf( stderr, "*** Catch in EWrapper::%s( Id=%ld, ...) \n", MethodName, Id ); 191 | } 192 | 193 | //---- To be Threaded or not to be Threaded------------------------------- 194 | // This allows the choice between a treaded or non threaded execution. 195 | // When non threaded, one must call checkMessages periodically. 196 | // The choice is made during creation only! Default it is set to true. 197 | // The users derived EWrapper must define a similar constructor in order to 198 | // set it to non-threaded, or just change the default to false. 199 | EWrapperL0( bool CalledFromThread = true ): m_CalledFromThread( CalledFromThread ) {} 200 | bool IsCalledFromThread( void ) { return m_CalledFromThread; } 201 | 202 | protected: 203 | bool m_CalledFromThread; 204 | }; 205 | 206 | #undef EWRAPPERL0_DEFAULT 207 | 208 | 209 | //---------------------------------------------------------------------------- 210 | #endif // _TwsApiL0_h 211 | -------------------------------------------------------------------------------- /TwsApiC++/Readme.txt: -------------------------------------------------------------------------------- 1 | ===================== 2 | = TwsApi C++ 9.71 = 3 | ===================== 4 | Released as is and free to use, but when used in a commercial environment, documentation should include a reference to the use of this software. 5 | 6 | By 7 | Jan Boonen 8 | Hofstade 9 | Belgium 10 | 11 | 12 | Purpose 13 | ------- 14 | Provide a portable and a platform/vendor independant C++ API based on the POSIX C++ API provided by IB, that is backward compatible with version 9.60 and before. 15 | 16 | Starting from version 9.62, IB supports a C++ API with POSIX socket implementation. This is a platform and vendor independant implementation. The only drawback of the POSIX API is its complexity and its non-compatibility with versions previous to 9.62. Indeed, the new API is the combination of the classes EClient/EWrapper, the class EPosixClientSocket AND the POSIX sockets API. Reading the example code in directory TestPosixSocketClient makes it clear: you will find a call to the select() method, the use of the low level macro's FD_ZERO, FD_SET, FD_CLR and FD_ISSET and tests on the file descriptor whether it is still valid or not, plus calls to onReceive(), onSend(), and onError(), introduced in new class EPosixClientSocket in the POSIX API. This all makes the use of the TWS C++ API far more complicated then it was before and not just plug & play with previous versions. 17 | 18 | This TwsApiC++ ensures all that is hidden and restores the backwards 'plug & play' compatibility, except for the xstring wich is replaced by newly introduced IBString by IB in version 9.62. 19 | 20 | 21 | 9.71: Differences with TwsApiC++ versions 9.67_4 22 | -------------------------------------------------- 23 | * IB changed its file structure drastically, but the way to use this lib remains unchanged. The zip file contains all is needed to build the c++ POSIX library. 24 | 25 | * ECLient: 26 | ** method added that returns the api version 27 | static char* apiVersion( void ) { return "9.71"; } 28 | ** Some existing methods got an extra parameter of type 'const TagValueListSPtr&' only for internal usage by IB. For these, an extra definition is added in EClientL0 where this parameter get a default value to ensure backwards compatibility. 29 | The methods involved are 30 | reqMktData 31 | reqMktDepth 32 | reqHistoricalData 33 | reqRealTimeBars 34 | reqScannerSubscription 35 | 36 | * EWRAPPERL0 37 | ** The default empty methods in EWrapperL0 print a message in debug mode to ensure their call is exposed. 38 | #define EWRAPPERL0_DEFAULT(id, name) 39 | #if 1 // set to 0 to prevent this warning message in debug mode 40 | #ifdef _DEBUG 41 | #undef EWRAPPERL0_DEFAULT 42 | #define EWRAPPERL0_DEFAULT(id, name) printf( "#warning: empty default method EWrapperL0::%s(id=%d) was called!\n", name, id ); 43 | #endif 44 | #endif 45 | 46 | 47 | 48 | 9.67_4: Differences with TwsApiC++ versions 9.67_3 49 | -------------------------------------------------- 50 | * the _linux/makefile(s) used the wrong -gdb switch, is now -ggdb (for the dgb debugger) 51 | 52 | 9.67_3: Differences with TwsApiC++ versions 9.67.2 53 | -------------------------------------------------- 54 | * the Test/_linux/makefile was a wrong copy (my mistake), it is now the orrect one 55 | 56 | * the Test/_cygwin/makefile and the Test/_linux/makefile both have now targets for each program and an 'all' target to makes each of them in one go 57 | 58 | * Test/_linux/compile script now call the make command by its full path '/usr/bin/make' 59 | 60 | * for linux, the -gdb compiler flag is added, so that gdb can be used to step through the program while debugging and show the source code line by line. (thanks Randall) 61 | 62 | 63 | 9.67: Differences with TwsApiC++ versions 9.65 64 | ---------------------------------------------- 65 | This release is an upstep to version 9.67, but also a merger of the specific linux version contributed by Randall L. Rathbun. It is available as TwsApiC++.9.65.v2.tar.gz in the same directory. 66 | 67 | His special note: 68 | SPECIAL NOTES: 69 | 70 | I built a linux section for Ubuntu V12.04 LTS (Precise Pangolin edition) which uses the gcc compiler v4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) and tested it with both the IB TWS and the IB Gateway Client. 71 | 72 | I also fixed an incomplete switch statement in EClientSocketBaseImpl.h and unused variable warnings for TwsApiL0.cpp in TwsApic++.9.65/TwsApiC++/Src and Main.cpp in TwsApiC++.9.65/TwsApiC++/Test/Src 73 | 74 | The make command with the -Wall option on the compile now passes both the library creation and the testing section. 75 | 76 | Author: Randall L. Rathbun 77 | Date: 2012-August-31 78 | 79 | Many thank Randall! 80 | 81 | Note: the adjustement on EClientSocketBaseImpl.h is not included, because the polici is not to touch the source of IB. 82 | 83 | 84 | * The new introduced methods added to EClient and EWrapper 85 | ** EClient: reqMarketDataType 86 | ** EWrapper: marketDataType and commissionReport 87 | 88 | * Linux adjustements, thanks to Randall 89 | ** see the _linux for the make files 90 | ** some includes stdio.h and string.h for linux 91 | ** printf format specifiers, %d -> %ld where needed (also in main.cpp) 92 | 93 | * TwsApiDefs: updated with new definitions/values, and 1 bugfixed 94 | ** SecType updated: 3 new values: WAR, FUND and EFP 95 | ** ClearIntent bugfixed: it must be a string instead of en numeric value 96 | *** Default (""), IB ("IB"), Away ("Away"), PTA ("PTA") // (post trade allocation). 97 | ** HedgeType added : Delta ("D"), Beta ("B"), FX ("F"), Pair ("P") 98 | ** HedgeParam added: BetaHedge ("beta=X"), PairHedge ("ratio=Y") 99 | ** SmartComboRouting added: (indeed, long names) 100 | *** Priority ("LeginPrio") 101 | *** DiscretionaryAmount ("MaxSegSize") 102 | *** MarketIfTouchedTimeoutAfterFirstFill ("ChangeToMktTime1") 103 | *** MarketIfTouchedTimeoutAfterLastFill ("ChangeToMktTime2") 104 | *** MarketIfTouchedStopLoss ("ChangeToMktOffset") 105 | *** MaximumLegInSize ("MaxSegSize") 106 | *** DiscretionaryPercentage ("DiscretionaryPct") 107 | ** MarketDataType added: Realtime and Frozen 108 | ** BarSizeSetting: values updated (10 secs, 10 mins and 4 hours added) 109 | 110 | * Test: main_mini.cpp is replaced by two other examples: 111 | ** Main-history.cpp: connects with TWS and executes a reqHistoricalData(). 112 | Default parameters, or with some on the command line i.e. 113 | MSFT 20130220 1 M 1 day TRADES 114 | It also demonstrates the use of the TwsApiDefs.h, just try wrong a parameter 115 | ** Main-8clients.cpp: demonstrates the low overhead of the library by running 8 connection simultaniously, first with checkMessages() called in the main thread for each connection, and secondly with a separate thread per connection, and just a Sleep(20seconds) to let the data come in automatically. Take a close look at the printed process id's at the beginning of the lines. 116 | 117 | 118 | 9.65: Differences with TwsApiC++ versions 9.64 119 | ---------------------------------------------- 120 | * Support for new method EClient::reqGlobalCancel() 121 | 122 | * TickTypes extended with new values 123 | ** TRADE_COUNT = 54 124 | ** TRADE_RATE = 55 125 | ** VOLUME_RATE = 56 126 | ** LAST_RTH_TRADE = 57 127 | 128 | * .\Test\Src\Main_mini.cpp added 129 | ** it is an updated version of Main_minimal.cpp included in previous versions 130 | 131 | Remark: in the Shared directory delivered by IB, two old files are included that are not needed anymore: EClientSocket.h and MySocket.h. They are not included in this delivery of TwsApiC++ 9.65. 132 | 133 | 9.64: Differences with TwsApiC++ versions 9.63 134 | ---------------------------------------------- 135 | * TwsApiDefs en Enumerations.h 136 | ** The way to define the enumerations is extracted from TwsApiDefs.h and defining maintaining is now easier 137 | ** But although the purpose is the same, the new enumerations are each enclosed in a class, instead of giving each name a different prefix. 138 | An example 139 | TT_Bid is now TickTypes::Bid 140 | OS_Submitted is now OrderStatus::Submitted 141 | ** Advantage/Disadvantage: 142 | ** + more readable WS_BID => WhatToShow::BID 143 | ** + conversion id/string and iteration possible even when the values are not consecutive, see i.e. TriggerMethod 144 | ** + enumerations are easier to maintain 145 | ** + you can use the system to add your own enumerations for other parts in the program 146 | ** - more text to write in the code 147 | ** - current code needs update 148 | 149 | But it is possible to keep using the old system: 150 | i) at the beginning of source TwsApiL0.cpp, change: 151 | #if 0 152 | //Old version 153 | 154 | into 155 | #if 1 156 | //Old version 157 | 158 | ii) and replace the new TwsApiDefs.h with the old one. 159 | 160 | 161 | Differences with TwsApiC++ versions 9.60 and before 162 | --------------------------------------------------- 163 | * xstring is replaced by IBString: 164 | IB had to replace its MFC specific CString with something based on the C++ standard. They've choosen for stl::string and extended it with a few extra methods and called it IBString. TwsApiC++ extends it with some methods to keep its compatibility with its xstring. So the impact of that change should be minimal. 165 | 166 | * TwsApiDefs.h 167 | is used the same way as before, but has been rewritten: 168 | ** including it multiple times in one project will not lead to linking problems. 169 | ** strings and enumeration values are both defined in one statement what reduces changes for errors and improves its maintenanability 170 | Note: TwsApiDefs.h is in fact a very convenient system to support conversions between enumerations and their string representations. So it could be used on its own in other projects as well. 171 | 172 | * class EWrapperL0Protected 173 | is no longer part of the TwsApiL0, as it is integrated in the library. Just rename EWrapperL0Protected back to EWrapperL0 in case you were using it. 174 | 175 | * OnCatch event in EWrapperL0 176 | When an exception is catched in the intergrated EWrapperL0Protected, it calls the OnCatch event in the EWrapperL0: 177 | virtual void OnCatch( const char* MethodName, const long Id ); 178 | 179 | * Threaded checkMessages() 180 | In previous versions prior to 9.63 of TwsApiC++, a seperate thread reads the incomming events from the socket and calls the appropriate EWrapper methods. Starting from version 9.63, TwsApiC++ offers the choice to not run this automatic thread. In that case, the user program must call checkMessages(). More info in the following chapter. 181 | 182 | * An extra error COULD_NOT_START_THREAD is defined in TwsApiL0.h: 183 | static const CodeMsgPair COULD_NOT_START_THREAD( 700, "Couldn't start thread to read incomming messages." ); 184 | This error is send from eConnect() in case the extra thread for automatic execution of checkMessages() failed to start. After sending this message, the connection is closed and eConnect returns with false. But because the connection was established first, connectionOpened() and connectionClosed() are called! 185 | 186 | * The zip files contains more then TwsApiC++ only 187 | It contains also a copy of all needed sources from the directories shared and PosixSocketClient, just for convenience. 188 | 189 | 190 | 191 | Use and Implementation notes 192 | ---------------------------- 193 | By default, the MS behaviour of class CAsyncSocket is simulated by executing checkMessages() in a seperate thread. The EWrapper members are called from this thread the moment the events arrives in the socket. In this automatic mode, calling checkMessages() in the application is unnecessary, but doing so does no harm and would make no difference. 194 | 195 | From version 9.63 on, the choice whether or not to start a thread is a property of EWrapperL0 set durings its creation: EWrapper EW( false ); When set to false, no thread is started and the user program must call checkMessages() periodically in order to handle the incoming events on the socket. See the main.cpp for an example. 196 | 197 | It is garanteed that connectionClosed() is called and the automatic thread, if any, stops running (if any) whenever the connection with TWS gets broken for any reason. There is no need to call eDisconnect() when receiving the connectionClosed() event without a call to eDisconnect(). Because sockets have no method to detect that the other end died without closing the socket, about every second, a '\0' byte is send to TWS as a check. 198 | 199 | For convenience, a class EWrapperL0 derived from EWrapper provides an empty body for each method and adds a few: 200 | * connectionOpened() is called when the connection with TWS is established successfully (symmetry with connectionClosed()); 201 | * IsEndOfHistoricalData() can be used to check for the end in the historicalData() stream. 202 | Class EClient is extended into EClientL0 and provides some extra methods, i.e. clientVersion() and IsConnected(). 203 | * OnCatch() is called whenever an exception is raised in the users EWrapper code. The tickerId/orderId/reqId and the method name in wich the exception was raised are available. 204 | 205 | The result is very lightweight and fast. The library in release mode is < 1MB and the small test program compiles into less then 300KB and needs less then 2MB of memory to run. 206 | 207 | One user, Mark Casson mentioned to have some issues when integrating an older version of this library with Qt and qmake. He solved it by just including TwsApiL0.cpp in its program instead of compiling it separately. So thanks for sharing this knowledge. 208 | 209 | 210 | Platforms/compilers tested so far 211 | --------------------------------- 212 | For the moment, it is tested only on a Windows platform, but both the WIN32 and the non-win32 (==unix assumed) path are compiled and tested successfully. 213 | 214 | The Visual C++ Express 2008 files sln and vcproj files are included and it should compile out of the box. Use TwsApiC++\Win32\TwsApi.sln for it. 215 | 216 | Also available are the makefiles for the Linux/unix make utility. 217 | 218 | NON-WIN32 == UNIX: 219 | I downloaded and installed the cygwin environment via the setup at http://www.cygwin.com/ and added some development support via the same setup. There are two makefiles in the project (see below in the file list). One compiles the library, the other compiles the test program. Compiling/linking and running the result went well. Only a debug version is implemented in the makefiles for now. 220 | For convenience, the ./compile shell in TwsApiC++\Test\_cygwin\. compiles both the library and the test program, while the ./run script compiles and runs the test. 221 | 222 | LINUX (by Randall L. Rathbun) 223 | A linux section has been added and tested under Ubuntu LTS 12.04. There is a makefile for compiling the library and also a makefile for compiling the test program. 224 | 225 | As in the Cygwin, compile compiles both the library and test program, while ./run compiles and runs the test. Be sure to set the listener to port 7496 on the IB Gateway Client in order for it to detect the socket requests. You can recompile this port to a different one (say 4001) if you wish by changing the source files. 226 | 227 | Installation 228 | ------------ 229 | For a quick start under Windows, expand the zipfile into the Jts directory. The Visual C++ Express 2008 files .sln and .vcproj files are included, and the projects should compile out of the box. Of course, the directories Jts\Shared, and Jts\PosixSocketClient must be available. 230 | 231 | When you consider to make a new makefile, keep following in mind: 232 | A) the include directories to build the library should be in following order: 233 | 1) TwsApiC++\Api 234 | 2) TwsApiC++\Src 235 | 3) Jts\Shared 236 | 4) Jts\PosixSocketClient\src 237 | B) only TwsApiC++\Src\TwsApiL0.cpp should be compiled to build the library. All other cpp files are incuded to get access to some #defines and private members. 238 | 239 | The compiler option to allow multithreading must be switched on. 240 | 241 | Including TwsApiC++\Api\TwsApiL0.h is sufficient to use the library. TwsApiDefs.h is optional but must be included after TwsApiL0.h. 242 | 243 | To build the cygwin version, the current directory must be on _cygwin when executing the make command. First build the api, then the test program, or execute the compile or run script in TwsApiC++\Test\_cygwin 244 | 245 | 246 | Overview of the zip file (TwsApiC++ only) 247 | ----------------------------------------- 248 | TwsApiC++\Readme.txt : this file 249 | 250 | TwsApiC++\Api : the directory to be included in the include path when using this library 251 | TwsApiC++\Api\Enumerations.h : Included when TwsApiDefs is used. 252 | TwsApiC++\Api\TwsApiDefs.h : An optional include file. See the comments for its purpose. Is used in the test program. 253 | TwsApiC++\Api\TwsApiL0.h : The only mandatory include file for TwsApi. It includes all other necessary include files. 254 | 255 | TwsApiC++\Src\afxwin.h : To #undef _MSC_VER 256 | TwsApiC++\Src\TwsApiL0.cpp : The source code of the library (~ 700 lines) 257 | 258 | TwsApiC++\_cygwin\makefile : makefile for the library 259 | TwsApiC++\_cygwin\debug : output directory for the build step 260 | 261 | TwsApiC++\_linux\makefile : makefile for the library 262 | TwsApiC++\_linux\debug : output directory for the build step 263 | 264 | TwsApiC++\_win32\TwsApi.sln : Visual C++ Express 2008 Solution file (= main project file) 265 | TwsApiC++\_win32\TwsApi.vcproj : Visual C++ Express 2008 project file for the TwsApi library 266 | 267 | TwsApiC++\Test\Src\Test.cpp : The source of the small test/example program 268 | TwsApiC++\Test\Src\Bars.cpp : Example of a reqMktData, no command line paramaters can be specified yet 269 | TwsApiC++\Test\Src\History.cpp : Example of reqHistoricalData, accepts command line parameters 270 | TwsApiC++\Test\Src\Clients.cpp : makes 8 connections and demontrates both ways to check for incomming data 271 | 272 | TwsApiC++\Test\_cygwin\makefile : makefile for the example programs. 273 | TwsApiC++\Test\_cygwin\debug : output directory for the build step 274 | TwsApiC++\Test\_cygwin\compile : shell script that compiles the library irst and then the test programm. 275 | TwsApiC++\Test\_cygwin\run : shell script that compiles the library first and then the test programm and runs the test program 276 | 277 | TwsApiC++\Test\_linux\makefile : makefile for the example programs. 278 | TwsApiC++\Test\_linux\debug : output directory for the build step 279 | TwsApiC++\Test\_linux\compile : shell script that compiles the library first and then the test programm. 280 | TwsApiC++\Test\_linux\run : shell script that compiles the library first and then the test programm and runs the test program 281 | 282 | TwsApiC++\Test\_win32\Test.vcproj:Visual C++ Express 2008 project file for Test 283 | -------------------------------------------------------------------------------- /TwsApiC++/Src/TwsApiL0.cpp: -------------------------------------------------------------------------------- 1 | /*===========================================================================*\ 2 | TwsApiL0.cpp 3 | \*===========================================================================*/ 4 | #include "TwsApiL0.h" 5 | 6 | #if 0 7 | //Old version 8 | #define TwsApiDefsImpl // Allocate the string values 9 | #include "TwsApiDefs.h" 10 | #else 11 | //New version 12 | #include "TwsApiDefs.h" 13 | #undef _TwsApiDefs_h 14 | #define ENUMImplementation 15 | #include "TwsApiDefs.h" 16 | #endif 17 | 18 | 19 | #ifndef WIN32 20 | #include // 21 | #endif 22 | // (4 march 2013) JBOO #define replaced by friend class EClientL0Impl 23 | // #define private public // to get access to send and receive 24 | #include "EPosixClientSocket.cpp" 25 | #include "EClientSocketBase.cpp" // CLIENT_VERSION 26 | #undef private 27 | 28 | #ifdef WIN32 29 | #ifndef CorrectAfxWinIncluded 30 | #error Not the correct afxwin.h included. 31 | #endif 32 | #endif 33 | 34 | 35 | #ifdef WIN32 36 | #include // for mutex 37 | #include // for Sleep 38 | #define CurrentThreadId GetCurrentThreadId 39 | #else 40 | #include // for mutex 41 | #define Sleep( m ) usleep( m*1000 ) 42 | #define CurrentThreadId pthread_self 43 | #endif 44 | 45 | 46 | #define _TRY_ try{ 47 | 48 | #ifdef _DEBUG 49 | #define _CATCH_ }catch(...){ fprintf( stderr, "*** CATCH: in file %s, at %d ***\n", __FILE__, __LINE__ ); } 50 | #define ENTERCRITICALSECTION( CSobject ) { bool b=true; try{ CSobject EnterCriticalSection(); } catch(...) { printf("***CS*** %s %d\n",__FILE__,__LINE__); b = false; } if ( b ) { 51 | #define LEAVECRITICALSECTION( CSobject ) CSobject LeaveCriticalSection(); } } 52 | 53 | #else 54 | #define _CATCH_ }catch(...){} 55 | #define ENTERCRITICALSECTION(CSobject) CSobject EnterCriticalSection(); 56 | #define LEAVECRITICALSECTION(CSobject) CSobject LeaveCriticalSection(); 57 | 58 | #endif 59 | 60 | 61 | //---------------------------------------------------------------------------- 62 | // CriticalSection 63 | // Less expensive than Mutex, but sufficient as interprocess isn't needed. 64 | //---------------------------------------------------------------------------- 65 | struct CriticalSection 66 | { 67 | #ifdef WIN32 68 | public: 69 | CRITICAL_SECTION m_CriticalSection; 70 | 71 | CriticalSection ( void ) { ::InitializeCriticalSection (&m_CriticalSection); } 72 | ~CriticalSection ( void ) { ::DeleteCriticalSection (&m_CriticalSection); } 73 | 74 | #ifdef _DEBUG 75 | // Put in a seperate method to allow breakpoint in debugger 76 | // While debugging, shouldn't it always have a breakpoint set 77 | // The throw(0) on purpose for the ENTERCRITICALSECTION() macro 78 | void DeadlockEncountered( void ) { throw(0); } 79 | void EnterCriticalSection ( void ) { try{ ::EnterCriticalSection(&m_CriticalSection); } catch(...) { DeadlockEncountered(); } } 80 | #else 81 | void EnterCriticalSection ( void ) { ::EnterCriticalSection(&m_CriticalSection); } 82 | #endif 83 | 84 | void LeaveCriticalSection ( void ) { ::LeaveCriticalSection(&m_CriticalSection); } 85 | 86 | bool TryEnterCriticalSection( void ) { return ::TryEnterCriticalSection(&m_CriticalSection) != 0; } 87 | #else 88 | pthread_mutex_t m_mutex; 89 | 90 | CriticalSection ( void ) :m_mutex (PTHREAD_MUTEX_INITIALIZER) {} 91 | 92 | ~CriticalSection ( void ) { ::pthread_mutex_destroy( &m_mutex ); } 93 | 94 | bool EnterCriticalSection ( void ) { return ::pthread_mutex_lock ( &m_mutex ) == 0; } 95 | void LeaveCriticalSection ( void ) { ::pthread_mutex_unlock( &m_mutex ); } 96 | 97 | bool TryEnterCriticalSection( void ) { return ::pthread_mutex_trylock( &m_mutex ) == 0; } 98 | #endif 99 | }; 100 | 101 | //---------------------------------------------------------------------------- 102 | // EWrapperL0Impl 103 | // * Protects TwsApi from unhandled exceptions in the users EWrapper 104 | // * Allows the EClientL0Impl to disables the calls just before eDisconnect() 105 | //---------------------------------------------------------------------------- 106 | #define EW_TRYCATCH( N, I, F ) \ 107 | try { if( m_EW && m_Enabled ) m_EW->F; } catch( ... ) { _TRY_ m_EW->OnCatch( #N, I ); _CATCH_ } 108 | 109 | class EWrapperL0Impl: public EWrapperL0 110 | { 111 | protected: 112 | EWrapperL0* m_EW; 113 | bool m_Enabled; // When false, calls are not passed on 114 | EClient* m_Client; // Access to the logger 115 | 116 | public: 117 | EWrapperL0Impl( EWrapperL0* EW ) 118 | : m_EW ( EW ) 119 | , m_Enabled ( true ) 120 | , m_Client ( 0 ) 121 | {} 122 | 123 | void EnableCalls ( void ) { m_Enabled = true; } 124 | void DisableCalls ( void ) { m_Enabled = false; } 125 | bool IsEnableCalls ( void ) { return m_Enabled; } 126 | 127 | void SetClient ( EClient* Client ) { m_Client = Client; } 128 | 129 | 130 | // Wrap each call in a try/catch to protect the API client (==EClientSocket) 131 | virtual void tickPrice ( TickerId tickerId, TickType field, double price, int canAutoExecute ) 132 | {EW_TRYCATCH(tickPrice , tickerId, tickPrice( tickerId, field, price, canAutoExecute ); ) } 133 | 134 | virtual void tickSize ( TickerId tickerId, TickType field, int size ) 135 | {EW_TRYCATCH(tickSize , tickerId, tickSize( tickerId, field, size ); ) } 136 | 137 | virtual void tickOptionComputation ( TickerId tickerId, TickType tickType, double impliedVol, double delta, double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice) 138 | {EW_TRYCATCH(tickOptionComputation , tickerId, tickOptionComputation ( tickerId, tickType, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice ); ) } 139 | 140 | 141 | virtual void tickGeneric ( TickerId tickerId, TickType tickType, double value ) 142 | {EW_TRYCATCH(tickGeneric , tickerId, tickGeneric( tickerId, tickType, value ); ) } 143 | 144 | virtual void tickString ( TickerId tickerId, TickType tickType, const IBString& value ) 145 | {EW_TRYCATCH(tickString , tickerId, tickString( tickerId, tickType, value ); ) } 146 | 147 | virtual void tickEFP ( TickerId tickerId, TickType tickType, double basisPoints, const IBString& formattedBasisPoints, double totalDividends, int holdDays, const IBString& futureExpiry, double dividendImpact, double dividendsToExpiry) 148 | {EW_TRYCATCH(tickEFP , tickerId, tickEFP( tickerId, tickType, basisPoints, formattedBasisPoints, totalDividends, holdDays, futureExpiry, dividendImpact, dividendsToExpiry); ) } 149 | 150 | virtual void orderStatus ( OrderId orderId, const IBString& status, int filled, int remaining, double avgFillPrice, int permId, int parentId, double lastFillPrice, int clientId, const IBString& whyHeld ) 151 | {EW_TRYCATCH(orderStatus , orderId, orderStatus( orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeld ); ) } 152 | 153 | virtual void openOrder ( OrderId orderId, const Contract& contract, const Order& order, const OrderState& orderState ) 154 | {EW_TRYCATCH(openOrder , orderId, openOrder( orderId, contract, order, orderState ); ) } 155 | 156 | virtual void openOrderEnd () 157 | {EW_TRYCATCH(openOrderEnd , NO_VALID_ID, openOrderEnd(); ) } 158 | 159 | virtual void winError ( const IBString& str, int lastError ) 160 | {EW_TRYCATCH(winError , NO_VALID_ID, winError( str, lastError ); ) } 161 | 162 | virtual void connectionClosed () 163 | {EW_TRYCATCH(connectionClosed , NO_VALID_ID, connectionClosed(); ) } 164 | 165 | virtual void updateAccountValue ( const IBString& key, const IBString& val, const IBString& currency, const IBString& accountName ) 166 | {EW_TRYCATCH(updateAccountValue , NO_VALID_ID, updateAccountValue( key, val, currency, accountName ); ) } 167 | 168 | virtual void updatePortfolio ( const Contract& contract, int position, double marketPrice, double marketValue, double averageCost, double unrealizedPNL, double realizedPNL, const IBString& accountName ) 169 | {EW_TRYCATCH(updatePortfolio , NO_VALID_ID, updatePortfolio( contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName ); ) } 170 | 171 | virtual void updateAccountTime ( const IBString& timeStamp ) 172 | {EW_TRYCATCH(updateAccountTime , NO_VALID_ID, updateAccountTime( timeStamp ); ) } 173 | 174 | virtual void accountDownloadEnd ( const IBString& accountName ) 175 | {EW_TRYCATCH(accountDownloadEnd , NO_VALID_ID, accountDownloadEnd( accountName ); ) } 176 | 177 | virtual void nextValidId ( OrderId orderId ) 178 | {EW_TRYCATCH(nextValidId , orderId, nextValidId( orderId ); ) } 179 | 180 | virtual void contractDetails ( int reqId, const ContractDetails& contractDetails ) 181 | {EW_TRYCATCH(contractDetails , reqId, contractDetails( reqId, contractDetails ); ) } 182 | 183 | virtual void bondContractDetails ( int reqId, const ContractDetails& contractDetails ) 184 | {EW_TRYCATCH(bondContractDetails , reqId, bondContractDetails( reqId, contractDetails ); ) } 185 | 186 | virtual void contractDetailsEnd ( int reqId ) 187 | {EW_TRYCATCH(contractDetailsEnd , reqId, contractDetailsEnd( reqId ); ) } 188 | 189 | virtual void execDetails ( int reqId, const Contract& contract, const Execution& execution ) 190 | {EW_TRYCATCH(execDetails , reqId, execDetails( reqId, contract, execution ); ) } 191 | 192 | virtual void execDetailsEnd ( int reqId ) 193 | {EW_TRYCATCH(execDetailsEnd , reqId, execDetailsEnd( reqId ); ) } 194 | 195 | virtual void error ( const int id, const int errorCode, const IBString errorString ) 196 | {EW_TRYCATCH(error , id, error( id, errorCode, errorString ); ) } 197 | 198 | virtual void updateMktDepth ( TickerId id, int position, int operation, int side, double price, int size ) 199 | {EW_TRYCATCH(updateMktDepth , id, updateMktDepth( id, position, operation, side, price, size ); ) } 200 | 201 | virtual void updateMktDepthL2 ( TickerId id, int position, IBString marketMaker, int operation, int side, double price, int size ) 202 | {EW_TRYCATCH(updateMktDepthL2 , id, updateMktDepthL2( id, position, marketMaker, operation, side, price, size ); ) } 203 | 204 | virtual void updateNewsBulletin ( int msgId, int msgType, const IBString& newsMessage, const IBString& originExch ) 205 | {EW_TRYCATCH(updateNewsBulletin , msgId, updateNewsBulletin( msgId, msgType, newsMessage, originExch ); ) } 206 | 207 | virtual void managedAccounts ( const IBString& accountsList ) 208 | {EW_TRYCATCH(managedAccounts , NO_VALID_ID, managedAccounts( accountsList ); ) } 209 | 210 | virtual void receiveFA ( faDataType pFaDataType, const IBString& cxml ) 211 | {EW_TRYCATCH(receiveFA , NO_VALID_ID, receiveFA( pFaDataType, cxml ); ) } 212 | 213 | virtual void historicalData ( TickerId reqId, const IBString& date, double open, double high, double low, double close, int volume, int barCount, double WAP, int hasGaps ) 214 | {EW_TRYCATCH(historicalData , reqId, historicalData( reqId, date, open, high, low, close, volume, barCount, WAP, hasGaps ); ) } 215 | 216 | virtual void scannerParameters ( const IBString& xml ) 217 | {EW_TRYCATCH(scannerParameters , NO_VALID_ID, scannerParameters( xml ); ) } 218 | 219 | virtual void scannerData ( int reqId, int rank, const ContractDetails &contractDetails, const IBString &distance, const IBString &benchmark, const IBString &projection, const IBString &legsStr) 220 | {EW_TRYCATCH(scannerData , reqId, scannerData( reqId, rank, contractDetails, distance, benchmark, projection, legsStr); ) } 221 | 222 | virtual void scannerDataEnd ( int reqId) 223 | {EW_TRYCATCH(scannerDataEnd , reqId, scannerDataEnd( reqId); ) } 224 | 225 | virtual void realtimeBar ( TickerId reqId, long time, double open, double high, double low, double close, long volume, double wap, int count) 226 | {EW_TRYCATCH(realtimeBar , reqId, realtimeBar( reqId, time, open, high, low, close, volume, wap, count); ) } 227 | 228 | virtual void currentTime ( long time ) 229 | {EW_TRYCATCH(currentTime , NO_VALID_ID, currentTime( time ); ) } 230 | 231 | virtual void fundamentalData ( TickerId reqId, const IBString& data ) 232 | {EW_TRYCATCH(fundamentalData , reqId, fundamentalData( reqId, data ); ) } 233 | 234 | virtual void deltaNeutralValidation( int reqId, const UnderComp& underComp ) 235 | {EW_TRYCATCH(deltaNeutralValidation, reqId, deltaNeutralValidation( reqId, underComp ); ) } 236 | 237 | virtual void tickSnapshotEnd ( int reqId ) 238 | {EW_TRYCATCH(tickSnapshotEnd , reqId, tickSnapshotEnd( reqId ); ) } 239 | 240 | virtual void marketDataType ( TickerId reqId, int marketDataType) 241 | {EW_TRYCATCH(marketDataType , reqId, marketDataType( reqId, marketDataType ); ) } 242 | 243 | virtual void commissionReport ( const CommissionReport &commissionReport) 244 | {EW_TRYCATCH(commissionReport , NO_VALID_ID, commissionReport( commissionReport ); ) } 245 | 246 | virtual void position ( const IBString& account, const Contract& contract, int position, double avgCost) 247 | { EW_TRYCATCH(position , NO_VALID_ID, position( account, contract, position, avgCost); ) } 248 | 249 | virtual void positionEnd () 250 | { EW_TRYCATCH(positionEnd , NO_VALID_ID, positionEnd(); ) } 251 | 252 | virtual void accountSummary ( int reqId, const IBString& account, const IBString& tag, const IBString& value, const IBString& curency) 253 | { EW_TRYCATCH(accountSummary , reqId, accountSummary( reqId, account, tag, value, curency); ) } 254 | 255 | virtual void accountSummaryEnd ( int reqId) 256 | { EW_TRYCATCH(accountSummaryEnd , reqId, accountSummaryEnd( reqId); ) } 257 | 258 | virtual void verifyMessageAPI ( const IBString& apiData) 259 | { EW_TRYCATCH(verifyMessageAPI , NO_VALID_ID, verifyMessageAPI( apiData); ) } 260 | 261 | virtual void verifyCompleted ( bool isSuccessful, const IBString& errorText) 262 | { EW_TRYCATCH(verifyCompleted , NO_VALID_ID, verifyCompleted( isSuccessful, errorText); ) } 263 | 264 | virtual void displayGroupList ( int reqId, const IBString& groups) 265 | { EW_TRYCATCH(displayGroupList , reqId, displayGroupList( reqId, groups); ) } 266 | 267 | virtual void displayGroupUpdated ( int reqId, const IBString& contractInfo) 268 | { EW_TRYCATCH(displayGroupUpdated , reqId, displayGroupUpdated( reqId, contractInfo); ) } 269 | 270 | //---- Extra Methods ----------------------------------------------------- 271 | virtual void connectionOpened( void ) 272 | {EW_TRYCATCH(connectionOpened , NO_VALID_ID, connectionOpened( ); ) } 273 | 274 | }; 275 | #undef EW_TRYCATCH 276 | 277 | 278 | //---------------------------------------------------------------------------- 279 | // ThreadMain 280 | //---------------------------------------------------------------------------- 281 | void ThreadMain( void* pEClient ); // implementation at end of file 282 | 283 | 284 | //---------------------------------------------------------------------------- 285 | // EClientL0Impl 286 | // 287 | //---------------------------------------------------------------------------- 288 | struct EClientL0Impl: public EPosixClientSocket 289 | { 290 | EWrapperL0Impl m_EWrapperL0Impl; // the wrapper called by EPosixClientSocket 291 | EWrapperL0* m_EWrapperL0; // Just to have pointer to user specified EWrapper 292 | int m_ClientId; 293 | bool m_ThreadIsRunning; 294 | time_t m_NextHeartbeat; 295 | 296 | EClientL0Impl( EWrapperL0* EW ) 297 | : EPosixClientSocket ( &m_EWrapperL0Impl ) 298 | , m_EWrapperL0Impl ( EW ) 299 | , m_EWrapperL0 ( EW ) 300 | 301 | , m_ClientId ( NO_VALID_ID ) 302 | 303 | , m_ThreadIsRunning ( false ) 304 | , m_NextHeartbeat ( 0 ) 305 | { 306 | m_EWrapperL0Impl.SetClient( this ); 307 | } 308 | 309 | ~EClientL0Impl( void ) 310 | { 311 | eDisconnect(); 312 | } 313 | 314 | bool eConnect( const char *host, unsigned int port, int clientId=0, bool extraAuth=0 ) 315 | { 316 | m_EWrapperL0Impl.EnableCalls(); // just to ensure it is enabled 317 | 318 | // If connected, just let it follow the flow in EClientSocket 319 | if( isConnected() ) 320 | return EPosixClientSocket::eConnect(host, port, clientId, extraAuth); 321 | 322 | if( !EPosixClientSocket::eConnect(host, port, clientId, extraAuth) ) 323 | { 324 | EPosixClientSocket::eDisconnect(); // otherwise, the m_fd > 0 325 | return false; 326 | } 327 | 328 | m_EWrapperL0Impl.connectionOpened(); 329 | 330 | if( m_EWrapperL0->IsCalledFromThread() ) 331 | { // Then start the reading thread 332 | #ifdef WIN32 333 | int err = _beginthread( ThreadMain, 2*8192, this ); 334 | if( err < 0 ) 335 | // errno == EAGAIN // there are too many threads 336 | // errno == EINVAL // the argument is invalid or the stack size is incorrect 337 | // errno == EACCES // insufficient resources (such as memory) 338 | { 339 | m_EWrapperL0->error( errno, COULD_NOT_START_THREAD.code(), COULD_NOT_START_THREAD.msg()); 340 | #else 341 | pthread_t thr; 342 | int err = pthread_create(&thr, 0, (void *(*)(void *)) ThreadMain, this); 343 | if( err != 0 ) 344 | // err == EAGAIN // Insufficient resources to create another thread 345 | // err == EINVAL // Invalid settings in attr. 346 | // err == EPERM // No permission to set the scheduling policy 347 | { // if err 348 | m_EWrapperL0->error( err, COULD_NOT_START_THREAD.code(), COULD_NOT_START_THREAD.msg()); 349 | #endif 350 | eDisconnect(); 351 | return false; 352 | } 353 | } 354 | 355 | return true; 356 | } 357 | 358 | 359 | 360 | void eDisconnect() 361 | { 362 | if( !isConnected() && !m_ThreadIsRunning ) 363 | return; 364 | 365 | _TRY_ 366 | // if threaded, try to stop the thread gracefully ... 367 | // * EWrapper calls are disabled to spend no time in users code while 368 | // checkMessages parses the current buffer 369 | // * The receive method prevents new data will be presented to 370 | // checkMessages() 371 | // * Execution is passed to another thread for max 100 times, hoping 372 | // in the meantime the current running checkMessages() returns and 373 | // checkMessagesLoop() can end and so can the thread. 374 | if( m_ThreadIsRunning ) 375 | { 376 | m_EWrapperL0Impl.DisableCalls(); // will stop the thread loop 377 | _TRY_ 378 | for( int i = 100; i > 0 && m_ThreadIsRunning; i-- ) { Sleep(1); } 379 | 380 | if( m_ThreadIsRunning ) 381 | { 382 | /* troubles ahead!? */ 383 | } 384 | _CATCH_ 385 | m_EWrapperL0Impl.EnableCalls(); 386 | } 387 | 388 | EPosixClientSocket::eDisconnect(); 389 | _CATCH_ 390 | 391 | m_EWrapperL0Impl.connectionClosed(); 392 | } 393 | 394 | 395 | virtual int receive(char* buf, size_t sz) 396 | { 397 | // no point to process new data when system is disconnecting 398 | if( !m_EWrapperL0Impl.IsEnableCalls() ) 399 | return 0; 400 | 401 | // return EPosixClientSocket::receive( buf, sz ); 402 | if( sz <= 0) 403 | return 0; 404 | 405 | int nResult = ::recv( fd(), buf, sz, 0); 406 | 407 | // Seems the only way to discover TWS was shut down? See comment on ErrorSet. 408 | if( nResult < 0 ) 409 | eDisconnect(); 410 | 411 | return nResult; 412 | } 413 | 414 | 415 | virtual int send(const char* buf, size_t sz) 416 | { 417 | return EPosixClientSocket::send( buf, sz ); 418 | } 419 | 420 | 421 | virtual bool isSocketOK() const { return EPosixClientSocket::isSocketOK(); } 422 | 423 | 424 | //---- Extra Methods ----------------------------------------------------- 425 | virtual EWrapper* GetEWrapper () { return m_EWrapperL0; } 426 | virtual int clientVersion () { return CLIENT_VERSION; } 427 | virtual bool IsConnected () { return isConnected(); } 428 | 429 | 430 | 431 | // Block the checkMessages() call from the EClient API when threaded 432 | // Note: checkMessages() is called in EPosixClientSocket::eConnect 433 | // before isConnected() == true! 434 | bool checkMessages() 435 | { 436 | if( IsConnected() && time(0) > m_NextHeartbeat ) 437 | { 438 | bufferedSend("\0",1); // Sending a 0 byte helps the socket detect its closing by TWS 439 | m_NextHeartbeat = time(0)+1; // Wait +/- 1 second for next heartbeat 440 | } 441 | 442 | if( !isSocketOK() ) 443 | return false; 444 | 445 | if( m_EWrapperL0->IsCalledFromThread() && isConnected() ) 446 | return false; 447 | 448 | return checkMessagesOnce(1); 449 | } 450 | 451 | bool checkMessagesOnce( long waitfor = 0 ) 452 | { 453 | _TRY_ 454 | // fprintf( stderr, "ThreadId = %d \r", CurrentThreadId() ); 455 | 456 | int SH = fd(); // Socket Handle 457 | 458 | fd_set ReadSet ; FD_ZERO( &ReadSet ); FD_SET ( SH, &ReadSet ); 459 | fd_set WriteSet; FD_ZERO( &WriteSet ); if( !isOutBufferEmpty() ) FD_SET ( SH, &WriteSet ); 460 | fd_set ErrorSet; FD_ZERO( &ErrorSet ); FD_SET ( SH, &ErrorSet ); 461 | 462 | struct timeval timeout = {0,waitfor}; // wait for some milli/micro seconds 463 | int s = select( SH+1, &ReadSet, &WriteSet, &ErrorSet, &timeout ); 464 | s = s; // turn of -Wall warning 465 | 466 | 467 | // The ErrorSet doesn't seem to do a lot on windows? 468 | // Even if TWS is shut down, ErrorSet is cleared as nothing is wrong? 469 | if( FD_ISSET(SH, &ErrorSet) ) // error on socket 470 | return handleSocketError(); 471 | 472 | if( FD_ISSET(SH, &WriteSet) && isSocketOK() ) // socket is ready for writing 473 | onSend(); 474 | 475 | if( FD_ISSET(SH, &ReadSet ) && isSocketOK() ) // socket is ready for reading 476 | return EPosixClientSocket::checkMessages(); 477 | 478 | _CATCH_ // EPosixClientSocket::checkMessages() can throw an exception! 479 | 480 | // Nothing done, but nothing wrong either 481 | return true; 482 | } 483 | 484 | void checkMessagesLoop ( void ) 485 | { 486 | m_ThreadIsRunning = true; 487 | 488 | _TRY_ 489 | while( isSocketOK() && isConnected() && m_EWrapperL0Impl.IsEnableCalls() ) 490 | { 491 | checkMessagesOnce(1); // the minimal time possible to wait is enough 492 | } // to prevent this loop using 100% of the cpu 493 | _CATCH_ 494 | 495 | m_ThreadIsRunning = false; 496 | } 497 | 498 | }; // EClientL0Impl 499 | 500 | 501 | //---------------------------------------------------------------------------- 502 | // ThreadMain 503 | //---------------------------------------------------------------------------- 504 | void ThreadMain( void* pEClient ) 505 | { 506 | _TRY_ ((EClientL0Impl*)pEClient)->checkMessagesLoop(); _CATCH_ 507 | } 508 | 509 | 510 | 511 | //---------------------------------------------------------------------------- 512 | // Interface to EClientL0 513 | // Implements the interface as a call through to EClientL0Impl 514 | // The critical section is needed because the EWrapper running in another 515 | // thread can call EClient too, and the EClientSocketBase::bufferedSend() is 516 | // not thread safe as it sets EClientSocketBase members. 517 | //---------------------------------------------------------------------------- 518 | #define ENTER_CLIENT( x, i ) ENTERCRITICALSECTION(this->) 519 | #define LEAVE_CLIENT( x ) LEAVECRITICALSECTION(this->) 520 | 521 | 522 | struct EClientL0Interface: public EClientL0, CriticalSection 523 | { 524 | EClientL0Impl EC; 525 | 526 | EClientL0Interface( EWrapperL0* EW ) :EC( EW ) {} 527 | 528 | 529 | bool eConnect ( const char *host, unsigned int port, int clientId=0, bool extraAuth=0) 530 | { bool r; 531 | ENTER_CLIENT( eConnect , NO_VALID_ID ) 532 | r = EC.eConnect ( host, port, clientId); 533 | LEAVE_CLIENT( eConnect ) 534 | return r ; } 535 | 536 | void eDisconnect () 537 | { ENTER_CLIENT( eDisconnect , NO_VALID_ID ) 538 | EC.eDisconnect (); 539 | LEAVE_CLIENT( eDisconnect ) } 540 | 541 | int serverVersion () 542 | { int r; 543 | ENTER_CLIENT( serverVersion , NO_VALID_ID ) 544 | r = EC.serverVersion (); 545 | LEAVE_CLIENT( serverVersion ) 546 | return r; } 547 | 548 | IBString TwsConnectionTime () 549 | { IBString s; 550 | ENTER_CLIENT( TwsConnectionTime , NO_VALID_ID ) 551 | s = EC.TwsConnectionTime (); 552 | LEAVE_CLIENT( TwsConnectionTime ) 553 | return s; } 554 | 555 | void reqMktData ( TickerId id, const Contract &contract, const IBString& genericTicks, bool snapshot, const TagValueListSPtr& mktDataOptions) 556 | { ENTER_CLIENT( reqMktData , id ) 557 | EC.reqMktData ( id, contract, genericTicks, snapshot, mktDataOptions); 558 | LEAVE_CLIENT( reqMktData ) } 559 | 560 | void cancelMktData ( TickerId id) 561 | { ENTER_CLIENT( cancelMktData , id ) 562 | EC.cancelMktData ( id); 563 | LEAVE_CLIENT( cancelMktData ) } 564 | 565 | void placeOrder ( OrderId id, const Contract &contract, const Order &order) 566 | { ENTER_CLIENT( placeOrder , id ) 567 | EC.placeOrder ( id, contract, order); 568 | LEAVE_CLIENT( placeOrder ) } 569 | 570 | void cancelOrder ( OrderId id) 571 | { ENTER_CLIENT( cancelOrder , id ) 572 | EC.cancelOrder ( id); 573 | LEAVE_CLIENT( cancelOrder ) } 574 | 575 | void reqOpenOrders () 576 | { ENTER_CLIENT( reqOpenOrders , NO_VALID_ID ) 577 | EC.reqOpenOrders (); 578 | LEAVE_CLIENT( reqOpenOrders ) } 579 | 580 | void reqAccountUpdates (bool subscribe, const IBString& acctCode) 581 | { ENTER_CLIENT( reqAccountUpdates , NO_VALID_ID ) 582 | EC.reqAccountUpdates (subscribe, acctCode); 583 | LEAVE_CLIENT( reqAccountUpdates ) } 584 | 585 | void reqExecutions (int reqId, const ExecutionFilter& filter) 586 | { ENTER_CLIENT( reqExecutions , reqId ) 587 | EC.reqExecutions ( reqId, filter); 588 | LEAVE_CLIENT( reqExecutions ) } 589 | 590 | void reqIds ( int numIds) 591 | { ENTER_CLIENT( reqIds , NO_VALID_ID ) 592 | EC.reqIds ( numIds); 593 | LEAVE_CLIENT( reqIds ) } 594 | 595 | bool checkMessages () 596 | { bool r; 597 | ENTERCRITICALSECTION(this->); // without logging 598 | r = EC.checkMessages (); 599 | LEAVECRITICALSECTION(this->); // without logging 600 | return r; } 601 | 602 | void reqContractDetails ( int reqId, const Contract &contract) 603 | { ENTER_CLIENT( reqContractDetails , reqId ) 604 | EC.reqContractDetails ( reqId, contract); 605 | LEAVE_CLIENT( reqContractDetails ) } 606 | 607 | void reqMktDepth ( TickerId id, const Contract &contract, int numRows, const TagValueListSPtr& mktDepthOptions) 608 | { ENTER_CLIENT( reqMktDepth , id ) 609 | EC.reqMktDepth ( id, contract, numRows, mktDepthOptions); 610 | LEAVE_CLIENT( reqMktDepth ) } 611 | 612 | void cancelMktDepth ( TickerId id) 613 | { ENTER_CLIENT( cancelMktDepth , id ) 614 | EC.cancelMktDepth ( id); 615 | LEAVE_CLIENT( cancelMktDepth ) } 616 | 617 | void reqNewsBulletins ( bool allMsgs) 618 | { ENTER_CLIENT( reqNewsBulletins , NO_VALID_ID ) 619 | EC.reqNewsBulletins ( allMsgs); 620 | LEAVE_CLIENT( reqNewsBulletins ) } 621 | 622 | void cancelNewsBulletins () 623 | { ENTER_CLIENT( cancelNewsBulletins , NO_VALID_ID ) 624 | EC.cancelNewsBulletins (); 625 | LEAVE_CLIENT( cancelNewsBulletins ) } 626 | 627 | void setServerLogLevel (int level) 628 | { ENTER_CLIENT( setServerLogLevel , NO_VALID_ID ) 629 | EC.setServerLogLevel (level); 630 | LEAVE_CLIENT( setServerLogLevel ) } 631 | 632 | void reqAutoOpenOrders (bool bAutoBind) 633 | { ENTER_CLIENT( reqAutoOpenOrders , NO_VALID_ID ) 634 | EC.reqAutoOpenOrders (bAutoBind); 635 | LEAVE_CLIENT( reqAutoOpenOrders ) } 636 | 637 | void reqAllOpenOrders () 638 | { ENTER_CLIENT( reqAllOpenOrders , NO_VALID_ID ) 639 | EC.reqAllOpenOrders (); 640 | LEAVE_CLIENT( reqAllOpenOrders ) } 641 | 642 | void reqManagedAccts () 643 | { ENTER_CLIENT( reqManagedAccts , NO_VALID_ID ) 644 | EC.reqManagedAccts (); 645 | LEAVE_CLIENT( reqManagedAccts ) } 646 | 647 | void requestFA (faDataType pFaDataType) 648 | { ENTER_CLIENT( requestFA , NO_VALID_ID ) 649 | EC.requestFA (pFaDataType); 650 | LEAVE_CLIENT( requestFA ) } 651 | 652 | void replaceFA (faDataType pFaDataType, const IBString& cxml) 653 | { ENTER_CLIENT( replaceFA , NO_VALID_ID ) 654 | EC.replaceFA (pFaDataType, cxml); 655 | LEAVE_CLIENT( replaceFA ) } 656 | 657 | void reqHistoricalData ( TickerId id, const Contract &contract, const IBString &endDateTime, const IBString &durationStr, const IBString &barSizeSetting, const IBString &whatToShow, int useRTH, int formatDate, const TagValueListSPtr& chartOptions) 658 | { ENTER_CLIENT( reqHistoricalData , id ) 659 | EC.reqHistoricalData ( id, contract, endDateTime, durationStr, barSizeSetting, whatToShow, useRTH, formatDate, chartOptions); 660 | LEAVE_CLIENT( reqHistoricalData ) } 661 | 662 | void exerciseOptions ( TickerId id, const Contract &contract, int exerciseAction, int exerciseQuantity, const IBString &account, int override) 663 | { ENTER_CLIENT( exerciseOptions , id ) 664 | EC.exerciseOptions ( id, contract, exerciseAction, exerciseQuantity, account, override); 665 | LEAVE_CLIENT( exerciseOptions ) } 666 | 667 | void cancelHistoricalData ( TickerId tickerId ) 668 | { ENTER_CLIENT( cancelHistoricalData , tickerId ) 669 | EC.cancelHistoricalData ( tickerId ); 670 | LEAVE_CLIENT( cancelHistoricalData ) } 671 | 672 | void reqRealTimeBars ( TickerId id, const Contract &contract, int barSize, const IBString &whatToShow, bool useRTH, const TagValueListSPtr& realTimeBarsOptions) 673 | { ENTER_CLIENT( reqRealTimeBars , id ) 674 | EC.reqRealTimeBars ( id, contract, barSize, whatToShow, useRTH, realTimeBarsOptions); 675 | LEAVE_CLIENT( reqRealTimeBars ) } 676 | 677 | void cancelRealTimeBars ( TickerId tickerId) 678 | { ENTER_CLIENT( cancelRealTimeBars , tickerId ) 679 | EC.cancelRealTimeBars ( tickerId); 680 | LEAVE_CLIENT( cancelRealTimeBars ) } 681 | 682 | void cancelScannerSubscription ( int tickerId) 683 | { ENTER_CLIENT( cancelScannerSubscription , tickerId ) 684 | EC.cancelScannerSubscription ( tickerId); 685 | LEAVE_CLIENT( cancelScannerSubscription ) } 686 | 687 | void reqScannerParameters () 688 | { ENTER_CLIENT( reqScannerParameters , NO_VALID_ID ) 689 | EC.reqScannerParameters (); 690 | LEAVE_CLIENT( reqScannerParameters ) } 691 | 692 | void reqScannerSubscription ( int tickerId, const ScannerSubscription &subscription, const TagValueListSPtr& scannerSubscriptionOptions) 693 | { ENTER_CLIENT( reqScannerSubscription , tickerId ) 694 | EC.reqScannerSubscription ( tickerId, subscription, scannerSubscriptionOptions); 695 | LEAVE_CLIENT( reqScannerSubscription ) } 696 | 697 | void reqCurrentTime () 698 | { ENTER_CLIENT( reqCurrentTime , NO_VALID_ID ) 699 | EC.reqCurrentTime (); 700 | LEAVE_CLIENT( reqCurrentTime ) } 701 | 702 | void reqFundamentalData ( TickerId reqId, const Contract& contract, const IBString& reportType) 703 | { ENTER_CLIENT( reqFundamentalData , reqId ) 704 | EC.reqFundamentalData ( reqId, contract, reportType); 705 | LEAVE_CLIENT( reqFundamentalData ) } 706 | 707 | void cancelFundamentalData ( TickerId reqId) 708 | { ENTER_CLIENT( cancelFundamentalData , reqId ) 709 | EC.cancelFundamentalData ( reqId); 710 | LEAVE_CLIENT( cancelFundamentalData ) } 711 | 712 | virtual void calculateImpliedVolatility ( TickerId reqId, const Contract &contract, double optionPrice, double underPrice) 713 | { ENTER_CLIENT( calculateImpliedVolatility , reqId ) 714 | EC.calculateImpliedVolatility ( reqId, contract, optionPrice, underPrice); 715 | LEAVE_CLIENT( calculateImpliedVolatility ) } 716 | 717 | virtual void calculateOptionPrice ( TickerId reqId, const Contract &contract, double volatility, double underPrice) 718 | { ENTER_CLIENT( calculateOptionPrice , reqId ) 719 | EC.calculateOptionPrice ( reqId, contract, volatility, underPrice); 720 | LEAVE_CLIENT( calculateOptionPrice ) } 721 | 722 | virtual void cancelCalculateImpliedVolatility( TickerId reqId) 723 | { ENTER_CLIENT( cancelCalculateImpliedVolatility, reqId ) 724 | EC.cancelCalculateImpliedVolatility( reqId); 725 | LEAVE_CLIENT( cancelCalculateImpliedVolatility) } 726 | 727 | virtual void cancelCalculateOptionPrice ( TickerId reqId) 728 | { ENTER_CLIENT( cancelCalculateOptionPrice , reqId ) 729 | EC.cancelCalculateOptionPrice ( reqId); 730 | LEAVE_CLIENT( cancelCalculateOptionPrice ) } 731 | 732 | void reqGlobalCancel () 733 | { ENTER_CLIENT( reqGlobalCancel , NO_VALID_ID ) 734 | EC.reqGlobalCancel (); 735 | LEAVE_CLIENT( reqGlobalCancel ) } 736 | 737 | void reqMarketDataType ( int marketDataType) 738 | { ENTER_CLIENT( reqMarketDataType , NO_VALID_ID ) 739 | EC.reqMarketDataType ( marketDataType); 740 | LEAVE_CLIENT( reqMarketDataType ) } 741 | 742 | void reqPositions () 743 | { ENTER_CLIENT( reqPositions , NO_VALID_ID ) 744 | EC.reqPositions (); 745 | LEAVE_CLIENT( reqPositions ) } 746 | 747 | void cancelPositions () 748 | { ENTER_CLIENT( cancelPositions , NO_VALID_ID ) 749 | EC.cancelPositions (); 750 | LEAVE_CLIENT( cancelPositions ) } 751 | 752 | void reqAccountSummary ( int reqId, const IBString& groupName, const IBString& tags) 753 | { ENTER_CLIENT( reqAccountSummary , reqId ) 754 | EC.reqAccountSummary ( reqId, groupName, tags); 755 | LEAVE_CLIENT( reqAccountSummary ) } 756 | 757 | void cancelAccountSummary ( int reqId) 758 | { ENTER_CLIENT( cancelAccountSummary , reqId ) 759 | EC.cancelAccountSummary ( reqId); 760 | LEAVE_CLIENT( cancelAccountSummary ) } 761 | 762 | void verifyRequest ( const IBString& apiName, const IBString& apiVersion) 763 | { ENTER_CLIENT( verifyRequest , NO_VALID_ID ) 764 | EC.verifyRequest ( apiName, apiVersion); 765 | LEAVE_CLIENT( verifyRequest ) } 766 | 767 | void verifyMessage ( const IBString& apiData) 768 | { ENTER_CLIENT( verifyMessage , NO_VALID_ID ) 769 | EC.verifyMessage ( apiData); 770 | LEAVE_CLIENT( verifyMessage ) } 771 | 772 | void queryDisplayGroups ( int reqId) 773 | { ENTER_CLIENT( queryDisplayGroups , reqId ) 774 | EC.queryDisplayGroups ( reqId); 775 | LEAVE_CLIENT( queryDisplayGroups ) } 776 | 777 | void subscribeToGroupEvents ( int reqId, int groupId) 778 | { ENTER_CLIENT( subscribeToGroupEvents , reqId ) 779 | EC.subscribeToGroupEvents ( reqId, groupId); 780 | LEAVE_CLIENT( subscribeToGroupEvents ) } 781 | 782 | void updateDisplayGroup ( int reqId, const IBString& contractInfo) 783 | { ENTER_CLIENT( updateDisplayGroup , reqId ) 784 | EC.updateDisplayGroup ( reqId, contractInfo); 785 | LEAVE_CLIENT( updateDisplayGroup ) } 786 | 787 | void unsubscribeFromGroupEvents ( int reqId) 788 | { ENTER_CLIENT( unsubscribeFromGroupEvents , reqId ) 789 | EC.unsubscribeFromGroupEvents ( reqId); 790 | LEAVE_CLIENT( unsubscribeFromGroupEvents ) } 791 | 792 | //---- Extra Methods ----------------------------------------------------- 793 | virtual EWrapper* GetEWrapper ( void ) { return EC.GetEWrapper (); } 794 | virtual int clientVersion ( void ) { return EC.clientVersion (); } 795 | virtual bool IsConnected ( void ) { return EC.IsConnected (); } 796 | }; 797 | 798 | 799 | //---------------------------------------------------------------------------- 800 | // EClientL0::New() 801 | //---------------------------------------------------------------------------- 802 | EClientL0* EClientL0::New( EWrapperL0* EW ) 803 | { 804 | return (EClientL0*)new EClientL0Interface( EW ); 805 | } 806 | 807 | --------------------------------------------------------------------------------