-
Notifications
You must be signed in to change notification settings - Fork 59
Example: Retrieve History
/*========================================================================
* TwsApiC++ - Demonstration program
* Retrieving historical data from Interactive Brokers
* See the ///blocks for some explanation
*========================================================================
*/
///Easier: Just one include statement for all functionality
#include "TwsApiL0.h"
///Faster: Check spelling of parameter at compile time instead of runtime.
#include "TwsApiDefs.h"
using namespace TwsApi; // for TwsApiDefs.h
///Advantages of deriving from EWrapperL0
/// Faster: implement only the methods you need.
/// Safe: receive notification of methods called you didn't implement
/// Robust: exceptions thrown by your code are catched safely and notified to you
class YourEWrapper: public EWrapperL0 {
public:
bool m_Done, m_ErrorForRequest;
bool notDone( void ) { return !(m_Done || m_ErrorForRequest); }
///Easier: The EReader calls all methods automatically(optional)
YourEWrapper( bool runEReader = true ): EWrapperL0( runEReader ) {
m_Done = false;
m_ErrorForRequest = false;
}
///Methods winError & error print the errors reported by IB TWS
virtual void winError( const IBString& str, int lastError ) {
fprintf( stderr, "WinError: %d = %s\n", lastError, (const char*)str );
m_ErrorForRequest = true;
}
virtual void error( const int id, const int errorCode, const IBString errorString ) {
fprintf( stderr, "Error for id=%d: %d = %s\n"
, id, errorCode, (const char*)errorString );
m_ErrorForRequest = (id > 0); // id == -1 are 'system' messages, not for user requests
}
///Safer: uncatched exceptions are catched before they reach the IB library code.
/// The Id is tickerId, orderId, or reqId, or -1 when no id known
virtual void OnCatch( const char* MethodName, const long Id ) {
fprintf( stderr, "*** Catch in EWrapper::%s( Id=%ld, ...) \n", MethodName, Id );
}
///Faster: Implement only the method for the task.
/// => TwsApiC++ provides an empty implementation for each EWrapper method.
virtual void historicalData( TickerId reqId, const IBString& date
, double open, double high, double low, double close
,int volume, int barCount, double WAP, int hasGaps ) {
///Easier: EWrapperL0 provides an extra method to check all data was retrieved
if( IsEndOfHistoricalData(date) ) {
m_Done = true;
return;
}
fprintf( stdout, "%10s, %5.3f, %5.3f, %5.3f, %5.3f, %7d\n"
, (const char*)date, open, high, low, close, volume );
}
}
//========================================================================
// main entry
//========================================================================
int main(void) {
///Easier: just allocate your wrapper and instantiate the EClientL0 with it.
YourEWrapper YW( false ); // false: not using the EReader
EClientL0* EC = EClientL0::New( &YW );
///Easier: All structures defined by IB are immediately available.
///Faster: Use of TwsApiDefs.h codes check typos at compile time
Contract C;
C.symbol = "MSFT";
C.secType = *SecType::STK; // instead of "STK"
C.currency = "USD";
C.exchange = *Exchange::IB_SMART; // instead of "SMART"
C.primaryExchange = *Exchange::AMEX; // instead of "AMEX"
///Easier: Use of TwsApiDefs.h makes code self explanatory,
/// i.e. UseRTH::OnlyRegularTradingData instead of true or 1.
if( EC->eConnect( "", 7496, 100 ) ) {
EC->reqHistoricalData
( 20
, C
, EndDateTime(2013,02,20) // 20130220 00:00:00
, DurationStr(1, *DurationHorizon::Months) // instead of "1 M"
, *BarSizeSetting::_1_day // instead of "1 day"
, *WhatToShow::TRADES // instead of "TRADES"
, UseRTH::OnlyRegularTradingData // instead of 1
, FormatDate::AsDate // instead of 1
);
///Easier: Call checkMessages() in a loop. No need to wait between two calls.
while( YW.notDone() ) {
EC->checkMessages();
}
}
EC->eDisconnect();
delete EC;
}Below are some of the tweaks to make a Visual Studio project when creating a fresh TwsApiC++ project.
Assuming you have copied the TwsApiC++ to C:\Jts\TwsApiCpp (adjust to your installation accordingly) and have compiled the TwsApiC++ library TwsApi.lib and saved it to C:\Jts\TwsApiCpp\TwsApiC++\Api
- For the Project property:
Project -> Properties -> C/C++ -> General -> Additional Include DirectoriesAdd the following folders for Shared and the API so that Visual Studio can find the header files:
C:\Jts\TwsApiCpp\source\PosixClient\Shared
C:\Jts\TwsApiCpp\TwsApiC++\Api
- For the Project property:
Project -> Properties -> Linker -> General -> Additional Library DirectoriesAdd the following folder:
C:\Jts\TwsApiCpp\TwsApiC++\Api
- For the Project property:
Project -> Properties -> Linker -> Input -> Additional DependenciesAdd the following files:
TwsApi.lib (for Release)
TwsApiD.lib (for Debug)
ws2_32.lib
- For the Project property:
Project -> Properties -> C/C++ -> Code Generation -> Runtime Library
For Release: Set to Multi-Threaded /MT to match the other libraries.
For Debug: Set to Multi-Threaded Debug /MTd to match the other libraries.
-
If you are building for Debug, use the
Multi-Threaded Debug /MTdswitch and add theTwsApiD.libfile. -
If you are building for Release, use the
Multi-Threaded /MTswitch and add theTwsApi.libfile. -
In Visual Studio 2013, you may also receive some warnings about the use of the "unsafe" functions like
sprintfandlocaltime. The suggested replacements aresprintf_sandlocaltime_s. Thesprintf_scall is a direct replacement forsprintfbutlocaltime_suses some different structures.
To get around these warnings (which may keep your program from compiling), add a #define _CRT_SECURE_NO_WARNINGS at the top of your program.