DEVELOPING DATA PROVIDERS FOR NEEDFORTRADE STUDIO PLATFORM NeedForTrade.com Internal release number: 2.0.2 Public release number: 1.0.1 27-06-2008 To develop data or brokerage provider for NeedForTrade Studio or NeedForTrade Studio Lite platform strong programming skills are required. Because of the very different nature of available data sources and brokerage APIs there can be no straightforward development guide. This guide only describes methods and properties that should be implemented to connect to 3 rd party data source or brokerage services. We've made available source codes of one of our data providers - Interactive Brokers to ease this task. See WHERE TO START section below. PREREQUISITES Microsoft Visual C# 2008 Express (can be downloaded here for free) or Microsoft Visual Studio 2008 Standard or Microsoft Visual Studio 2008 Professional or any other development tool and/or language that supports Microsoft.NET Framework 2.0 development. WHERE TO START To setup development environment and to test Interactive Brokers data provider sample, please follow steps described in this tutorial. DATA PROVIDER TYPES Here presented different types of data and brokerage providers that can be implemented: Historical Bar Data Provider provides access to historical bar data. Real-Time Data Provider delivers real-time bar data such as Ask price, Bid price and so on. Real-Time Bar Data Provider - delivers real-time data to update bars. Lookup Data Provider provides access to symbol lookup data. Broker implements brokerage support. Attention: In the latter text we don't distinguish data provider and brokerage support so everything mentioned about data providers can be applied to brokerage providers too. Tip: Real-Time Data Provider and Real-Time Bar Data Provider are often implemented by the same code. For each data provider type there is interface that defines methods and properties that must be implemented to create data provider. See interfaces hierarchy below. Page 1 of 8
DATA PROVIDER INTERFACES HIERARCHY All data providers must implement IDataProvider interface and one or more of data provider type-specific interfaces. IMPLEMENTING DATA PROVIDER To simplify data provider development there is base class DataProviderBase that implements base functionality and common methods of IDataProvider interface. For brokerage providers there is BrokerBase base class derived from DataProviderBase. We recommend to implement all data provider functionality in a single class derived from DataProviderBase, but using separate source files for each data provider functionality type using C# partial keyword. GENERAL DATA PROVIDER STATEMENTS Each request to data provider is stored in Request* class instance that can be retrieved by Request* property of DataProvidersBase class where * is specific to data provider type (e.g. RealTimeBarRequest, BrokerageRequest). For each request new instance of data provider class is created. Each data provider is called in a separate thread to avoid user interface freezes and locks. Some data provider types can do their job without holding separate thread (for example, Real Time data providers and Brokerage providers). Each data provider derived from DataProviderBase or BrokerBase can implement methods described above. Methods for any data provider: void SetupEvents_Common(bool bind) ( e.g. SetupEvents_RealTimeQuotes(bool bind) ) - binds/unbinds data provider-related common events. bool Connect() starts connection to data source. Page 2 of 8
void Disconnect() disconnects from data source. Data provider type-specific methods: void SetupEvents_*(bool bind) ( e.g. SetupEvents_RealTimeQuotes(bool bind) ) - binds/unbinds data provider-related events. void Shutdown*() ( e.g. ShutdownRealTimeQuotesData() ) - shuts down data provider instance (but doesn't close connection to data source). The following methods can be implemented only for selected data providers: void Request*() ( e.g. RequestRealTimeQuotesData() ) void Process*() ( e.g. ProcessHistoricalRequest() ) COMMON METHODS AND PROPERTIES Each data or brokerage provider must be marked with DataProvider attribute.see sample below. Where the first parameter is data provider name and the second parameter is a unique GUID string. [DataProvider("Interactive Brokers", "{707612AD-55BC-4e9e-94FE-55DB47505233}")] Each provider implements IDataProvider interface. The following methods can be implemented: public override string WebLookupLink Returns web url to data source simbol lookup page. protected override void SetupEvents_Common(bool bind) Binds/unbinds data provider-related common events. protected override bool Connect() Starts connection to data source. public override void Disconnect() Disconnects from data source. Page 3 of 8
DATA PROVIDER PROPERTIES Data provider can have two types of properties: Global properties that are common to the all data providers of this type. Private properties that are stored separately for each window (e.g. Chart). To save/restore (serialize) properties data provider can implement following methods: protected override void SerializeGlobalProperties(dem.Serialization.Serializer serializer) and protected override void SerializePrivateProperties(dem.Serialization.Serializer serializer) For examples see IBDataProviderGlobalProperties and IBDataProviderPrivateProperties in the supplied Interactive Brokers data provider code. HISTORICAL DATA PROVIDER Historical data provider implements IHistoricalBarDataProvider interface. Data request is stored in HistoricalBarRequest property. Historical data provider can implement following methods: protected override void SetupEvents_Historical(bool bind) Binds/unbinds historical data provider-related events. Example: protected override void SetupEvents_Historical(bool bind) { if (bind) { //binding to historical data related events IBSocket.HistoricalData += new IBSocket.HistoricalDataDelegate(IBSocket_HistoricalData); } else { //unbinding from Interactive Brokers historical data related events IBSocket.HistoricalData -= new IBSocket.HistoricalDataDelegate(IBSocket_HistoricalData); } } protected override void ProcessHistoricalRequest() Processes historical request. protected override void ShutdownHistoricalData() Cancels historical request (if it's not already eneded). Do not disconnect from data source in this method. Page 4 of 8
REAL-TIME DATA PROVIDER Real-time data provider implements IRealTimeDataProvider and IRealTimeBarDataProvider interfaces. Data request is stored in RealTimeQuotesRequest and RealTimeBarRequest properties. Real-time data provider must override following properties: bool SingletonRealTimeDataProvider this propery must return true if data provider doesn't require separate thread for processing request, otherwise false. Example: public bool SingletonRealTimeDataProvider { get { return true; } } Tip: It's recommended to not to hold separate thread if it's possible because each thread consumes CPU power. Real-time data provider can implement following methods: protected override void SetupEvents_RealTimeQuotes(bool bind) Binds/unbinds real-time quotes data provider-related events. protected override void SetupEvents_RealTimeBar(bool bind) Binds/unbinds real-time bar data provider-related events. protected override void RequestRealTimeBarData() Real time bar data should be requested from data source in this method. Request* methods are called after SetupEvents_* methods. protected override void RequestRealTimeQuotesData() Real time bar data should be requested from data source in this method. Request* methods are called after SetupEvents_* methods. protected virtual void ProcessRealTimeBarRequest() { } Process* methods can be implemented for real-time data providers that need to run in their own separate thread. It's better practice to avoid using separate thread and so no need to define this method. Process* methods are called after Request* methods. protected virtual void ProcessRealTimeQuotesRequest() { } Process* methods can be implemented for real-time data providers that need to run in their own separate thread. It's better practice to avoid using separate thread and so no need to define this method. Process* methods are called after Request* methods. protected override void ShutdownRealTimeQuotesData() Cancels real-time quotes request. Do not disconnect from data source in this method. Page 5 of 8
protected override void ShutdownRealTimeBarData() Cancels real-time bar request. Do not disconnect from data source in this method. LOOKUP DATA PROVIDER Lookup data provider implements ILookupDataProvider interface. Lookup request is stored in InstrumentLookupRequest property. Lookup data provider can implement following methods: protected override void SetupEvents_Lookup(bool bind) Binds/unbinds lookup data provider-related events. protected override void ProcessLookupRequest() Processes lookup request. protected virtual void ShutdownLookupData() { } Cancels real-time quotes request. Do not disconnect from data source in this method. BROKERAGE PROVIDER Brokerage provider implements IBroker interface. Broker implementation must derive from BrokerBase<T> class. Where T is broker trade order type. See section below. Brokerage request is stored in BrokerageRequest property. There are two types of brokerage requests: If BrokerageRequest.ManageOnlyPlatformTrades property is true than BrokerageRequest.Instrument property holds symbol for which brokerage is requesed. If BrokerageRequest.ManageOnlyPlatformTrades property is false than BrokerageRequest.Instrument property is null and brokerage implementation must listen to all brokerage events. Real-time data provider must override following properties: bool SingletonBroker this propery must return true if brokerage provider doesn't require separate thread for processing request, otherwise false. Example: public bool SingletonBroker { get { return true; } } Tip: It's recommended to not to hold separate thread if it's possible because each thread consumes CPU power. Brokerage provider must implement following methods: public void PlaceOrder(BrokerTradeOrder order) Sends order to broker. Page 6 of 8
public void CancelOrder(BrokerTradeOrder order) Cancels previously sent order. Brokerage provider can implement following methods: protected override void SetupEvents_Brokerage(bool bind) Binds/unbinds lookup data provider-related events. protected override void ProcessBrokerageRequest() Processes brokerage request. protected virtual void ShutdownBroker() { } Stops brokerage support. Do not disconnect from broker in this method. BROKER TRADE ORDER TYPE Each brokerage provider must define a class derived from BrokerTradeOrder class. This class stores broker-specific trade order properties. For the sample see IBTradeOrder class in the supplied Interactive Brokers data provider code. This class must implement the following methods: public override void Initialize() Initialization method. Broker property can be used to initialize trade order For the sample see IBTradeOrder class in the supplied Interactive Brokers data provider code. public override bool Equals(BrokerTradeOrder other) Equals method returns true if current trade order is equivalent to other trade order, otherwise false. For the sample see IBTradeOrder class in the supplied Interactive Brokers data provider code. APPENDIX A. THREAD SAFETY All DataProviderBase and BrokerBase properties are thread-safe. Methods listed below can be used to safely access class fields shared between different threads. long SafeRead(ref long location); Returns value of class field defined by location. double SafeRead(ref double location); Returns value of class field defined by location. float SafeRead(ref float location); Returns value of class field defined by location. int SafeRead(ref int location); Page 7 of 8
Returns value of class field defined by location. long SafeWrite(ref long location, long value); Writes value to class field defined by location. Returns value. double SafeWrite(ref double location, double value); Writes value to class field defined by location. Returns value. float SafeWrite(ref float location, float value); Writes value to class field defined by location. Returns value. int SafeWrite(ref int location, int value); Writes value to class field defined by location. Returns value. int SafeIncrement(ref int location); Increments value of class field defined by location. Returns incremented value. long SafeIncrement(ref long location); Increments value of class field defined by location. Returns incremented value. T SafeRead<T>(ref T value); Returns value of class field of type T (must be class) defined by location. SafeWrite<T>(ref T location, T value); Writes value to class field of type T (must be class) defined by location. Returns value. For samples of use see supplied Interactive Brokers data provider code. APPENDIX B. USEFUL CLASSES, METHODS AND PROPERTIES Useful methods: void Sleep(int millisecondstimeout); Pauses therad execution for specified number of milliseconds. DateTime Now; Returns current time in local timezone. Returns internet time servers-synchronized time. Use this method instead of DateTime.UtcNow call. DateTime UtcNow; Returns current time in universal (GMT) timezone. Returns internet time servers-synchronized time. Use this method instead of DateTime.UtcNow call. Useful classes: class ReusableRequestLock //Special type of lock to avoid simultaneous requests to some shared resource class ExclusiveRequestLock //Special type of lock to avoid duplicate requests by reusing existing connections For samples of use see supplied Interactive Brokers data provider code. Page 8 of 8