Blpapi Developers Guide
Blpapi Developers Guide
Blpapi Developers Guide
October 3, 2012
Table of Contents
Preface: About this Document .................................................................................................. 9 Purpose................................................................................................................................... 9 Audience ................................................................................................................................. 9 Document History ................................................................................................................... 9 1 Introduction to the Bloomberg API ..................................................................................... 10 1.1 Overview of the Bloomberg API ..................................................................................... 10 1.1.1 Features ................................................................................................................ 11 1.1.2 The Bloomberg Platform ....................................................................................... 13 1.1.3 Managed B-PIPE .................................................................................................. 14 1.1.4 The Desktop API and Server API.......................................................................... 15 1.2 The Programming Examples ......................................................................................... 18 1.3 Typical Application Structure ......................................................................................... 19 1.4 Overview of this Guide ................................................................................................... 19 2 Sample Programs in Two Paradigms.................................................................................. 20 2.1 Overview ........................................................................................................................ 20 2.2 The Two Paradigms ....................................................................................................... 21 2.2.1 Request/Response................................................................................................ 21 2.2.2 Subscription .......................................................................................................... 22 2.3 Using the Request/Response Paradigm ........................................................................ 22 2.4 Using the Subscription Paradigm................................................................................... 26 3 Sessions and Services ......................................................................................................... 29 3.1 Sessions ........................................................................................................................ 29 3.2 Services ......................................................................................................................... 29 3.3 Event Handling.............................................................................................................. 29 3.3.1 Synchronous Event Handling................................................................................ 31 3.3.2 Asynchronous Event Handling .............................................................................. 32 3.4 Multiple Sessions ........................................................................................................... 36 4 Requests and Responses .................................................................................................... 37 4.1 The Programming Example ........................................................................................... 37 4.2 Elements ........................................................................................................................ 38 4.3 Request Details.............................................................................................................. 38 4.4 Response Details ........................................................................................................... 40 5 Subscriptions ........................................................................................................................ 45 5.1 The Programming Example ........................................................................................... 45
Table of Contents
5.2 Starting a Subscription................................................................................................... 45 5.3 Receiving Data from a Subscription .............................................................................. 48 5.4 Modifying an Existing Subscription ................................................................................ 49 5.5 Stopping a Subscription................................................................................................. 49 5.6 Overlapping Subscriptions............................................................................................. 50 5.7 Conflation and the Interval Option ................................................................................. 50 5.8 Delayed Data ................................................................................................................. 50 5.9 Subscription Life Cycle .................................................................................................. 51 6 Core Services........................................................................................................................ 52 6.1 Common Concepts ........................................................................................................ 52 6.1.1 Security/Securities ................................................................................................ 52 6.1.2 Pricing Source....................................................................................................... 53 6.1.3 Fields .................................................................................................................... 54 6.1.4 Overrides .............................................................................................................. 54 6.1.5 Relative Dates....................................................................................................... 55 6.2 Reference Data Service //blp/refdata............................................................................. 56 6.2.1 Reference Data Request and Response Overview .............................................. 57 6.2.2 Historical Data Request ........................................................................................ 58 6.2.3 Intraday Tick Request ........................................................................................... 59 6.2.4 Intraday Bar Services............................................................................................ 60 6.2.5 Portfolio Data Request.......................................................................................... 61 6.2.6 BEQS Request...................................................................................................... 61 6.3 Market Data Service //blp/mktdata................................................................................. 62 6.4 Custom VWAP Service //blp/mktvwap........................................................................... 63 6.5 Market Bar Subscription Service //blp/mktbar................................................................ 63 6.6 API Field Information Service //blp//apiflds .................................................................... 64 6.6.1 Field Information Request..................................................................................... 64 6.6.2 Field Search Request ........................................................................................... 65 6.6.3 Categorized Field Search Request ....................................................................... 65 6.7 Page Data Service......................................................................................................... 67 6.8 Technical Analysis Service ............................................................................................ 70 6.8.1 Historical End of Day study request...................................................................... 70 6.8.2 Intraday bar study request .................................................................................... 72 6.8.3 Realtime study request ......................................................................................... 74 6.9 API Authorization ........................................................................................................... 75
Table of Contents
7 Authorization and Permissioning Systems........................................................................ 76 7.1 Overview........................................................................................................................ 76 7.2 Underlying Concepts ..................................................................................................... 76 7.2.1 EIDs ...................................................................................................................... 76 7.2.2 Requirement for the Terminal ............................................................................... 76 7.2.3 The //blp/apiauth service....................................................................................... 77 7.2.4 The V3 Identity Object .......................................................................................... 77 7.2.5 V3 Permissioning Models ..................................................................................... 77 7.2.6 Authorization Lifetime ........................................................................................... 77 7.3 Server API Authorization ............................................................................................... 78 7.3.1 Authorization by IP Address.................................................................................. 78 7.4 Managed B-PIPE Authorization ..................................................................................... 84 7.4.1 Authentication ....................................................................................................... 85 7.4.2 Token Generation ................................................................................................. 87 7.5 Authorization.................................................................................................................. 89 7.6 Permissioning ................................................................................................................ 91 7.6.1 Entitlements .......................................................................................................... 91 7.6.2 User Mode ............................................................................................................ 94 7.6.3 Content Based ...................................................................................................... 94 7.7 Specific Application Types (Managed B-PIPE only) ...................................................... 96 7.7.1 Single-User ........................................................................................................... 96 7.7.2 Multi-User.............................................................................................................. 96 7.7.3 Derived Data / Non-Display .................................................................................. 96 7.8 V2 Authorization and Permissioning Models ................................................................. 96 7.8.1 User Mode ............................................................................................................ 96 7.8.2 All-or-None............................................................................................................ 97 7.8.3 Content-Based / Per-Product / Per-Security ......................................................... 97 7.8.4 Validating Logon Status ........................................................................................ 98 8 Publishing ............................................................................................................................. 99 8.1 Overview........................................................................................................................ 99 8.2 The Programming Examples ......................................................................................... 99 8.3 Simple Broadcast........................................................................................................... 99 8.3.1 Creating a Session................................................................................................ 99 8.3.2 Authorization ....................................................................................................... 100 8.3.3 Creating a Topic.................................................................................................. 102 8.3.4 Publishing ........................................................................................................... 103
Table of Contents
8.4 Interactive Publication.................................................................................................. 104 8.4.1 Registration......................................................................................................... 105 8.4.2 Event Handling.................................................................................................... 106 8.4.3 Publication .......................................................................................................... 108 9 Managed B-Pipe.................................................................................................................. 110 9.1 Overview...................................................................................................................... 110 9.2 Managed B-Pipe Services ........................................................................................... 110 9.2.1 Market Depth Service ......................................................................................... 110 9.2.2 Market List Service ............................................................................................. 130 9.2.3 Source Reference Service .................................................................................. 146 A Schemas ............................................................................................................................. 154 A.1 Overview ..................................................................................................................... 154 A.2 Reference Data Service //blp/refdata .......................................................................... 154 A.2.1 Operations .......................................................................................................... 154 A.2.2 ReferenceDataRequest: Sequence.................................................................... 154 A.2.3 ReferenceDataResponse: Choice ...................................................................... 156 A.2.4 HistoricalDataRequest: Sequence...................................................................... 157 A.2.5 HistoricalDataResponse: Choice........................................................................ 162 A.2.6 IntradayTickRequest: Sequence ................................................................ 163 A.2.7 IntradayTickResponse: Choice........................................................................... 165 A.2.8 IntradayBarRequest: Sequence ......................................................................... 167 A.2.9 IntradayBarResponse: Choice............................................................................ 169 A.2.10 PortfolioDataRequest: Sequence ..................................................................... 170 A.2.11 PortfolioDataResponse: Choice ....................................................................... 171 A.2.12 BEQSRequest: Sequence ................................................................................ 172 A.2.13 BEQSResponse: Choice .................................................................................. 173 A.2.14 Reference Data Service Response .................................................................. 174 A.3 Schema for API Field Service //blp//apiflds ................................................................. 177 A.3.1 Requests: Choice ............................................................................................... 177 A.3.2 Responses: Choice ............................................................................................ 177 A.3.3 Field Information Request .................................................................................. 177 A.3.4 Field Search Request ......................................................................................... 179 A.3.5 Categorized Field Search Request..................................................................... 183 A.3.6 Field List Request............................................................................................... 186 A.3.7 Field Service Response Elements...................................................................... 188 A.3.8 Field Service Response Values.......................................................................... 189
Table of Contents
A.4 Market Bar Subscription .............................................................................................. 190 A.4.1 Market Bar Subscription Settings ....................................................................... 190 A.4.2 Market Bar Subscription: Data Events Response .............................................. 190 A.5 Schema for Market Data and Custom VWAP ............................................................. 192 A.5.1 MarketDataEvents: Choice................................................................................. 192 A.5.2 Market Data Service Subscription Options......................................................... 192 A.5.3 MarketDataEvents: Sequence............................................................................ 192 A.5.4 Market VWAP Service Subscription Options...................................................... 203 A.6 Schema for API Authorization ..................................................................................... 204 A.6.1 Authorization Request ........................................................................................ 204 A.6.2 Authorization Request Response ....................................................................... 205 A.6.3 Logon Status Request ........................................................................................ 206 A.6.4 Logon Status Request Response....................................................................... 206 A.6.5 User Entitlements Request................................................................................. 207 A.6.6 User Entitlements Request Response................................................................ 207 A.6.7 Security Entitlements Request ........................................................................... 208 A.6.8 Security Entitlements Request Response .......................................................... 208 A.6.9 Authorization Token Request ............................................................................. 209 A.6.10 Authorization Token Request Response .......................................................... 209 A.6.11 Field Service Response Elements.................................................................... 210 A.6.12 Field Service Request Values .......................................................................... 210 B Java Examples ................................................................................................................... 211 B.1 Request Response Paradigm ..................................................................................... 212 B.1.1 Request Response Paradigm Output................................................................. 214 B.2 Subscription Paradigm ................................................................................................ 215 B.3 Asynchronous Event Handling .................................................................................... 219 B.3.1 Asynchronous Event Handling: Output .............................................................. 222 B.4 Request Response Multiple ........................................................................................ 223 B.4.1 Request Response Multiple: Output................................................................... 226 B.5 Subscription Multiple ................................................................................................... 227 B.5.1 Multiple Subscription: Output B.6 Authorization by IP Address ................................................................. 230 ......................................................................... 237
C .Net Examples..................................................................................................................... 243 C.1 RequestResponseParadigm ....................................................................................... 244 C.1.1 Request Response Paradigm Output................................................................. 246 C.2 Subscription Paradigm ................................................................................................ 247
Table of Contents
C.3 Asynchronous Event Handling .................................................................................... 253 C.3.1 Asynchronous Event Handling: Output ............................................................. 257 C.4 Request Response Multiple C.5 Subscription Multiple .................................................................................... 258 C.4.1 Request Response Multiple: Output................................................................... 261 .............................................................................................. 262 ................................................................... 265 C.5.1 Multiple Subscription: Output
D C++ Examples..................................................................................................................... 270 D.1 RequestResponseParadigm ....................................................................................... 271 D.2 Subscription Paradigm ................................................................................................ 274 D.3 Asynchronous Event Handling .................................................................................... 279 D.4 Request Response Multiple ........................................................................................ 283 D.5 Subscription Multiple ................................................................................................... 287 E C Examples ......................................................................................................................... 296 E.1 RequestResponseParadigm ....................................................................................... 297 E.2 Subscription Paradigm ................................................................................................ 302 E.3 Asynchronous Event Handling .................................................................................... 311 E.4 Request Response Multiple ........................................................................................ 316 E.5 Subscription Multiple ................................................................................................... 324
Table of Contents
Audience
This document is intended for developers who use the Bloomberg API.
Document History
Version
1.0 1.23 1.24 1.25 1.26 1.27 1.28 1.29 1.30 1.31 1.32 1.33
Date
11/05/09 01/10/11 01/19/11 02/04/11 03/02/11 05/18/11 05/25/11 06/27/11 08/04/11 09/20/11 11/08/11 01/10/12
Description of Changes
This is the first release of the Bloomberg API Developers Guide. Updated Core Services on page 52 Authorization and Permissioning Systems on page 76, and Schemas on page 154. Updated Stopping a Subscription on page 49. Updated Security/Securities on page 52, HistoricalDataRequest: Sequence on page 157 ,and Figure A-1. Updated Creating a Topic on page 102. Added Conflation and the Interval Option on page 50 and Delayed Data on page 50. Add bsid to the Topic Prefix list in Security/Securities on page 52. Updated Authorization Lifetime on page 77. Updated IntradayTickRequest: Sequence on page 163 and added BEQSRequest: Sequence on page 172. Updated Field Information Request Response on page 178. Updated Entitlements on page 91. Fixed code formatting on page 212. Added details to Page Data Service on page 67. Updated Overrides on page 54 to specify that 100 overrides can be specified in a single request. Added note to page 47 about creating subscriptions with C#.
Updated license notice on front page. Added Managed B-Pipe on page 110 and updated Schemas on page 154. Corrected items in Table 9-4, Chain Subservice Examples, on page 134 and Table 9-5, Additional "chain" Subscription Examples, on page 135.
10
10
1.1.1 Features
Feature Four Languages, One Interface Details API 3.0 provides all new programming interfaces in:
The Java, .Net and C++ object models are identical, while the C interface provides a C-style version of the object model. You are able to effortlessly port applications among these languages as the needs of your applications change. Lightweight Interfaces The API 3.0 programming interface implementations are extremely lightweight. The lightweight design makes the process of receiving data from Bloomberg and delivering it to applications as efficient as possible. It is now possible to get the maximum performance out of the Java, .Net, C, and C++ versions of the interface. Extensible ServiceOriented Data Model The new API generically understands the notions of subscription and request-response services. The subscribe method and request method allow you to send requests to different data services with potentially different or overlapping data dictionaries and different response schemas. This, in combination with the new canonical data form, means that Bloomberg can deliver new data services via the API without having to extend the interface to support the new services. Field Level Subscriptions You are now able to request updates for only the fields of interest to your application, rather than receiving all trade and quote fields when you establish a subscription. This reduces the overhead of processing unwanted data within both the API and your application, and also reduces network bandwidth consumption between Bloomberg and its customers. For example, if quotes are of no interest to an application, processing and bandwidth consumption can be cut by as much as 90%.
11
Details When you subscribe to market data for a security, the API performs two actions: 1. It retrieves a summary of the current state of the security and delivers it to you. A summary is made up of data elements known as fields. The set of summary fields varies depending on the asset class of the requested security. 2. The API streams all market data updates to you as they occur and continues to do so until you cancel the subscription. About 300 market data fields are available via the API subscription interface, most of them derived from trade and quote events.
Interval-based Subscriptions
Many users of API data are interested in subscribing to large sets of streaming data but only need summaries of each requested security to be delivered at periodic intervals. The API subscription model allows you to specify the minimum interval at which to receive streaming updates. This reduces processing and bandwidth consumption by delivering only an updated summary at the interval you define. It is also possible to establish multiple subscriptions such that a summary arrives periodically but other fields, such as traderelated fields are delivered in real-time.
API 3.0 allows you to request a potentially unlimited number of securities and fields without having to manage request rates yourself. The API infrastructure manages the distribution of these requests across Bloomberg's back end data servers, which in turn ensure that all arriving data requests are given equal access to the available machine resources.
Each data field returned to an application via the API is now accompanied by an in-memory dictionary element that indicates the data type (for example, integer, double) and provides a description of the field - the data is self-describing. Data elements may be simple, such as a price field, or complex, such as historical prices or bulk fields. All data is represented in the same canonical form and developers do not have to deal with multiple data formats or be exposed to the details of the underlying transport protocol.
12
Feature Thread-Safe
Details All language bindings for the new API are now fully thread-safe. Applications can safely process responses and make requests simultaneously from multiple threads of execution. The Java and .Net API work on both 32- and 64-bit platforms. The C and C++ API libraries come in a 32-bit version with a 64- bit version coming in the future. The Java API is implemented entirely in Java. Bloomberg did not use JNI to wrap either our existing C library or the new C++ library. An application can discover a service and its attributes at runtime. Release 3.0 of the Server API provides a simplified permissioning model that allows you to simply provide a users UUID and IP address. The API returns the permissions to you.
32- and 64-bit Programming Support Pure Java Implementation Fully Introspective data model Simplified Permissioning Model
13
the Bloomberg Platform is a complete high-volume, low-latency service to end users, applications, and displays throughout your entire financial firm (see Figure 1-1).
14
15
The Desktop API The Desktop API is used when the end-user application resides on the same machine as the installed BLOOMBERG PROFESSIONAL service and connects to the local Bloomberg Communications Server (BBComm) to obtain data from the Bloomberg Data Center (see Figure 1-3).
Figure 1-3: The Desktop API The Server API The Server API allows customer end-user applications to obtain data from the Bloomberg Data Center via a dedicated process, known as the Server API process. Introduction of the Server API process allows, in some circumstances, better use of network resources. When the end-user applications interact directly with the Server API process they are using the Server API in User Mode (see Figure 1-4).
16
Figure 1-4: The Server API: User Mode When the customer implements a Customer Server Application to interact with the Server API process (see Figure 1-5), the Server API is then being used in Server Mode (by the Customer Server Application). Interactions between the Customer Server Application and the Customer End-User Application(s) are handled by an application protocol of the customers design.
17
18
Complete, contiguous listings of the Java code examples are provided in Java Examples on page 211 and the programming interface specification is found in Schemas on page 116. For the sample programs in the other supported languages see:
.Net Examples on page 243 C++ Examples on page 270 C Examples on page 296
First a small but complete example program is presented to illustrate the most common features of the Bloomberg API. See Sample Programs in Two Paradigms on page 20. This is followed by detailed descriptions of the key scenarios in using the Bloomberg API: creating a session; opening services; sending requests and processing their responses; subscribing to streaming data and processing the results. See Sessions and Services on page 29, Requests and Responses on page 37, and Subscriptions on page 45.
19
The creation and startup of a Session object which the application uses to specify the data it wants and then receive that data. Data from the Bloomberg infrastructure is organized into various services. The application "opens" the service that can provide the needed data (e.g., reference data, current market data). The application asks the service for specific information of interest. For example, the last price for a specific security. The application waits for the data to be delivered.
Data from the service will arrive in one or more asynchronously delivered Event objects. If an application has several outstanding requests for different data, the data arriving from these multiple requests may be interleaved with each other; however, data related to a specific request always arrives in order. Note: To assist applications in matching incoming data to requests, the Bloomberg API allows applications to provide a CorrelationID object with each request. Subsequently, the Bloomberg infrastructure uses that identifier to tag the events sent in response. On receipt of the Event object, the client can use the identifier it supplied to match events to requests. Even if an application (such as the examples in this chapter) makes only a single request for data, the application must also be prepared to handle status events from the service in addition to the requested data.
20
The following display provides an outline of the organization used in these examples.
import classes public class Example1 { private static void handleDataEvent(Event event) throws Exception { } private static handleOtherEvent(Event event) throws Exception { } public static void main(String[] args) throws Exception { create and start Session use Session to open service ask service for data (provide id for service to label replies) loop waiting for data; pass replies to event handlers } }
The additional details needed to create a working example are provided below.
2.2.1 Request/Response
In this case, data is requested by issuing a Request and is returned in a sequence consisting of zero or more Events of type PARTIAL_RESPONSE followed by exactly one Event of type RESPONSE. The final RESPONSE indicates that the Request has been completed.
21
In general, applications written to this paradigm will perform extra processing after receiving the final RESPONSE from a Request.
2.2.2 Subscription
In this case a Subscription is created which results in a stream of updates being delivered in Events of type SUBSCRIPTION_DATA until the Subscription is explicitly cancelled by the application.
22
CorrelationID requestID = new CorrelationID(1); Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "PX_LAST"); session.sendRequest(request, requestID); boolean continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: // final event continueToLoop = false; // fall through case Event.EventType.Constants.PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } } }
A Session is created and started; then that Session is used to open a service named "//blp/refdata", a service that provides data according to the Request/ Response paradigm. In this example, the values explicitly set for host and port correspond to the default values for Session; supply the values for your installation. If the default values suffice then Session construction can be simplified to:
Session session = new Session();
The Session is used to obtain refDataSvc, a handle for the service, which is used to obtain an empty Request object for the "ReferenceDataRequest" operation. The empty request object is customized to the data needed for this application: the security of interest is "IBM US Equity", the Bloomberg field of interest is "PX_LAST" (last price). The request is sent to the service along with requestID, an application specified CorrelationID. (The value chosen is not important for this example.) The application enters a loop that makes a blocking request for nextEvent from the Session. Each Event is handled according to its type.
Both PARTIAL_RESPONSE and (final) RESPONSE events are handled by the user defined handleResponseEvent method. The only difference is that
23
the (final) RESPONSE changes the state of continueToLoop so that the looping stops and the application terminates.
Event objects of any other type are handled by a different user defined handler, handleOtherEvent.
In this application, the event handlers simply output some information about the received events.
private static void handleResponseEvent(Event event) throws Exception { System.out.println("EventType =" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType =" + message.messageType()); message.print(System.out); } }
Each Event has a type and possibly some associated Messages which can be obtained via the MessageIterator obtained from the Event. Each Message from these response events shows the same CorrelationID that was specified when the Request was sent. Additionally, each Message has a type. Finally, there is a print method to output the details of the Message in a default format.
24
However, this response to our query is not the only output from this program. This application also receives Events of type neither PARTIAL_RESPONSE nor RESPONSE.
EventType=SESSION_STATUS correlationID=null messageType=SessionStarted SessionStarted = { } EventType=SERVICE_STATUS correlationID=Internal: 1 messageType=ServiceOpened ServiceOpened = { }
This output comes from the event handling function called from the default case of the switch statement. The events reported here are returned in response to the applications starting of a session and opening of a service.
private static void handleOtherEvent(Event event) throws Exception { System.out.println("EventType=" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType=" + message.messageType()); message.print(System.out); if (Event.EventType.Constants.SESSION_STATUS == event.eventType().intValue() && "SessionTerminated" == message.messageType().toString()){ System.out.println("Terminating: " + message.messageType()); System.exit(1); } } }
The overall organization of handleOtherEvent is quite similar to that of handleResponseEvent but there are some notable differences:
Some messages (e.g., system messages) may not have a CorrelationID. The handler must be able to handle such cases. Note: The SERVICE_STATUS correlation ID has type Internal because it was automatically generated. The RESPONSE correlation ID that was explicitly specified by the application is typed User.
There may be events that do not arise from application request; for example, an unexpected session shutdown.
25
The service opened by this application has been changed from "//blp/refdata" (reference data) a service that follows the request/response paradigm to "//blp/mktdata" (market data), a service that follows the subscription paradigm. Instead of creating and initializing a Request; here we create and initialize a SubscriptionList and then subscribe to the contents of that list. In this first example, we subscribe to only one security, "AAPL US Equity", and specify only one Bloomberg field of interest, LAST_PRICE (the subscription analog for PX_LAST, the field used in the request/response example). The request/response example had application logic to detect the final event of the request and then break out of the event-wait-loop. Here, there is no final event. A subscription will continue to send update events until cancelled (not done in this example) or until the session shut down (handled, as we did before, in the handleOtherEvent method). The event type of particular interest is now SUBSCRIPTION_DATA. In this example, these events are passed to the handleEventData method.
26
The handleDataEvent method is quite similar to handleResponseMethod. The additional parameter, updateCount, is used in this simple example just to enhance the output.
private static void handleDataEvent(Event event, int updateCount) throws Exception { System.out.println("EventType=" + event.eventType()); System.out.println("updateCount = " + updateCount); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID = " + message.correlationID()); System.out.println("messageType = " + message.messageType()); message.print(System.out); } }
Despite these many similarities, the output from the subscription is considerably different from that of the request/response. Examine the output for a random event in the sequence:
EventType=SUBSCRIPTION_DATA updateCount = 54 correlationID = User: 2 messageType = MarketDataEvents MarketDataEvents = { LAST_PRICE = 85.71 VOLUME = 18969874 LAST_TRADE = 85.71 LAST_ALL_SESSIONS = 85.71 EQY_TURNOVER_REALTIME = 1.6440605281984758E9 ALL_PRICE_SIZE = 100 ALL_PRICE = 85.71 SIZE_LAST_TRADE_TDY = 100 RT_PX_CHG_NET_1D = -4.29 RT_PX_CHG_PCT_1D = -4.767 VOLUME_TDY = 18969874 LAST_PRICE_TDY = 85.71 LAST2_PRICE = 85.719 LAST_DIR = -1 LAST2_DIR = 1 SIZE_LAST_TRADE = 100 TIME = 19:06:30.000+00:00 TRADE_SIZE_ALL_SESSIONS_RT = 100 EVENT_TIME = 19:06:30.000+00:00 EID = 14005 IS_DELAYED_STREAM = false }
27
Clearly, this subscription event provides much data in addition to LAST_PRICE, the specifically requested field (shown in bold above). A later example will demonstrate how a customer application can extract and use the value of interest. Note: The Bloomberg infrastructure is at liberty to package additional fields in the data returned to a client; however, the client cannot validly expect any data except the requested fields. This sample output shows that the requested field is the first data out of message; that is happenstance and cannot be assumed. The output of the otherEventHandler method also shows differences from the first example.
EventType=SESSION_STATUS correlationID=null messageType=SessionStarted SessionStarted = { } EventType=SERVICE_STATUS correlationID=Internal: 1 messageType=ServiceOpened ServiceOpened = { } EventType=SUBSCRIPTION_STATUS correlationID=User: 2 messageType=SubscriptionStarted SubscriptionStarted = { }
In addition to the events for the start of session and opening of a service, which were seen in the request/response example, we also see here an event signaling that a subscription has been initiated. The empty SubscriptionStarted message indicates successful starting of the subscription; otherwise, there would have been error information. The value of the CorrelationID informs the customer application which subscription (of possibly many subscription requests) has been successfully started.
28
3.2 Services
All Bloomberg data provided by the Bloomberg API is accessed through a "service" which provides a schema to define the format of requests to the service and the events returned from that service. The customer application's interface to a Bloomberg service is a Service object. Accessing a Service is a two step process.
Open the Service using either the openService or the openServiceAsync methods of the Session object. Obtain the Service object using the getService method of the Session object.
In both stages above, the service is identified by its "name", an ASCII string formatted as "//namespace/service"; for example, "//blp/refdata". Once a service has been successfully opened, it remains available for the lifetime of that Session object.
29
Alternatively, one can supply an EventHandler object when creating a Session. In this case, the user-defined processEvent method in the supplied EventHandler will be called by the Bloomberg API when an Event is available. The signature for processEvent method is:
public void processEvent(Event event, Session session) // Note: no exceptions are thrown
The calls to the processEvent method will be executed by a thread owned by the Bloomberg API, thereby making the customer application multi-threaded; consequently customer applications must, in this case, ensure that data structures and code accessed from both its main thread and from the thread running the EventHandler object are threadsafe. The two choices for event handling are mutually exclusive:
If a Session is provided with an EventHandler when it is created calling the nextEvent method will throw an exception. If no EventHandler is provided then the only way to retrieve Event object is by calling the nextEvent method.
30
31
The status for starting the asynchronous session will be received as an event and checked in the handler. Also, there is no exit from main; logic in the event handler will determine when the process should be terminated. The MyEventHandler class is in this example a non-public class (it is used only by main) implementing the EventHandler interface. The class also defines dumpEvent, a "helper" function.
class MyEventHandler implements EventHandler { void dumpEvent(Event event){ Output event type. For each message, output the type and correlation ID. } public void processEvent(Event event, Session session) { Details below. } }
32
The processEvent method is organized to each of the expected events as well as unexpected events:
public void processEvent(Event event, Session session) { switch (event.eventType().intValue()) { case Event.EventType.Constants.SESSION_STATUS: { If session started, open service. break; } case Event.EventType.Constants.SERVICE_STATUS: { If service opened successfully, send request. break; } case Event.EventType.Constants.PARTIAL_RESPONSE: { Handle partial response. break; } case Event.EventType.Constants.RESPONSE: Handle final response. break; } default: { Handle unexpected response. break; } }
Each case in processEvent will now be examined in greater detail. We first show the processing of the event returned for starting the session. If successful, the code will attempt to open the needed service. Since the openServiceAsync method throws an exception on failure, but processEvent is not allowed to emit an exception, that call must be surrounded by a try-catch block. In event of failure, this simple example chooses to terminate the process.
33
case Event.EventType.Constants.SESSION_STATUS: { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); if (message.messageType().equals("SessionStarted")) { try { session.openServiceAsync("//blp/refdata", new CorrelationID(99)); } catch (Exception e) { System.err.println( "Could not open //blp/refdata for async"); System.exit(1); } } else { Handle error. } } break; }
On receipt of a SERVICE_STATUS type event, the messages are searched for one indicating that the openServiceAsync call was successful: the message type must be "ServiceOpened" and the correlation ID must match the value assigned when the request was sent.
34
If the service was successfully opened, we can create, initialize and send a request as has been shown in earlier examples. The only difference is that the call to sendRequest must be guarded against the transmission of exceptions, not a concern until now.
case Event.EventType.Constants.SERVICE_STATUS: { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); if (message.correlationID().value() == 99 && message.messageType().equals("ServiceOpened")) { //Construct and issue a Request Service service = session.getService("//blp/refdata"); Request request = service.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "LAST_PRICE"); try { session.sendRequest(request, new CorrelationID(86)); } catch (Exception e) { System.err.println("Could not send request"); System.exit(1); } } else { Handle other message types, if expected. } } break; }
The handling of events containing the requested data is quite similar to the examples already seen. One difference is that, in this example, on the final event, we terminate the process from the event handler, not from main.
35
case Event.EventType.Constants.PARTIAL_RESPONSE: { dumpEvent(event); // Handle Partial Response break; } case Event.EventType.Constants.RESPONSE: { dumpEvent(event); // Handle final response // Example complete; shut-down. try { session.stop(Session.StopOption.ASYNC); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("terminate process from handler"); System.exit(0); break; }
Finally, for completeness, there is a default case to handle events of unexpected types.
default: { System.err.println("unexpected Event"); dumpEvent(event); System.exit(1); break; }
36
Our focus will be on the creation and initialization of the request in main and, later, on the extraction of data from the response in the user-defined handleResponseEvent method.
37
4.2 Elements
The services provided by the Bloomberg API collectively accept a great variety of different types of requests which, in turn, often take many different parameters and options. The data returned in response is correspondingly diverse in type and organization. Consequently, requests and responses are composed of Element objects: instances of a class with great flexibility in representing data.
Firstly, an Element object can contain a single instance of a primitive type such as an integer or a string. Secondly, Element objects can also be combined into hierarchical types by the mechanism of SEQUENCE or CHOICE.
A SEQUENCE is an Element object that contains one or more Element objects, each of which may be of any type, similar to a struct in the C language. A CHOICE is an Element object that contains exactly one Element object of a type from a list of possible Element types. That list can be composed of any Element types, similar to a union in the C language.
The Element class also provides introspective methods (in addition to the introspective methods provided by the Java language) which allow the programmatic discovery of the structure of an Element object and any constituent Element objects. However, that level of generality is required in few applications. Most applications can be written to a known structure for request and response, as defined in the schema for a service. Should an applications structural assumptions prove incorrect (e.g., service schemas can be redefined), then an Exception is generated at run-time. Note: Incompatible changes to the schema of a Bloomberg core service are very rare. In fact, so far there have been none. Should such changes ever be necessary, they will be phased in and announced with ample warning.
a list of fields of interest, each a string type, a list of securities of interest, each a string type, and a list of overrides, each of type FieldOverride, a non-primitive type. This last Element is optional and will not be used in this example.
38
the Session is created and started the Service is opened and a handle to that Service is obtained.
Given the handle to the service, here named refDataSvc, a Request can be created for the request type named "ReferenceDataRequest".
Request request = refDataSvc.createRequest("ReferenceDataRequest");
As described in the schema, this request consists of three Element objects named "securities", "fields", and "overrides", each initially empty. These elements represent arrays of strings so their values can be set by appending strings to them specifying the securities and fields required, respectively.
request.getElement("securities").appendValue("AAPL US Equity"); request.getElement("securities").appendValue("IBM US Equity"); request.getElement("securities").appendValue("BLAHBLAH US Equity"); request.getElement("fields").appendValue("PX_LAST"); // Last Price request.getElement("fields").appendValue("DS002"); // Description request.getElement("fields").appendValue("VWAP_VOLUME"); // Volume used to calculate the Volume Weighted Average Price (VWAP)
The request is now ready to be sent. Note that one of the securities was deliberately set to an invalid value; later, we will examine the error returned for that item. Note: This usage pattern of appending values of arrays of Elements occurs so frequently that the Request class provides convenience methods that are more concise (but also obscure the Element sub-structure):
request.append("securities", "AAPL US Equity"); request.append("securities", "IBM US Equity"); request.append("securities", "BLAHBLAH US Equity"); request.append("fields", "PX_LAST"); request.append("fields", "DS002"); request.append("fields", "VWAP_VOLUME");
39
The rest of main, specifically the event-loop for the response, is essentially the same as that used in earlier examples. The main function is shown in its entirety below;
public static void main(String[] args) throws Exception { Session session = new Session(); session.start(); session.openService("//blp/refdata"); Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.getElement("securities").appendValue("AAPL US Equity"); request.getElement("securities").appendValue("IBM US Equity"); request.getElement("securities").appendValue("BLAHBLAH US Equity"); request.getElement("fields").appendValue("PX_LAST"); // Last Price request.getElement("fields").appendValue("DS002"); // Description request.getElement("fields").appendValue("VWAP_VOLUME"); // Volume used to calculate Volume Weighted Average Price (VWAP) session.sendRequest(request, new CorrelationID(1)); boolean continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: // final response continueToLoop = false; // fall through case Event.EventType.Constants.PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } } }
40
schema, but is also conveniently viewed, as we have done earlier, by printing the response in the response event handler code.
ReferenceDataResponse (choice) = { securityData[] = { securityData = { security = AAPL US Equity sequenceNumber = 0 fieldData = { PX_LAST = 173.025 DS002 = APPLE INC VWAP_VOLUME = 3.0033325E7 } } } }
The fact that the element named "ReferenceDataResponse" is an array allows each response event to receive data for several of the requested securities. The Bloomberg API may return a series of Message objects (each containing a separate "ReferenceDataResponse") within a series of Event objects in response to a request. However, each security requested will appear in only one array entry in only one Message object. Each element of the "securityData" array is a SEQUENCE that is also named "securityData". Each "securityData" SEQUENCE contains an assortment of data including values for the fields specified in the request. The reply corresponding to the invalidly named security, "BLAHBLAH US Equity", shows that the number and types of fields in a response can vary between entries.
ReferenceDataResponse (choice) = { securityData[] = { securityData = { security = BLAHBLAH US Equity securityError = { source = 100::bbdbs1 code = 15 category = BAD_SEC message = Unknown/Invalid security [nid:100] subcategory = INVALID_SECURITY } sequenceNumber = 2 fieldData = { } } } }
This response message has an Element not previously seen, named "securityError". This Element provides details to explain why data could not be provided for this security. Note that sending one unknown security did not invalidate the entire request.
4 Requests and Responses 41
Just printing the response in the default format is educational but to perform any real work with the response the values must be extracted from the received message and assigned elsewhere for use. The following event handler shows how to navigate the Element structure of the "ReferenceDataResponse". The asElement method of Message provides a handle for navigating the contents of the Message objects using Element methods. If an Element object is an array (e.g., securityDataArray) then the numValues method provides the number of items in the array. Note: The Element class also provides similarly named method, numElements (not used in this example), which returns the number of Element objects in a SEQUENCE.
42
private static void handleResponseEvent(Event event) throws Exception { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); Element ReferenceDataResponse = message.asElement(); if (ReferenceDataResponse.hasElement("responseError")) { handle error } Element securityDataArray = ReferenceDataResponse.getElement("securityData"); int numItems = securityDataArray.numValues(); for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.getValueAsElement(i); String security = securityData.getElementAsString("security"); int sequenceNumber = securityData.getElementAsInt32("sequenceNumber"); if (securityData.hasElement("securityError")) { Element securityError = securityData.getElement("securityError"); handle error return; } else { Element fieldData = securityData.getElement("fieldData"); double px_last = fieldData.getElementAsFloat64("PX_LAST"); String ds002 = fieldData.getElementAsString("DS002"); double vwap_volume = fieldData.getElementAsFloat64( "VWAP_VOLUME"); // Individually output each value System.out.println("* security =" System.out.println("* sequenceNumber=" System.out.println("* px_last =" System.out.println("* ds002 =" System.out.println("* vwap_volume =" System.out.println(""); } } } } + + + + + security); sequenceNumber); px_last); ds002); vwap_volume);
When stepping through the securityData array, the requested Bloomberg fields are accessed by the name and type (e.g., getElementAsFloat64, getElementAsInt32) as specified in the schema. Once values have been assigned to
43
local variables they can be used as needed. In this simple example, they are merely output individually in a distinctive format. The program output is shown below.
* * * * * * * * * * security =AAPL US Equity sequenceNumber=0 px_last =173.025 ds002 =APPLE INC vwap_volume =3.0033325E7 security =IBM US Equity sequenceNumber=1 px_last =126.46 ds002 =INTL BUSINESS MACHINES CORP vwap_volume =2885962.0
* security =BLAHBLAH US Equity securityError = { source = 100::bbdbs1 code = 15 category = BAD_SEC message = Unknown/Invalid security [nid:100] subcategory = INVALID_SECURITY }
The sequenceNumber is provided to allow the ordering of PARTIAL_RESPONSE events from the reference data service.
44
5 Subscriptions
Subscriptions are ideal for data that changes frequently and/or at unpredictable intervals. Instead of repeatedly polling for the current value your application gets the latest value as soon as it is available without wasting time and bandwidth when there has been no change. This chapter contains more details on how you can start, modify, and stop subscriptions as well as what to expect as the result of a subscription and how to handle those results. This chapter uses examples from the "//blp/mktdata" service. Currently, the Bloomberg API services that provide a subscription service are market data and Custom VWAP. In the future, the Bloomberg API may support delivering information other than market data through a subscription service.
SubscriptionMultiple.cs (Subscription Multiple on page 262) SubscriptionMultiple.cpp (Subscription Multiple on page 287) SubscriptionMultiple.c (Subscription Multiple on page 324)
The service name (for example, "//blp/mktdata"). If you do not specify the service name the defaultSubscriptionService of the SessionOptions object is used. The topic. In the case of "//blp/mktdata" the topic value consists of an optional symbology identifier followed by an instrument identifier. For example, "/cusip/ 097023105" and "/sedol1/2108601" include the symbology identifier whereas "IBM US Equity" omits the symbology identifier. If you do not specify the symbology identifier then the defaultTopicPrefix of the SessionOptions object is used. Note: The topic's form may be different for different subscription services. The options. These are qualifiers that can affect the content delivered. Examples in "//blp/mktdata" include specifying which fields an application requires or specifying an interval for conflated data.
5 Subscriptions
45
The correlation ID. Data for each subscription is tagged with a correlation ID (represented as a CorrelationID object) which must be unique to the session. The customer application can specify that value when the subscription is created. If the customer application does not specify a correlation ID, the Bloomberg infrastructure will supply a suitable value; however, in practice, the internally generated correlation ID is rarely used. Most customer applications assign meaningful correlation ids that allow the mapping of incoming data to the originating request or subscription.
You can represent any subscription as a single string that includes the service name, topic and options. For example:
//blp/mktdata/cusip/ subscription using the market data service to an instrument (BA) specified by CUSIP where any changes to the fields LAST_PRICE or LAST_TRADE_ACTUAL from the Bloomberg data model should generate an update.
097023105?fields=LAST_PRICE,LAST_TRADE_ACTUAL" represents a
"IBM US Equity?fields=BID,ASK&interval=2" represents a subscription using the market data service to an instrument (IBM) specified by Bloomberg Ticker where any changes to the fields BID or ASK from the Bloomberg data model should generate an update subject to conflation restriction of at least two seconds between updates. In this case, we are assuming that the Session has a defaultSubscriptionService of "//blp/mktdata" and a defaultTopicPrefix of "ticker/".
The Bloomberg API provides methods which accept the subscription specification as a single string as well as methods in which the different elements of the subscription are specified as separate parameters. Subscriptions are typically manipulated in groups so the Bloomberg API provides methods that operate on a list of subscriptions. This example shows subscription creation by several of these methods.
SubscriptionList subscriptions = new SubscriptionList(); CorrelationID subscriptionID_IBM = new CorrelationId(10); subscriptions.add(new Subscription("IBM US Equity", "LAST_TRADE", subscriptionID_IBM))); subscriptions.add(new Subscription("/ticker/GOOG US Equity", "BID,ASK,LAST_PRICE", new CorrelationID(20))); subscriptions.add(new Subscription("MSFT US Equity", "LAST_PRICE", "interval=.5", new CorrelationID(30))); subscriptions.add(new Subscription( "/cusip/097023105?fields=LAST_PRICE&interval=5.0", //BA US Equity new CorrelationID(40))); session.subscribe(subscriptions);
5 Subscriptions
46
Subscribing to this list of subscriptions returns an Event of type SUBSCRIPTION_STATUS consisting of a Message object of type SubscriptionStarted for each CorrelationID. For example, the user-defined "dump" method used previous examples shows:
eventType=SUBSCRIPTION_STATUS messageType=SubscriptionStarted CorrelationID=User: 10 SubscriptionStarted = { } messageType=SubscriptionStarted CorrelationID=User: 20 SubscriptionStarted = { } messageType=SubscriptionStarted CorrelationID=User: 30 SubscriptionStarted = { } messageType=SubscriptionStarted CorrelationID=User: 40 SubscriptionStarted = { }
In case of an error, there is an Event to report the subscriptions that failed. For example, if the specification for MSFT (correlation ID 30) above was mistyped (MSFTT) we would get the event:
eventType=SUBSCRIPTION_STATUS messageType=SubscriptionFailure CorrelationID=User: 30 SubscriptionFailure = { reason = { source = BBDB@p111 errorCode = 2 category = BAD_SEC description = Invalid security } }
5 Subscriptions
47
5 Subscriptions
48
The client receives an Event object indicating successful re-subscription (or not) before receipt of any data from that subscription. Note: The behavior is undefined if the topic of the subscription (e.g., the security itself) is changed.
5 Subscriptions
49
5 Subscriptions
50
Please note that Desktop API and Server API will have automatic access to delayed data (where available), whereas Managed B-Pipe requires explicit permission for access.
Start-up: Subscriptions are started by the subscribe method of Session. An Event object is generated to report the successful creation of any subscriptions and separate events for each failure, if any. Data Delivery: Data is delivered in Event objects of type SUBSCRIPTION_DATA; each such event has one or more messages; each such Message object has one or more correlation IDs to identify the associated subscriptions. Since each Message object may contain more data than requested in any individual subscription, the code managing each subscription must be prepared to extract its data of interest from the Message object. Note: customer applications must not rely on the delivery of data that was not explicitly requested in the subscription.
Modification: A list of subscriptions (each subscription identified by its correlation ID) can be modified by the resubscribe method of Session. Cancellation: Subscriptions (each subscription identified by its correlation ID) can be cancelled by the unsubscribe method of Session. Failure: A subscription failure (e.g., a server-side failure) is indicated by an Event of type SUBSCRIPTION_STATUS containing a Message to describe the problem.
5 Subscriptions
51
6 Core Services
There are two core and five additional services for accessing Bloomberg data. Each API service operates with either the subscription or request/response paradigm through following well-defined schema. The schema defines the request and request options, with detailed information in Appendix A Schemas. This chapter provides an overview of each of these services.
Core:
Reference Data Service Market Data Service
"//blp/refdata" "//blp/mktdata"
Additional:
Custom VWAP Service Market Bar Subscription Service API Field Information Service Page Data Service Technical Analysis Service API Authorization Important Notes: 1. Each Bloomberg data product using the Bloomberg API may vary in the services available and also the entirety of the service available. Please see the specific product overview to determine which services are available. For information on the Managed B-Pipe-only services, please see Managed B-Pipe Services on page 110.
"//blp/mktvwap" "//blp/mktbar" "//blp/apiflds" "//blp/pagedata" "//blp/tasvc" "//blp/apiauth"
2.
6 Core Services
52
Syntax
A security must conform to the following syntax:
/[Topic Prefix]/SYMBOLOGY[@Pricing Source][Exchange]
The default format for a security is the Bloomberg ticker format, for example, "IBM US Equity". This format consists of:
SYMBOLOGY [Exchange] <Yellow Key> SYMBOLOGY is required and is the ticker name [Exchange] is optional and is a two character mnemonic for the exchange where
the security is traded. If you do not specify [Exchange] then the default value for the user or for the Server API process will be used.
<Yellow Key> is the text equivalent of one of the Bloomberg yellow function keys. Govt M-Mkt Equity Curncy Corp Muni Comdy Client Mtge Pfd Index
Case Sensitivity
The API will adjust the yellow key (Equity, Cmdty, Index...) to be in the correct format despite the case that is used. An example is that it will adjust "equity" to "Equity". The ticker and source are case sensitive and will need to be specified in the correct casing for it to resolve. The only exception is if all characters are specified in lower case in which the API will always change to upper case for both the ticker and source. Hence "vod ln" and "VOD LN" are the same and will both be successful, however "vOD lN" will not resolve."
6 Core Services
53
If you wish to specify which pricing source should be used append @ followed by the pricing source to the security, for example, "/cusip/912828GM6@BGN" or "MSFT@ETPX US Equity". Note for securities in the Curncy Yellow Key use a space instead of @ to separate the security from the pricing source, for example, "GBPUSD BAAM Curncy". In Managed B-Pipe, if you request a security with a specific pricing source (e.g., CT10@BGN Govt), and if there is not pricing available on the specified source, you will receive a 'Pricing Not Available' error. Reference data requests that are not pricing specific will return data. In the event that you are not entitled for the requested source, you will receive a 'Not Entitled' error and no data will be returned. In Desktop API and Server API, if you request a security with a specific pricing source and if there is not pricing available on the specified source, Bloomberg systems will hunt through a list of preferred sources to find pricing and return that pricing to you. Note that the logic described above only applies to Corporate, Government, and Preferred securities. To find what pricing sources are available for a security, load the security then type PCS<GO> on your Bloomberg. This will also tell you what your preferences for pricing source are for that class of securities. If a pricing is not listed on this screen, then it is not available through the Bloomberg API.
6.1.3 Fields
Some requests (for example, ReferenceDataRequest or HistoricalDataRequest) as well as subscriptions require you to specify which fields from the Bloomberg data model you wish to receive. When using the Reference Data Service you can specify fields using either the field mnemonic or the CALCRT ID. Returned values have the same name (field mnemonic or CALCRT ID) specified in the request. However, when creating subscriptions you will only receive the mnemonic, even if you are passing the CALCRT ID. Therefore, you will want to use the mnemonic for subscriptions. You can retrieve information about available fields programmatically using the Bloomberg API Field Information Service ("//blp/apiflds") or you can use FLDS<GO> on your BLOOMBERG PROFESSIONAL service.
6.1.4 Overrides
You can use overrides to change the basis on which Bloomberg calculates a derived field. You can use this facility to perform "what if?" analysis. For example, override the bid price of a bond (PX_BID) and request the bid yield to maturity (YLD_YTM_BID) based on the value you supplied for the bid price. You can retrieve information about which fields react when a particular field is overridden programmatically by using the Bloomberg API Field Information Service, "//blp/apiflds", or you can use FLDS<GO> on your BLOOMBERG PROFESSIONAL service.
6 Core Services
54
You can specify up to 100 overrides in a single request. The overrides are specified in the request as an array of name/value pairs. The value you supply is always represented as a string. If the override field requires:
A date, then the format is <YYYY><MM><DD>, where <YYYY> is a 4-digit year, <MM> is a 2-digit month and <DD> is a 2-digit day. Therefore, August 4, 2010 would be specified as 20100804. A decimal value, then you must always use a "." (period) character as the decimal separator regardless of any preferences you may have set in your operating system.
Syntax
The syntax of the Relative Date is:
[A][+/-nCU]
where [A] is the Anchor Date (details below) and [+/-nCU] is the Offset from the Anchor Date (details below). Both parts are optional and the date is the result of applying the specified Offset to the specified Anchor.
If the Anchor Date is omitted then the current date is used. If the Offset is omitted then no offset is applied to the Anchor.
In the Offset, +/- defines the direction of the offset, n is a non-negative integer multiplier, C is a Calendar Type, and U is a Period Unit. The integer multiplier in the Offset is optional
Anchor
You may specify the Anchor portion in any of the following formats
<YYYY><MM><DD> format. The valid range is from 19000101 to 99991231.
The symbol ED is only valid in a start date and represents the supplied end date anchor. The symbol SD is only valid in an end date and represents the supplied start date anchor.
<C><U><n><YYYY>, where: <C> represents the calendar type, which can be either C (calendar) or F (fiscal). <U> represents the period unit, which can be either Q (quarterly), S (semiannually) or Y (yearly).
6 Core Services
55
<n> represents a valid integer value for the specified period unit. So, for Quarterly, <n> must be either 1, 2, 3, or 4. For Semi-annually, <n> must be
<YYYY> represents the year. The valid range is from 1900 to 9999.
Offset
If you supply an offset it must always be in the form <+|->[n]<C><U>, where:
The first character is always a plus (+) or minus (-) sign to indicate the direction of the offset from the Anchor date. The second character (<n>) is an optional multiplier. It must be between 0 and 32767 and the default if it is not specified is 0. The third character, <C> is either A (actual), C (calendar) or F (fiscal).
For Actual or Calendar types the fourth character, <U> is either D (daily), W (weekly), M (monthly), Q (quarterly), S (semi-annually), or Y (yearly). For Fiscal calendar types the fourth character, <U>, is either Q (quarterly), S (semi-annually) or Y (yearly).
If you use the Actual calendar type, the offset is applied precisely with no "rounding". For example, +2AW from a Tuesday will result in the Tuesday two weeks hence. +1AM from the 16th will result in the 16th of the following month. If you use the Calendar or Fiscal calendar types, the resulting date is rounded down to the last active date of the previous period. For example, +1CW from a Tuesday will result in the Friday of the same week, +1CM from the 16th will result in the last active day of that month, +CM from the 16th will result in the last active day of the previous month. If the multiplier is not specified and defaults to 0 the resulting date will be the same as the Anchor if the Actual calendar type is used. If the Anchor is Calendar or Fiscal calendar type then the resulting date will be the end of the prior period.
Examples
20080409 represents 9 April 2008. CQ42007 represents 31 December 2007 20080409-1AM represents 9 March 2008 - exactly one month previous to the anchor. 20080409-1CM represents 29 February 2008 - the end of the month prior to 9 March
2008. A start date of 20080409-3CM and an end date of 20080409-CM will provide a range that covers the three calendar months prior to the anchor date of 9 April 2008 (that is, January, February and March).
-3CQ evaluated on 23 June 2008 represents 29 June 2007 (because 30 June 2007
was a Saturday). A start date of 20080409-2AQ and an end date of SD+1AD represents a range from 9 October 2007 to 10 April 2008 (Note that the SD refers only to the Anchor part of the start date not the result after adding the offset to the Anchor).
6 Core Services
56
Reference Data Request A Reference Data Request provides a snapshot of the current value of a security/ field pair.
Historical End-of-Day Data A Historical Data Request provides end-of-day data over a defined period of time for a security/field pair.
Historical Intraday Ticks An Intraday Tick Request provides each tick over a defined period of time for a security and event type pair.
Historical Intraday Bars An Intraday Bar Request provides a series of intraday summaries over a defined period of time for a security and event type pair.
Portfolio Data Request The Portfolio Data Request enables retrieval of change information and portfolio positions with respect to a specific date in order to see how current market movements have affected user's portfolio's constituent weights.
BEQS (Bloomberg Equity Screening) Request BEQS (Bloomberg Equity Screening) request returns security data for a selected screen created using the Bloomberg EQS <GO> function.
Service refDataService = session.getService("//blp/refdata"); Request request = refDataService.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("securities", "/cusip/912828GM6@BGN"); request.append("fields", "PX_LAST"); request.append("fields", "DS002"); d_cid = session.sendRequest(request, null);
6 Core Services
57
Response Overview
A PARTIAL_RESPONSE or RESPONSE message will be returned. For large requests, a PARTIAL_RESPONSE will be provided returning part of the information. A RESPONSE message indicates the request has been fully served. Further information is available in Appendix A Schemas. This example shows how to process a ReferenceDataResponse:.
private void processReferenceDataResponse(Message msg) throws Exception { Element securityDataArray = msg.getElement("securityData"); for (int i = 0; i < securityDataArray.numValues(); ++i) { Element securityData = securityDataArray.getValueAsElement(i); System.out.println(securityData.getElementAsString("security")); Element fieldData = securityData.getElement("fieldData"); for (int j = 0; j < fieldData.numElements(); ++j) { Element field = fieldData.getElementAt(j); System.out.println(field.name() + " = " + field.getValueAsString()); } System.out.println("\n"); } }
Service refDataService = session.getService("//blp/refdata"); Request request = refDataService.createRequest("HistoricalDataRequest"); request.append("securities", "IBM US Equity"); request.append("securities", "MSFT US Equity"); request.append("fields", "PX_LAST"); request.append("fields", "OPEN"); request.set("startDate", "20100101"); request.set("endDate", "20101231"); request.set("periodicitySelection", "MONTHLY");
6 Core Services
58
Response Overview
A successful HistoricalDataResponse holds information on a single security. It contains a HistoricalDataTable with one HistoricalDataRow for each interval returned.
private void processHistoricalDataResponse(Message msg) throws Exception { Element securityData = msg.getElement("securityData"); Element fieldDataArray = securityData.getElement("fieldData"); for (int j = 0; j < fieldDataArray.numValues(); ++j) { Element fieldData = fieldDataArray.getValueAsElement(j); for (int k = 0; k < fieldData.numElements(); ++k) { Element field = fieldData.getElementAt(k); System.out.println("\t" + field.name() + " = " + field.getValueAsString()); } } }
Response Overview
A successful IntradayTickResponse will contain an array of IntradayTickData providing information on each tick in the specified time range. The time taken to respond to this request
6 Core Services
59
is influenced by the date and time range of your request and the level of market activity during that period.
private void processIntradayTickResponse(Message msg) throws Exception { Element data = msg.getElement("tickData").getElement("tickData"); int numItems = data.numValues(); for (int i = 0; i < numItems; ++i) { Element item = data.getValueAsElement(i); Datetime time = item.getElementAsDate("time"); String type = item.getElementAsString("type"); double value = item.getElementAsFloat64("value"); int size = item.getElementAsInt32("size"); String cc; if (item.hasElement("conditionCodes")) { cc = item.getElementAsString("conditionCodes"); }
Process values
} }
6 Core Services
60
Response Overview
A successful IntradayBarResponse will contain an array of BarTickData each of which contains open, high, low, close, number of events and volume values. Further information is available in Appendix A Schemas. This example shows how to interpret an IntradayBarResponse.
private void processIntradayBarResponse(Message msg) throws Exception { Element data = msg.getElement("barData").getElement("barTickData"); int numBars = data.numValues(); for (int i Element Datetime double double double double int long Process } } = 0; i < numBars; ++i) { bar = data.getValueAsElement(i); time = bar.getElementAsDate("time"); open = bar.getElementAsFloat64("open"); high = bar.getElementAsFloat64("high"); low = bar.getElementAsFloat64("low"); close = bar.getElementAsFloat64("close"); numEvents = bar.getElementAsInt32("numEvents"); volume = bar.getElementAsInt64("volume"); values
Response Overview
A PARTIAL_RESPONSE or RESPONSE message will be returned. For large requests a PARTIAL_RESPONSE will be provided returning part of the information. A RESPONSE message indicates the request has been fully served. Further information is available in Appendix A Schemas.
6 Core Services
61
Response Overview
A PARTIAL_RESPONSE or RESPONSE message will be returned. For large requests a PARTIAL_RESPONSE will be provided returning part of the information. A RESPONSE message indicates the request has been fully served. Further information is available in Appendix A Schemas.
Response Overview
Once a subscription is established, the stream will supply messages in SUBSCRIPTION_DATA events. The initial message returned, known as a "SUMMARY" message, will contain a value for all the fields specified in the subscription. Subsequent messages may contain values for some or all of the requested Bloomberg fields. It is possible that a message contains none of the requested Bloomberg fields as the messages are only filtered based on the fields they could contain rather than the fields they actually contain and many fields in the streaming events are optional. The Bloomberg API will ensure all messages that contain any of the fields you have explicitly subscribed for are pushed to your application. Finally the stream may return additional fields in these messages, for which were not included in the subscription. These additional fields are not filtered for the purpose of speed, and their inclusion is subject to change at any time. Some of the fields that are returned also have a null state. For example the fields BID and ASK have values of type float and usually give positive values that you can use to populate your own caches. However there are times when these fields will be set to a null value. In the case of BID and ASK fields this is usually interpreted as an instruction to clear the values in your caches. Therefore it is important to test to see if the field is null before you try and retrieve a value from it. This example shows how to subscribe for streaming data.
Assume that session already exists and the "//blp/mktdata" service has been successfully opened.
SubscriptionList subscriptions = new SubscriptionList(); subscriptions.add("IBM US Equity", "LAST_PRICE,BID,ASK", ""); subscriptions.add("/cusip/912828GM6@BGN", LAST_PRICE,BID,ASK,BID_YIELD,ASK_YIELD", ""); session.susbcribe (subscriptions);
6 Core Services
62
SubscriptionList subscriptions = new SubscriptionList(); subscriptions.add("//blp/mktvwap/ticker/IBM US Equity" + "?VWAP_START_TIME=10:00&VWAP_END_TIME=16:00", "LAST_PRICE,BID,ASK", ""); session.susbcribe(subscriptions);
Response Behavior
The response will return a message containing a selection of VWAP fields.
"//blp/mktbar/isin/GB00B16GWD56 LN"
The only field that can be submitted for this service is LAST_PRICE. The following code snippet shows a subscription to market bars: .
Assume that the blp/mktbar service has already been opened successfully. SubscriptionList d_subscriptions = new SubscriptionList(); d_subscriptions.add("//blp/mktbar/ticker/VOD LN Equity","LAST_PRICE", "interval=5",CorrelationId(1)); d_session.subscribe(d_subscriptions);
Response Behavior
There are three types of messages that can occur in a SUBSCRIPTION_DATA event. The first event received is MarketBarStart, this occurs at every new bar; therefore the frequency of this will depend upon the interval setting. A MarketBarStart will return all fields (A.4 Market Bar Subscription on page 190). Subsequently, on every last price update a MarketBarUpdate will be sent. This will only include fields that have updated since the bar
6 Core Services
63
start or last update. Fields that are always updated are VOLUME, NUMBER_OF_TICKS, TIME and CLOSE. MarketBarEnd only occurs when the last market bar has been received - i.e., the end_time has been reached. This message only contains TIME. Please note there is no initial summary returned for streaming intraday bars, a reference data request or a subscription will be required to get an initial snapshot if required. When a market bar subscription is set to return delayed data, the market bar start message will not be returned until the delayed period has passed.
Field Information Request A Field Information Request provides a description on the specified fields in the request.
Field Search Request A Field Information Request provides the ability to search the Bloomberg data model with a search string for field mnemonics.
Categorized Field Search Request A Categorized Field Search Request provides the ability to search the Bloomberg data model based on categories with a search string for field mnemonics.
6 Core Services
64
Response Behavior
A successful FieldResponse will contain an array of FieldData. The FieldData contains the field's unique id and information about the field. This example shows how to process a single FieldResponse.
private void processFieldResponse(Message msg) throws Exception { Element fieldDataArray = msg.getElement("fieldData"); for (int i = 0; i < fieldDataArray.numValues(); ++i) { Element fieldData = fieldDataArray.getValueAsElement(i); Element fieldInfo = fieldData.getElement("fieldInfo"); System.out.println( fieldData.getElementAsString("id") + " " + fieldInfo.getElementAsString("mnemonic") + " (" + fieldInfo.getElementAsString("description") + ") " + fieldInfo.getElementAsString("datatype")); } }
Response Behavior
A FieldSearchRequest returns a FieldResponse just as a FieldInfoRequest does.
6 Core Services
65
Detailed information on these settings is located in Appendix A Schemas. This example shows how to construct a CategorizedFieldSearchRequest.
Service fieldInfoService = session.getService("//blp/apiflds"); Request request = fieldInfoService.createRequest( "CategorizedFieldSearchRequest"); request.set("searchSpec", "last price");
Response Behavior
A successful CategorizedFieldResponse will contain an array of CategoryData that contains a flattened representation of the matching fields arranged by the category tree. This example shows how to process a single CategorizedFieldResponse.
private void processCategorizedFieldResponse(Message msg) throws Exception { Element categoryArray = msg.getElement("category"); for (int i = 0; i < categoryArray.numValues(); ++i) { Element categoryData = categoryArray.getValueAsElement(i); System.out.println( "Category:" + categoryData.getElementAsString("categoryName")); Element fieldDataArray = categoryData.getElement("fieldData"); for (int j = 0; j < fieldDataArray.numValues(); ++j) { Element fieldData = fieldDataArray.getValueAsElement(i); Element fieldInfo = fieldData.getElement("fieldInfo"); System.out.println( fieldData.getElementAsString("id") + " " + fieldInfo.getElementAsString("mnemonic") + " (" + fieldInfo.getElementAsString("description") + ") " + fieldInfo.getElementAsString("datatype")); } } } }
6 Core Services
66
0708/012/0001
where: 0708 is the GPGX number 012 is the monitor number 0001 is the page number An array of strings is used to specify the rows on the page that are of interest. These can be specified as individual rows, multiple rows separated by commas, or ranges of rows, as follows:
String
"1 "1,2,3 "1,6-10,15,16"
Rows Specified
The first row on the page Rows 1,2 and 3 on the page Row 1, rows 6 to 10 and rows 15 and 16
The following example shows how to create a subscription, and demonstrates how the subscription fields are used to pass the rows the user wants to subscribe to.
String topic = "0708/012/0001" List<string> fields = new List<string>(); fields.Add("15-18"); // subscribing to rows 15 to 18 subscriptions.Add(new Subscription("//blp/pagedata/" + topic, fields, null, new CorrelationID(topic)));
Response Behaviour
Once a subscription has been created, and the subscription status messages have been processed, two event types might be received: PageUpdate A PageUpdate event contains a current view of the entire page. It provides the dimensions of the page, followed by a rowUpdate element for each row on the page. A full page update will
6 Core Services
67
be received first (all the rows on the page), regardless of the requested rows, and acts as an initial paint of the page, prior to receiving ongoing updates.
PageUpdate = { numRows = 23 numCols = 80 rowUpdate[] = { rowUpdate = { rowNum = 1 spanUpdate[] = { spanUpdate = { startCol = 1 length = 80 text = attr[] = { } fgColor = DARKBLUE bgColor = WHITE } } } . . . rowUpdate = { rowNum = 23 spanUpdate[] = { spanUpdate = { startCol = 1 length = 80 text = attr[] = { } fgColor = WHITE bgColor = DARKBLUE } } } } }
RowUpdate A RowUpdate event consists of a row number, and one or more spanUpdate elements. Each spanUpdate element describes the location and size of the data (startCol, length), the data itself (text), any attributes associated with that piece of data, and the foreground and background colors. The RowUpdate event is structured in exactly the same way as the rowUpdate element of the PageUpdate event.
6 Core Services
68
RowUpdate = { rowNum = 15 spanUpdate[] = { spanUpdate = { startCol = 61 length = 1 text = 9 attr[] = { } fgColor = WHITE bgColor = DARKBLUE } } }
6 Core Services
69
Description
Historical End of Day Intraday End-of-day data for a specified period of time in increments of days, weeks, months, quarters, or years. Intraday data for a specified period of time in increments of minutes. Based on Bid, Ask, or Trade events, data such as open, high, low, close, and volume can be retrieved for the interval of time specified. Real-time data and events.
Real-time
6 Core Services
70
monthly, bi-annually and annually. Each Historical study request can submit only a single instrument.
Service tasvcService = session.GetService("//blp/tasvc"); Request request = tasvcService.CreateRequest("studyRequest"); // set security name request.GetElement("priceSource"). GetElement("securityName").SetValue("IBM US Equity"); // set historical price data request.GetElement("priceSource"). GetElement("dataRange").SetChoice("historical"); Element historicalEle = request.GetElement("priceSource"). GetElement("dataRange").GetElement("historical"); historicalEle.GetElement("startDate").SetValue("20100501"); // set study start date historicalEle.GetElement("endDate").SetValue("20100528"); // set study end date // DMI study example - set study attributes request.GetElement("studyAttributes").SetChoice("dmiStudyAttributes"); Element dmiStudyEle = request.GetElement("studyAttributes"). GetElement("dmiStudyAttributes"); dmiStudyEle.GetElement("period").SetValue(15); // DMI study interval // set historical data price sources for study dmiStudyEle.GetElement("priceSourceLow").SetValue("PX_LOW"); dmiStudyEle.GetElement("priceSourceClose").SetValue("PX_LAST");
Response Behaviour
A successful studyResponse holds information on the requested security. It contains a studyDataTable with one studyDataRow for each interval returned.
6 Core Services
71
private void processResponseEvent(Message msg) { Element security = msg.GetElement(SECURITY_NAME); string ticker = security.GetValueAsString(); System.Console.WriteLine("\nTicker: " + ticker); if (security.HasElement("securityError")) { printErrorInfo("\tSECURITY FAILED: ", security.GetElement(SECURITY_ERROR)); continue; } Element fields = msg.GetElement(STUDY_DATA); if (fields.NumValues > 0) { int numValues = fields.NumValues; for (int j = 0; j < numValues; ++j) { Element field = fields.GetValueAsElement(j); for (int k = 0; k < field.NumElements; k++) { Element element = field.GetElement(k); System.Console.WriteLine("\t" + element.Name + " = " + element.GetValueAsString()); } System.Console.WriteLine(""); } } }
6 Core Services
72
Service tasvcService = session.GetService("//blp/tasvc"); Request request = tasvcService.CreateRequest("studyRequest"); // set security name request.GetElement("priceSource"). GetElement("securityName").SetValue("IBM US Equity"); Element intradayEle = request.GetElement("priceSource"). GetElement("dataRange").GetElement("intraday"); // set intraday price data intradayEle.GetElement ("eventType").SetValue("TRADE"); // intraday event type intradayEle.GetElement("interval").SetValue(60); // intraday interval intradayEle.GetElement("startDate").SetValue("2010-05-26T13:30:00"); // set study start date intradayEle.GetElement("endDate").SetValue("2010-05-27T13:30:00"); // set study end date // smavg study example - set study attributes request.GetElement("studyAttributes").SetChoice("smavgStudyAttributes") ; Element smavgStudyEle = request.GetElement("studyAttributes"). GetElement("smavgStudyAttributes"); smavgStudyEle.GetElement("period").SetValue(15); // SMAVG study interval smavgStudyEle.GetElement("priceSourceClose").SetValue("close");
Response Behaviour
A successful studyResponse holds information on the requested security. It contains a studyDataTable with one studyDataRow for each bar interval returned.
6 Core Services
73
private void processResponseEvent(Message msg) { Element security = msg.GetElement(SECURITY_NAME); string ticker = security.GetValueAsString(); System.Console.WriteLine("\nTicker: " + ticker); if (security.HasElement("securityError")) { printErrorInfo("\tSECURITY FAILED: ", security.GetElement(SECURITY_ERROR)); continue; } Element fields = msg.GetElement(STUDY_DATA); if (fields.NumValues > 0) { int numValues = fields.NumValues; for (int j = 0; j < numValues; ++j) { Element field = fields.GetValueAsElement(j); for (int k = 0; k < field.NumElements; k++) { Element element = field.GetElement(k); System.Console.WriteLine("\t" + element.Name + " = " + element.GetValueAsString()); } } } }
6 Core Services
74
Response Behaviour
Once a subscription is established, the stream will supply messages in SUBSCRIPTION_DATA events. Apart from study field subscribed, you may receive additional study fields in these messages which were not subscribed. These additional fields are not filtered for the purpose of speed and their inclusion is subject to change at any time.
Response Behaviour
The response message indicates a pass or fail.
6 Core Services
75
Authentication
Who is the consumer?
Authorization
What data is the consumer entitled to see?
Permissioning
The process of enforcing data distribution to only entitled consumer.
76
Authentication in Bloomberg's data products for Bloomberg users is performed by identifying a user as being logged into the Terminal. The Terminal's use of a biometric device will have already proven the identity of the logged in user. Please note that the Terminal is not a requirement for Managed B-PIPE's non-BPS (Market Data) users or applications.
User mode
When user mode permissioning is used, an Identity is passed as a parameter when sending a request. This means that all data returned will be already permissioned for that Identity, but is only for distribution to that particular user or application represented by the Identity.
Content based
When content based permissioning is used, the entitlement identifiers (EIDs) of incoming pieces of data is taken and the data is only distributed to users whose Identity contains the same EIDs as the data.
77
2.
A Bloomberg user's authorization remains valid until that user logs out from Bloomberg Professional service and logs in from another host. At that time, your application will receive an event of type AUTHORIZATION_STATUS, containing a message of type AuthorizationRevoked. This is the only time that an Identity must be re-established. Simply logging out or logging back in from the same host will not invalidate a user's authorization.
3. 4. 5.
User Authorization is needed when the session is destroyed or when the authorization is revoked. If any entitlements change for the user, the existing Identity object is automaticaly updated by Bloombergs infrastructure and SDK. Failiure to observe these practices will result in exceeding the maximum authorizations limit for a user, thereby resulting in further authorizations failing with error code MAX_AUTHORIZATIONS_EXCEEDED.
78
Figure 7-1: Server API: User Mode: Authorization by IP Address When the customer application has a Server Mode deployment, the authorization request is submitted by the customer server application using values obtained by the end-user applications by some customer defined protocol.
79
Figure 7-2: Server API: Server Mode: Authorization by IP Address The above diagram does not show the subordinate customer application that will be receiving the Bloomberg data. That application must report its users UUID and IP address to the customer application using the Server API. The customer application developer must define the protocol for transferring that information. To authorize a UUID/IP address pair, open "//blp/apiauth", the authorization service, and send an authorization request. The following code fragment shows how to create such a request and one method for blocking until receipt of the corresponding response.
80
<Java> int uuid = ; // Obtain UUID for user of interest. String ipAddress = ; // Obtain IP address for user of interest. Create and start 'session'. if (!session.openService("//blp/apiauth")) { System.out.println("Could not open service " + "//blp/apiauth"); System.exit(1); } Service apiAuthSvc = session.getService("//blp/apiauth"); Request authorizationRequest = apiAuthSvc.createAuthorizationRequest(); authorizationRequest.set("uuid", uuid); authorizationRequest.set("ipAddress", ipAddress); Identity identity = session.createIdentity(); CorrelationID authorizationRequestID = new CorrelationID(10); session.sendAuthorizationRequest(authorizationRequest, identity, authorizationRequestID); System.out.println("sent Authorization Request using ipAddress"); // Wait for 'AuthorizationSuccess' message which indicates // that 'identity' can be used.
81
for (boolean continueToLoop = true; continueToLoop; ) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: if (!handleAuthenticationResponseEvent(event)) { System.out.println("Authorization Failed"); System.exit(1); } continueToLoop = false; break; default: handleOtherEvent(event); break; } }
The helper" method, handleAuthenticationResponseEvent, examines the received messages for one of type "AuthorizationSuccess", "AuthorizationFailure", etc.
<Java> static private boolean handleAuthenticationResponseEvent(Event event) throws IOException { if (hasMessageType(event, "AuthorizationSuccess")) { System.out.println("Authorization OK"); return true; } else if (hasMessageType(event, "AuthorizationFailure")) { System.out.println("Authorization Problem"); dumpEvent(event); } else { System.out.println("Authorization: Other Problem"); dumpEvent(event); } return false; }
82
sent Authorization Request using ipAddress EventType=SESSION_STATUS correlationID=null messageType=SessionStarted SessionStarted = { } EventType=SERVICE_STATUS correlationID=Internal: 1 messageType=ServiceOpened ServiceOpened = { } Authorization OK
Successful authorization loads identity with information (i.e., entitlement data) later used in the Permissioning phase. However, if incorrect data is given, say an incorrect IP address, the output is:
sent Authorization Request using ipAddress EventType=SESSION_STATUS correlationID=null messageType=SessionStarted SessionStarted = { } EventType=SERVICE_STATUS correlationID=Internal: 1 messageType=ServiceOpened ServiceOpened = { } Authorization Problem eventType=RESPONSE messageType=AuthorizationFailure CorrelationID=User: 10 AuthorizationFailure = { reason = { code = 102 message = User not logged on to the Bloomberg Professional Service category = NO_AUTH subcategory = NOT_LOGGED_IN source = [nydsmeter1] } } Authorization Failed
83
"Authentication" of identity. This can be by user and/or by application "Authorization" which is the process of obtaining the entitlements of the authenticated user and/or application
84
Figure 7-3 shows the procedure for the user authorization system. It is important to note that the "authentication" section of the diagram MUST be performed on the user's desktop machine. The "authorization" section can be performed on the server-side application or on the user's desktop, depending on the application. For an application authorization system, the OS_LOGIN or DIRECTORY_SERVICE request is replaced with one for the Application Name as defined on EMRS and this can be run on any machine. For a combined application and user authorization system both the user authentication and the application authentication occurs in a single call and this must be run on the user desktop machine.
7.4.1 Authentication
The first stage of authentication is creating an Authentication Options string. This is attached to the SessionOptions object and thus passed into the session when it is created.
For a User
A user's identity can be authenticated by the user's Window's logon identity or a value from the Active Directory (e.g., email address) associated with the login. The correct authentication value for each user is made known to the Bloomberg Data Center using the EMRS<GO> function. The client application specifies this choice using the setAuthenticationOptions method of the SessionOptions class. Note that neither option requires the user to input or even be aware of the value that is used for authentication. The two options are OS_LOGON and DIRECTORY_SERVICE. An example of their use is as follows:
"mail" is the property name to lookup under Active Directory rather than the value itself. The libraries will obtain the value from Active Directory using this property name for the currently logged in user. A code example demonstrating the use of these can be found below in Token Generation.
For an Application
An application "authenticates" in much the same way as a user. However, instead of using Active Directory or a Logon, an application name is used as defined in EMRS <GO>.
85
Rather than using OS_LOGON and DIRECTORY_SERVICE with the AuthenticationType parameter of the authentication options string, we introduce two new parameters; AuthenticationMode and ApplicationAuthentication. AuthenticationMode will take the value APPLICATION_ONLY and ApplicationAuthentication will take the value APPNAME_AND_KEY. Finally we use the parameter ApplicationName. The value for this parameter will be the value stored on EMRS for that application.
"AuthenticationMode=APPLICATION_ONLY;
ApplicationAuthenticationType=APPNAME_AND_KEY; ApplicationName=TestApplication"
The above code snippet can be inserted in the following code example to generate a token for an application registered on EMRS as "TestApplication". After the token is generated, it should then be used to generate an Identity in the same way that a user has an identity created using a token.
86
There is one last possible value for AuthenticationMode: USER_AND_APPLICATION. This allows use of the AuthenticationType parameter with OS_LOGON and DIRECTORY_SERVICE alongside the AuthenticationMode, ApplicationAuthenticationType, and ApplicationName parameters.
const char *authenticationOptions = "AuthenticationMode=USER_AND_APPLICATION; ApplicationAuthenticationType=APPNAME_AND_KEY; ApplicationName=TestApplication; AuthenticationType=OS_LOGON"
Typically this will be used for authorizing specific users for specific applications and will return the intersection of the entitlements of the application and the user.
87
part of the session options, the call to session.generateToken will submit a token generation request.
<C++> // ManagedBpipeAuthorization.cpp using namespace BloombergLP; using namespace blpapi; const char *authenticationOptions = useLogon ? "AuthenticationType=OS_LOGON" : "AuthenticationType=DIRECTORY_SERVICE;DirSvcProperty=mail"; SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); //default sessionOptions.setServerPort(8194); //default sessionOptions.setAuthenticationOptions(authenticationOptions); Session session(sessionOptions); if (!session.start()) { std::cerr << "Failed to start session" << std::endl; return 1; } CorrelationId tokenGenerationId(99); EventQueue tokenEventQueue; session.generateToken(tokenGenerationId, &tokenEventQueue); std::string token; Event tokenEvent = tokenEventQueue.nextEvent(); // blocking
88
for (MessageIterator messageIterator(tokenEvent); messageIterator.next(); ) { Message message = messageIterator.message(); if (TOKEN_FAILURE == message.messageType()) { std::cerr << "Failed to obtain token" << std::endl; return 1; } assert(TOKEN_SUCCESS == message.messageType()); token.assign(message.getElementAsString("token")); break; } authorization stage
The token is a long alphanumeric string that has a limited lifespan for validity and needs to be used in an Authorization request before it expires.
7.5 Authorization
For Managed B-PIPE Authorization, the client application must set as an attribute of the Authorization request the token obtained during Authentication. Then, as in the other cases, an "AuthorizationFailure" message indicates failure (with details) and an "AuthorizationSuccess" message indicates that the identity has been set with the user's or application's entitlements. The Identity is then used in the same way as it would be in Permissioning in Server API. Please note that for an application that has been named in EMRS, all requests for data must have the Identity passed with it, so that only the securities that the application is entitled for are accessible rather than everything associated with the Managed B-PIPE.
89
<C++> authentication stage const char *authorizationServicePath = "//blp/apiauth"; if (!session.openService(authorizationServicePath)) { std::cerr << "Failed to open " << authorizationServicePath << std::endl; return 1; } Service authorizationService = session.getService(authorizationServicePath); Identity identity = session.createIdentity(); Request authorizationRequest = authorizationService.createAuthorizationRequest(); authorizationRequest.set("token", token.c_str()); CorrelationId authorizationRequestId(98); EventQueue authorizationEventQueue; session.sendAuthorizationRequest(authorizationRequest, &identity, authorizationRequestId, &authorizationEventQueue); Event authorizationEvent = authorizationEventQueue.nextEvent(); for (MessageIterator messageIterator(authorizationEvent); messageIterator.next(); ) { Message message = messageIterator.message(); if (AUTHORIZATION_FAILURE == message.messageType()) std::cerr << "Failed authorization" << std::endl; return 1; } assert(AUTHORIZATION_SUCCESS == message.messageType()); break; } rest of client application
90
7.6 Permissioning
7.6.1 Entitlements
Entitlement Identifiers (EIDs) are numeric values associated with data provided by Bloomberg. The following table contains some EID examples:
Table 1: EID
14005 INTC UQ Equitya
b
Description
NASDAQ Level 1 BGN U.S. Treasures London Stock Exchange Level 1 & 2
Source
NASDAQ Bloomberg Generic Merrill Lynch LSE
Examples
MSFT UQ Equity, CT2@BGN Govt CT2@ML Govt VOD LN Equity
a. In the example above, MSFT UQ Equity and INTC UQ Equity are both NASDAQ Level 1, and have the same EID. b. There can be cases where there are no entitlements associated with the associated instrument. In such cases the data is to be considered free for all BBA users. Bloomberg Generic Pricing has no EID and is therefore, free for all Bloomberg users. c. In the example above, we show that separate EIDs are used to represent London Stock Exchange Level 1 and Level 2.
The user's EIDs (in the first row, above) are returned in the AuthorizationResponse and are held in an "Identity". Each Message contained in a SUBSCRIPTION_DATA, PARTIAL_RESPONSE or RESPONSE Event may contain an EID field. Note that for reference data, EIDs are currently assigned at the instrument level, not at the field level. However, for subscription data, EIDs are currently assigned at the instrument and field level. The following code fragments show how the entitlements loaded into the Identity during the authorization stage and can be used to check a user's eligibility to receive given data.
91
First, the data request must be modified to request that entitlement identifiers be included with the returned data. For example:
<Java> Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "VOD LN Equity"); request.append("fields", "PX_LAST"); request.append("fields", "DS002"); request.append("fields", "VWAP_VOLUME"); request.set("returnEids", true); // new CorrelationID requestID = new CorrelationID(20); session.sendRequest(request, requestID);
92
Then, the handler for the resulting events can be modified to use the identity acquired during authorization:
<Java> private static void handleResponseEvent(Event event, Identity identity) throws IOException { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); Element ReferenceDataResponse = message.asElement(); if (ReferenceDataResponse.hasElement("responseError")) { handle error } Element securityDataArray = ReferenceDataResponse.getElement("securityData"); int numItems = securityDataArray.numValues(); for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.getValueAsElement(i); String security = securityData.getElementAsString("security"); int sequenceNumber = securityData.getElementAsInt32("sequenceNumber"); if (securityData.hasElement("securityError")) { handle error } ArrayList missingEntitlements = new ArrayList(); Element neededEntitlements = securityData.hasElement("eidData") ? securityData.getElement("eidData") : null; if (null == neededEntitlements) { forward data to the user } else if (identity.hasEntitlements(neededEntitlements, message.service(), missingEntitlements)) { forward data to the user } else {
93
In this example, data is forwarded to a user who has the entitlements for the security, or if the security has no entitlements.
94
For example,
<Java> create and open 'session' Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "VOD LN Equity"); request.append("fields", "PX_LAST"); request.append("fields", "DS002"); request.append("fields", "VWAP_VOLUME"); request.set("returnEids", true);
When the response arrives, the customer application must check that EID against the entitlements of a user before actually delivering the data to that user. A user's entitlements can be checked by using the hasEntitlements method of the Identity object.
<Java> Extract 'securityData' from response message ArrayList missingEntitlements = new ArrayList(); Element neededEntitlements = securityData.hasElement("eidData") ? securityData.getElement("eidData") : null; if (null == neededEntitlements) { forward data to the user } else if (identity.hasEntitlements(neededEntitlements, message.service(), missingEntitlements)) { forward data to the user } else { do not forward data to the user }
Of course, using this strategy, some requests may be satisfied and other rejected.
95
7.7.1 Single-User
Single-User applications are Desktop applications that take a user identity which has been authorized using the USER_AND_APPLICATION authorization mode. This is used in a User Mode style and results are passed directly back to the specific user.
7.7.2 Multi-User
Multi-User applications are typically Client-Server (N-tier, etc.) architectures and can either follow the user mode or content-based permissioning models. User Identities would be again created using the USER_AND_APPLICATION authorization mode (which also checks to see if the user is entitled to use that application according to records on EMRS). The application could then either send the user identities with separate requests and correlation IDs to get data for individual users, or it can use its own Identity (created just for the application) to request data (the application Identity is the parameter to the request or subscription function). EIDs could be extracted from the returned data and thus can be used in a Server-mode style by distributing to entitled users.
96
In the C API this involved using the bb_connect_server_user call which set the entire application as tied to that user. All requests would be processed using that user's entitlements and settings. .NET used configuration files (or XmlNode objects) with the ServerApiLicense node to determine the credentials of the user on whose behalf the application was to connect. After MarketDataAdapter.Startup() was called, all requests would have been serviced as that user. V3 avoids the issue of having to dedicate the entire program to a single user and instead allows multiple users in the same application by using Identities as parameters to requests and subscriptions. The same distribution restrictions as pre-V3 still apply, data downloaded on behalf of a single user cannot be distributed to another user.
7.8.2 All-or-None
All-or-none permissioning simply compared the set of entitlements of a user against the set of entitlements of the server. If the user had all of the entitlements of the server then that user was permitted to receive any data from the server without further checks. Pre-V3 provided calls to check this. The C API used the bb_get_authorization function to check this. If any EIDs were returned then that user did not match the Server on those EIDs and thus would have to be denied access to all data from the server application. The .NET API used the LicenseManager.GetRestrictions call. If it returned EIDs then the user had to be denied access to all data. V3 removes support for all-or-none systems as these are not considered to be flexible enough. In addition problems were caused by entitlements sometimes being applied to users non-homogenously.
97
98
8 Publishing
8.1 Overview
The Bloomberg API allows customer applications to publish data as well as consume it. Customer data can be published for distribution within the customers enterprise, contributed to the Bloomberg infrastructure, distributed to others, or used for warehousing. Publishing applications might simply broadcast data or they can be interactive, responding to feedback from the infrastructure about the currently active subscriptions from data consumers. This chapter will illustrate both paradigms.
Creating a session. Obtaining authorization. Creating the topic. Publishing events for the topic to the designated service.
Session.
8 Publishing
99
// BroadcastOneTopic.cpp int main() { SessionOptions sessionOptions; sessionOptions.setServerHost("platform"); sessionOptions.setServerPort(8195); sessionOptions.setAuthenticationOptions("AuthenticationType=OS_LOGON"); MyEventHandler myEventHandler; ProviderSession session(sessionOptions, &myEventHandler, 0); if (!session.start()) { std::cerr <<"Failed to start session." << std::endl; return 1; } }
The event handler plays no significant role in this example and will not be examined.
8.3.2 Authorization
The authorization stage, if successful, provides a valid Identity object which is required for later operations. Authorization is done by the "//blp/apiauth" service on receipt of an authorization request. See for Authorization and Permissioning Systems on page 76 details.
8 Publishing
100
Name TOKEN("token"); Name TOKEN_SUCCESS("TokenGenerationSuccess"); Name TOKEN_FAILURE("TokenGenerationFailure"); Name AUTHORIZATION_SUCCESS("AuthorizationSuccess"); EventQueue tokenEventQueue; session.generateToken(CorrelationId(), &tokenEventQueue); std::string token; Event event = tokenEventQueue.nextEvent(); if (event.eventType() == Event::TOKEN_STATUS) { MessageIterator iter(event); while (iter.next()) { Message msg = iter.message(); msg.print(std::cout); if (msg.messageType() == TOKEN_SUCCESS) { token = msg.getElementAsString(TOKEN); } else if (msg.messageType() == TOKEN_FAILURE) { break; } } } if (token.length() == 0) { std::cout << "Failed to get token" << std::endl; } session.openService("//blp/apiauth"); Service authService = session.getService("//blp/apiauth"); Request authRequest = authService.createAuthorizationRequest(); authRequest.set(TOKEN, token.c_str()); EventQueue authQueue; Identity providerIdentity = session.createIdentity(); session.sendAuthorizationRequest( authRequest, &providerIdentity, CorrelationId(), &authQueue);
8 Publishing
101
else if (event.eventType() == EventType.RESPONSE || event.eventType() == EventType.PARTIAL_RESPONSE || event.eventType() == EventType.REQUEST_STATUS) { for (Message msg: event) { if (msg.correlationID().equals(d_authorizationResponseCorrelationId)) { Object authorizationResponseMonitor = msg.correlationID().object(); synchronized (authorizationResponseMonitor) { if (msg.messageType() == AUTHORIZATION_SUCCESS) { d_authorizationResponse = Boolean.TRUE; authorizationResponseMonitor.notifyAll(); } else if (msg.messageType() == AUTHORIZATION_FAILURE) { d_authorizationResponse = Boolean.FALSE; System.err.println("Not authorized: " + msg.getElement("reason")); } else { assert d_authorizationResponse == Boolean.TRUE; System.out.println("Permissions updated"); } } } } }
8 Publishing
102
const std::string myService = "//blp/test"; const std::string myTopic = "testtopic"; TopicList topicList; topicList.add((myService + "/ticker/" + myTopic).c_str(), CorrelationId((long long)1)); session.createTopics( &topicList, ProviderSession::AUTO_REGISTER_SERVICES, providerIdentity); Topic topic; for (size_t i = 0; i < topicList.size(); ++i) { if (topicList.statusAt(i) == TopicList::CREATED) { topic = session.getTopic(topicList.messageAt(i)); } }
8.3.4 Publishing
In this example, data is published by sending events to the designated service, "//blp/test". Event objects are obtained from the service and populated with the topic and the application specific data. In this simple example, each event contains a single data message; however, in general, each event can contain multiple messages. In this simple example, the data is just an integer value that is incremented and published every ten seconds.
8 Publishing
103
Name messageType ("MyMessageType"); Name fieldType ("MyFieldType"); Service service = session.getService(myService.c_str()); for (int value = 1; true; ++value, sleep(10)) { Event event = service.createPublishEvent(); EventFormatter eventFormatter(event); eventFormatter.appendMessage(messageType, topic); eventFormatter.setElement(fieldName, value); session.publish(event); } session.stop(); return 0; }
Note: The standard C library 'sleep' function is used above. The argument specifies the number of seconds to sleep.
Creating a session. Obtaining authorization. Registering for subscription start and stop messages. Handling subscription start and stop events, which add and remove topics to the active publication set. Creating a topic. Publishing events for the active topics of the designated service.
The details for creating a session, obtaining a provider identity, and authorization are the same as in the earlier example; they will not be detailed again. This design requires the management of a collection of "active" topics for publication. That collection will be populated (and depopulated) by event handling threads and accessed for
8 Publishing
104
periodic publication by the main thread. A map will be used to store pairs of topic/CUSIP pairs (keyed on topic). The topics are provided in the start and stop messages, and CUSIPs are obtained by requesting resolution of the received topics. The multiple threads of this application must not concurrently access the collection; STL containers are not thread-safe in that respect. Since there is only one "reading" thread in this application, a simple mutex suffices. A pthread mutex was chosen because it is familiar to many readers.
// InteractivePublisher.cpp int main(int argc, char **argv) { Publications activePublications; pthread_mutex_t activePublicationsMutex; pthread_mutex_init(&activePublicationsMutex, NULL); MyEventHandler myEventHandler(&activePublications, &activePublicationsMutex); SessionOptions sessionOptions; sessionOptions.setServerHost("192.168.9.155"); sessionOptions.setServerPort(8195); //sessionOptions.setAuthenticationOptions("AuthenticationType=OS_LOGON"); sessionOptions.setAuthenticationOptions("AuthenticationMode=APPLICATION_ONLY; ApplicationAuthenticationType=APPNAME_AND_KEY;ApplicationName=blp:APP_BBOX"); ProviderSession session(sessionOptions, &myEventHandler, 0); if (!session.start()) { std::cerr << "Failed to start session." << std::endl; return -1; }
As we will see later, the event handler is designed to hold pointers to the collection of active topics and to the mutex that manages access to that collection.
8.4.1 Registration
On completion of service registration, the application can expect subscription start and subscription stop messages in the context of subscription status events.
8 Publishing
105
create activePublication collection, the managing mutex, and the event handler create session and obtain Identity const char *myService = "//blp/mktdata8"; if (!session.registerService(myService, providerIdentity)) { std::cerr <<"Failed to register " << myService << std::endl; return -1; } }
8 Publishing
106
bool MyEventHandler::processEvent(const Event& event, ProviderSession* session) { switch (event.eventType()) { case Event::TOPIC_STATUS: { TopicList topicList; MessageIterator iter(event); while (iter.next()) { Message msg = iter.message(); std::cout << msg << std::endl; if (msg.messageType() == TOPIC_SUBSCRIBED) { Topic topic; try { topic = session->getTopic(msg); } catch (blpapi::Exception &) { } if (!topic.isValid()) { topicList.add(msg); } else if (d_actPub_p->find(topic) == d_actPub_p->end()) { std::string topicStr = msg.getElementAsString("topic"); pthread_mutex_lock(d_actMutex_p); PublicationItem publicationItem(topic, topicStr); d_actPub_p->insert(publicationItem); pthread_mutex_unlock(d_actMutex_p); } } else if (msg.messageType() == TOPIC_UNSUBSCRIBED) { Topic topic; try { topic = session->getTopic(msg); pthread_mutex_lock(d_actMutex_p); Publications::iterator it = d_actPub_p->find(topic); if (it != d_actPub_p->end()) { d_actPub_p->erase(it); } pthread_mutex_unlock(d_actMutex_p); } catch (blpapi::Exception &) { } }
8 Publishing
107
else if (msg.messageType() == TOPIC_CREATED) { try { Topic topic = session->getTopic(msg); std::string topicStr = msg.getElementAsString("topic"); pthread_mutex_lock(d_actMutex_p); PublicationItem publicationItem(topic, topicStr); d_actPub_p->insert(publicationItem); pthread_mutex_unlock(d_actMutex_p); } catch (blpapi::Exception &e) { std::cerr << "Exception in Session::getTopic(): " << e.description() << std::endl; continue; } } } if (topicList.size()) { session->createTopicsAsync(topicList); } } break; default: printMessages(event); } return true; }
8.4.3 Publication
The publication loop in this example is, in many ways, similar to that used in the first example. There is a value that is incremented every ten seconds and is used to create an event for publication.
8 Publishing
108
Service service = session.getService(myService); Name messageType("MyMessageType"); Name fieldName("MyFieldName"); for (int value = 1; true; ++ value, sleep(10)) { pthread_mutex_lock(&activePublicationsMutex); if (0 == activePublications.size()) { continue; } Event event = service.createPublishEvent(); EventFormatter eventFormatter(event); for (Publications::iterator iter = activePublications.begin(); iter != activePublications.end(); ++iter) { const std::string& cusip = iter->second; eventFormatter.appendMessage(messageType, iter->first); eventFormatter.setElement(fieldName, myValueFor(cusip, value)); } pthread_mutex_unlock(&activePublicationsMutex); session.publish(event); } session.stop(); return 0; }
Note: The standard C library 'sleep' function is used above. The argument specifies the number of seconds to sleep. However, there are some differences (highlighted above):
Rather than a single fixed topic, publication is made for all of the topics in the collection of active publications. Note that the mutex is acquired before iterating over that collection. There is at most one published event per cycle. Each event may have multiple messages, each with data for a specific topic. Although sending an empty event would not be harmful, if the collection of active publications is empty, no event is published for that cycle. The published data might vary by topic. Details of the myValueFor function are not important and, therefore, not shown.
8 Publishing
109
9 Managed B-Pipe
9.1 Overview
In addition to the core set of services available to licensed users of the Desktop API and Server API products, there is an additional set of services that are offered only to Managed BPipe users. The primary purpose of this section is to provide the depth of knowledge required to understanding and utilizing these services in your Bloomberg API application. They are as follows:
Market Depth Service (//blp/mktdepth) Market List Service (//blp/mktlist) Source Reference Service (//blp/srcref)
For information on the core set of services available to Managed B-Pipe users, please see Core Services on page 52.
Important Notice
Field filtering is available as a configuration option, which means that Managed B-Pipe clients have the option to change their configurations so that only the fields specified in a subscription are returned. As a result, clients should be able to recognize significant bandwidth savings on their Client LAN. Contact Bloomberg support to have this feature enabled on your Bloomberg Appliance.
Many times exchanges consider order book (level 2) information a separate product from its level 1 data and charge additional fees for access to it. In these cases the level 2 data will have a different EID than the level 1 data. Order books have three characteristics that define them: The number of rows in the book (window size), the type of the order book and the method used to update the book. There are two types of order books, Market-By-Order (MBO) and Market-By-Level (MBL). An exchange may provide only MBL data, only MBO data or both MBO and MBL data. There are three order book update methods, Replace-By-Level (RBL), Add-Mod-Delete (AMD) and Replace-By-Broker (RBB).
Mnemonic
BEST_BID1 thru BEST_BID10 BEST_BID1_SZ thru BEST_BID10_SZ BEST_ASK1 thru BEST_ASK10 BEST_ASK1_SZ thru BEST_ASK10_SZ
Description
First thru tenth best bid price in ten levels of market depth Size of first thru tenth best bid in ten levels of market depth First thru tenth best ask price in ten levels of market depth Size of first thru tenth best ask in ten levels of market depth
For further information regarding making a subscription, please read the Subscriptions on page 45. Keep in mind that this method of obtaining market depth through the //blp/mktdata service is limited to receiving only aggregated Market By Level data for up to 10 levels. This service doesn't allow you to obtain "Market By Order" (MBO) data. Also, the //blp/mktdata service doesn't provide you with information such as the book type or the action performed on that position. Therefore, if you wish to receive more than 10 levels of market depth by level (MBL) or any market depth by order (MBO) levels, then you will be required to use the //blp/mktdepth
9 Managed B-Pipe
111
service. Subscribing to this comprehensive service will not only supply you with the order book in its entirety, but also provide you with the book type, action performed, etc.
Code Examples
You will find two separate examples in the Managed B-Pipe SDK for C++, Java and .NET. They are as follows:
MarketDepthSubscriptionExample This example demonstrates how to make a simple Market Depth subscription for one, or more, securities and display all of the messages to std::cout.
MarketDepthSubscriptionSnapshotExample This example demonstrates how to build and update an order and level book. It is comprised of a LevelBook and OrderBook class, which handle the Market Depth By Level and By Order messages, respectively, based upon the returned MD_TABLE_CMD_RT value, and then the main classes which perform the subscription, general message handling and output tasks.
Market-by-Level (MBL)
MBL order books show only one row for each price. If multiple brokers have bids or asks in at the same price the size of all the brokers orders will be summed and be displayed. Optionally, the number of brokers at that level may also be provided. The type of an order book is independent of the method used to maintain the order book.
9 Managed B-Pipe
112
Add-Mod-Del (AMD)
The second order book method is Add-Mod-Delete (AMD). It is used for both MBO and MBL types of order books. The AMD method is much more efficient in sending updates to order books. Instead of addressing each row in the book individually only the changes to the book are sent. This means that client applications must manage any related updates resulting from an Add or Delete event. For instance, when a new price is inserted at a specific row, the only message sent is the insert. It is the application's responsibility to adjust the position of all the rows that have been shifted down. Likewise, when a row is deleted, it is the application's responsibility to shift all the prices that were below it up. Of course any new price at the bottom of the book requires a separate "Insert", but this is much more efficient than resending the whole book. The downside of the AMD method is that it depends on receiving and correctly processing every update to keep the book accurate. With the RBL method a missed message will result in the specific row being wrong. But this condition is corrected the next time that row is updated. Because a single AMD message can affect a single row, one missed message can result in the order book being wrong for the rest of the day or until a recap is sent. Because of this, AMD messages are sent using sequence numbers. If the application detects a gap in the sequence numbers it can recover from the error by re-requesting the entire order book. In other words, resubscribe to the book. If the gap is detected as a result of an issue within the Bloomberg Data Center, Bloomberg will send down an order recap. This form of gap dectection is covered in a later section.
9 Managed B-Pipe
113
Replace-by-Broker (RBB)
The third order book method is Replace-By-Broker (RBB). Because it addresses specific broker entries, it is used only for MBO order books. It is a mix of the RBL and AMD methods. It is similar to the RBL method in that each broker's entry is individually addressed. It is similar to the AMD method in that a single update affects the entire book. However, unlike the AMD method, a missed message results in an order book that is wrong only until the next update for that broker. Both the RBL and AMD methods specify specific row numbers to identify each entry. The RBB method does not use row numbers. Instead the broker code is used to identify the entry. How RBB order books are sorted is left up to the feed handler. The general rule is to use the price as the primary sort key. The secondary sort key can either be the sequence the orders at the same price were received or an alphabetic listing of all the brokers at the same price.
Key Field
Bloomberg Symbol Ticker BSID Bloomberg Unique ID SEDOL CUSIP ISIN Parsekeyable
Format
//blp/mktdepth/bsym/source/symbol //blp/mktdepth/ticker/symbol //blp/mktdepth/bsid/bsid //blp/mktdepth/buid/source/identifier //blp/mktdepth/sedol/source/identifier //blp/mktdepth/cusip/source/identifier //blp/mktdepth/isin/source/identifier //blp/mktdepth/bpkbl/identifier
Example
//blp/mktdepth/bsym/LN/VOD?type=MBL //blp/mktdepth/bsym/US/AAPL?type=MBO //blp/mktdepth/ticker/ESM2 Index?type=MBL //blp/mktdepth/bsid/399432473346?type=MBO //blp/mktdepth/buid/US/EQ0010080100001000?type=MBL //blp/mktdepth/sedol/US/2005973?type=MBL //blp/mktdepth/cusip/US/459200101?type=MBL //blp/mktdepth/isin/US/US4592001014?type=MBL //blp/mktdepth/bpkbl/QCZ1 Index?type=MBL
The following code snippet demonstrates how to subscribe for streaming (MBL) market depth data and assumes that a session already exists and that the "//blp/mktdepth" service has been successfully opened.
const char *security = "//blp/mktdepth/isin/US/US4592001014?type=MBL"; SubscriptionList subscriptions; subscriptions.add(security, CorrelationId((char *)security)); session.susbcribe (subscriptions);
Figure 9-1: C++ code snippet: Subscribing for streaming (MBL) market depth data
9 Managed B-Pipe
114
Response Overview
The Market Depth response will be a series of SUBSCRIPTION_DATA events, which you will already be familiar with if you have developed Bloomberg API applications using any of the other streaming services, such as //blp/mktdata or //blp/mktvwap. A SUBSCRIPTION_DATA event message will be of type MarketDepthUpdates, and within each message there will be a MKTDEPTH_EVENT_TYPE and MKTDEPTH_EVENT_SUBTYPE field, along with, possibly, an array of MBO_TABLE_ASK/ MBO_TABLE_BID items (for MBO subscription) or MBL_TABLE_ASK/MBL_TABLE_BID (for MBL subscriptions). The MKTDEPTH_EVENT_TYPE will indicate whether the message is Market by Level (value= MARKET_BY_LEVEL) or Market by Order (value = MARKET_BY_ORDER). Here are the possible values for each MKTDEPTH_EVENT_SUBTYPE:
MKTDEPTH_EVENT_SUBTYPE
Notes This is the Initial Paint message for your subscription When this message is received, it is an indicator to you to clear the book cache and add the rows contained in the message. This message will contain the FEED_SOURCE, ID_BB_SEC_NUM_SRC (a.k.a. BSID) and MD_BOOK_TYPE. No other messages will contain this information, so it is required that you assign a unique correlation identifier to each one of your subscriptions in order to map the message updates to the initial request. For AMD and RBL book types, there will be a WINDOW_SIZE field/ value pairing, which indicates the number of levels in the book, as position is the key to the book. However, this field will not be contained in the MBO-RBB initial paint, as the key for this book is the broker.
TABLE_INITPAINT
This indicates a bid quote message This indicates an ask quote message In the event of a loss of connectivity upstream, the Bloomberg infrastructure will automatically recover (RECAP) and send BID_RETRANS and ASK_RETRANS events. Upon receipt of these messages, you will receive a CLEARALL message with a MKTDEPTH_EVENT_SUBTYPE of RETRANS and you should consider your book in a bad state and accept the recovery. Please note that the sequence numbers will be set to zero during the recap. See BID_RETRANS description above
ASK_RETRANS
Within each TABLE_INITPAINT message you will find one MD_TABLE_CMD_RT field/value pairing for the entire initial paint and then individual MD_TABLE_CMD_RT field/value pairings for each MBL_TABLE_ASK/MBO_TABLE_ASK/ MBL_TABLE_BID/MBO_TABLE_ BID that may be present. Thereafter, you will see on MD_TABLE_CMD field/value pairing for each BID or ASK MKTDEPTH_EVENT_SUBTYPE tick update.
9 Managed B-Pipe
115
The possible string values, which indicate what action should be taken in response to the market depth event, are listed in the table below.
Name
UNASSIGNED ADD
Value
0 1
Description
The default constant 'UNASSIGNED' is used to initialize all enumeration type fields Add an entry to the order book. When you add this order in the market depth table, you should shift all orders at the market depth position in the event and market depth orders or levels inferior to event passed to one position inferior. For example, if a new order is added to position one of the market depth table, then the previous order at position one is shifted to position two. The order at position two is shifted to position three and so on until you get to the market depth window size. If the ADD results in Bid or ASK sides to have more levels than the value configured in MB[LO]_WINDOW_SIZE, the last level in the corresponding side should be dropped. It will be up to you to cache MB[LO]_WINDOW_SIZE from the Initial paint event to handle this scenario. Delete this event from the market depth cache. The delete should occur at the position passed in the market depth event. When cached market event at the position passed in the delete is removed, all position inferior should have their positions shifted by one. For example, if position one is deleted from a market by order or market by price event, the position two becomes one, position three becomes two, etc. Delete all events from the cache. This is a market depth flush usually passed at the start or end of trading or when a trading halt occurs. Delete this order and any superior orders. The order ID at the next inferior position is now the best order. This differs from the EXEC command in that it deletes the current order, where the EXEC command modifies the current order. Delete all events on the corresponding side (bid/ask) of the order book. Trade Execution. Find the corresponding order in the cache, replace event details with this event and then delete any prior superior orders. Modify an existing event in the market depth cache. Find the cached market depth event by the position in the new market depth event and replace the cached event by the fields and data in the new event. Replace previous price level or order at this position. Add price level or order if you do not have it currently in the cache. A zero (0) price and size will be sent when there is no active price or order at this level.
DEL
DELALL
DELBETTER
DELSIDE EXEC
5 7
MOD
REPLACE
10
9 Managed B-Pipe
116
Name
REPLACE_BY_BROKER
Value
11
Description
This table command is used for top of file feeds where the action is to replace by the broker mnemonic. The recipient needs to find the broker in their cache and replace the quote with the one in the market depth event. If that broker is not present, it should be added to the cache. If the price and size for a broker is set to 0, the broker should be deleted from the cache. Clears the entire orderbook for the specified side. This market depth table command is issued by Bloomberg when market depth recovery is occurring. This table command has the same effect on the cache as DELETEALL which means all order or levels should be cleared from the cache. During LVC recovery you will generally see 2 CLEARALLs - 1 for Bid side and 1 for Ask side. Should the client of market depth need to process a recovery of market depth differently, this table command allows the user to differentiate from the source/exchange produced DELETEALL. The REPLACE_CLEAR table command is intended to remove an order or more often a level in the market depth cache. The REPLACE_CLEAR should be indexed by the MarketDepth.ByLevel/ByOrder.Bid/Ask.Position field. The cache should NOT be shifted up after the level is cleared. A clear means all orders at that position have been deleted from the order book. It is possible that an order or level at a superior or most superior position to be cleared prior to more inferior levels. After the level is cleared in this case, it is expected that subsequent market depth event(s) will be passed to clear the orders or levels at positions inferior to the one just cleared.
CLEARALL
12
REPLACE_CLEAR
13
The other important enumeration value is found in the Book Type (MD_BOOK_TYPE) field and is only included in the initial paint message. Here is a complete table covers all three book types and their possible table command enumeration values.
Book Type (MD_BOOK_TYPE) MBO[L]-AMD Initial Paint Table Command (MD_TABLE_CMD_RT) ADD Table Commands in Real-Time Messages (MD_TABLE_CMD_RT) CLEARALL, ADD, MOD, DELETE (* not in use are DELSIDE, DELBETTER) CLEARALL, REPLACE, REPLACE_CLEAR REPLACE_BY_BROKER, REPLACE_CLEAR
MBO[L]-RBL MBO-RBB
REPLACE REPLACE_BY_BROKER
The following code snippet demonstrates how to handle and print out a MarketDepth subscription to std::cout. This C++ snippet is based on the aforementioned "MarketDepthSubscriptionExample" C++ SDK example. For a more complete example that demonstrates how to handle and build an order/level book, please reference the
9 Managed B-Pipe
117
Figure 9-2: Handling a market depth data update (C++) You will notice that the above code checks the EventType being returned and looks for SUBSCRIPTION_DATA. Please note that the processSubscriptionStatus() and processMiscEvents() functions were not shown for brevity. You will also notice that the event handler for the tick updates is identical to that of a //blp/mktdata subscription, for instance.
value of FRAGMENT_START and a last message of FRAGMENT_END. If the TABLE_INITPAINT is split into more than 2 parts, all middle Fragments will be of type FRAGMENT_INTERMEDIATE. This enum will exist in both MARKET_BY_ORDER and MARKET_BY_LEVEL messages.
The following code snippet demonstrates how the C++ "MarketDepthSubscriptionSnapshotExample" example checks the fragment type. Please take a look at the full code example in the SDK for a working version of this code.
if (subType == TABLE_INITPAINT) { if (msg.fragmentType() == BloombergLP::blpapi::Message::Fragment::FRAGMENT_START || msg.fragmentType() == BloombergLP::blpapi::Message::Fragment::FRAGMENT_NONE) { if (msg.hasElement(MBO_WINDOW_SIZE, true) ){ d_orderBooks[Side::ASKSIDE].window_size = (unsigned int) msg.getElementAsInt64(MBO_WINDOW_SIZE); d_orderBooks[Side::BIDSIDE].window_size = d_orderBooks[Side::ASKSIDE].window_size; } d_orderBooks[Side::ASKSIDE].book_type = msg.getElementAsString(MD_BOOK_TYPE); d_orderBooks[Side::BIDSIDE].book_type = d_orderBooks[Side::ASKSIDE].book_type; // clear cache d_orderBooks[Side::ASKSIDE].doClearAll(); d_orderBooks[Side::BIDSIDE].doClearAll(); } }
Figure 9-3: Checking for the Fragment Type (C++) The above code checks the Market Depth Event Sub-Type being returned, and if it equals TABLE_INITPAINT, then it checks the Fragment Type. If a FRAGMENT_START or FRAGMENT_NONE type is returned by msg.fragmentType(), then the order book is cleared.
9 Managed B-Pipe
119
9 Managed B-Pipe
120
MBO_TABLE_BID[] = { MBO_TABLE_BID = { MBO_BID_POSITION_RT = 1 MBO_BID_RT = 11.3100004196167 MBO_BID_BROKER_RT = " 79" MBO_BID_COND_CODE_RT = "" MBO_ORDER_ID_RT = "32353235000075f8004f" MBO_BID_SIZE_RT = 1400 MBO_TIME_RT = 2012-05-25T19:46:59.000+00:00 MD_TABLE_CMD_RT = ADD } MBO_TABLE_BID = { MBO_BID_POSITION_RT = 2 MBO_BID_RT = 11.3100004196167 MBO_BID_BROKER_RT = " 79" MBO_BID_COND_CODE_RT = "" MBO_ORDER_ID_RT = "323532350000761a004f" MBO_BID_SIZE_RT = 500 MBO_TIME_RT = 2012-05-25T19:47:33.000+00:00 MD_TABLE_CMD_RT = ADD } (more) } Processing SUBSCRIPTION_DATA MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_ORDER MKTDEPTH_EVENT_SUBTYPE = ASK EID = 14184 MD_TABLE_CMD_RT = DEL MBO_SEQNUM_RT = 199951 MBO_ASK_POSITION_RT = 7 MBO_ASK_RT = 11.3199996948242 MBO_ASK_BROKER_RT = " 79" MBO_ASK_COND_CODE_RT = "" MBO_ORDER_ID_RT = "323532350000774e004f" MBO_ASK_SIZE_RT = 500 MBO_TIME_RT = 2012-05-25T19:53:55.000+00:00 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { } MBO_TABLE_BID[] = { } }
9 Managed B-Pipe
121
Processing SUBSCRIPTION_DATA /bsym/CT/RIM - MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_ORDER MKTDEPTH_EVENT_SUBTYPE = TABLE_INITPAINT ID_BB_SEC_NUM_SRC = 502511690826 FEED_SOURCE = "CT" EID = 14184 MD_TABLE_CMD_RT = ADD MD_BOOK_TYPE = MBO-AMD MBO_WINDOW_SIZE = 200 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { MBO_TABLE_ASK = { MBO_ASK_POSITION_RT = 200 MBO_ASK_RT = 12 MBO_ASK_BROKER_RT = " 80" MBO_ASK_COND_CODE_RT = "" MBO_ORDER_ID_RT = "3235313500000c390050" MBO_ASK_SIZE_RT = 100 MBO_TIME_RT = 2012-05-25T15:20:49.000+00:00 MD_TABLE_CMD_RT = ADD } } MBO_TABLE_BID[] = { } }
Notes: The first message above is the initial paint (as indicated by the TABLE_INITPAINT event subtype (i.e., MKTDEPTH_EVENT_SUBTYPE)) and indicates that it is a Market-By-Order message, as indicated by the MARKET_BY_ORDER event type (i.e., MKTDEPTH_EVENT_TYPE). Within the initial paint message, you will find a table of asks and bids. In this case, it is an MBO request, so the table will be of MBO bids and asks (indicated by MBO_TABLE_BID[] and MBO_TABLE_ASK[] array items). When you receive an initial paint message, you should clear your book prior to populating with the table of Asks and Bids. Because this is an AMD (Add-Mod-Del) MBO Book Type, the MD_TABLE_CMD_RT field in the initial paint is ADD. The valid table commands for subsequent AMD type message updates are ADD, MOD, DELETE and CLEARALL.
9 Managed B-Pipe
122
9 Managed B-Pipe
123
MBO_TABLE_BID[] = { MBO_TABLE_BID = { MBO_BID_RT = 514.900146484375 MBO_BID_BROKER_RT = "ADAM" MBO_BID_BROKER_MODE_RT = OPEN MBO_BID_COND_CODE_RT = "" MBO_BID_COND_CODE_SRC_RT = "" MBO_BID_LSRC_RT = "UQ" MBO_BID_SIZE_RT = 100 MBO_TIME_RT = 2012-05-25T13:44:01.000+00:00 MD_TABLE_CMD_RT = REPLACE_BY_BROKER } MBO_TABLE_BID = { MBO_BID_RT = 560.60009765625 MBO_BID_BROKER_RT = "ARCX" MBO_BID_BROKER_MODE_RT = OPEN MBO_BID_COND_CODE_RT = "" MBO_BID_COND_CODE_SRC_RT = "" MBO_BID_LSRC_RT = "UP" MBO_BID_SIZE_RT = 200 MBO_TIME_RT = 2012-05-25T19:24:13.000+00:00 MD_TABLE_CMD_RT = REPLACE_BY_BROKER } (more) } } Processing SUBSCRIPTION_DATA MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_ORDER MKTDEPTH_EVENT_SUBTYPE = BID EID = 14023 MD_TABLE_CMD_RT = REPLACE_BY_BROKER MBO_TIME_RT = 2012-05-25T19:24:14.000+00:00 MBO_BID_RT = 560.56005859375 MBO_BID_BROKER_RT = "NQBX" MBO_BID_BROKER_MODE_RT = OPEN MBO_BID_COND_CODE_RT = "" MBO_BID_COND_CODE_SRC_RT = "" MBO_BID_LSRC_RT = "UB" MBO_BID_SIZE_RT = 100 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { } MBO_TABLE_BID[] = { } }
9 Managed B-Pipe
124
Processing SUBSCRIPTION_DATA MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_ORDER MKTDEPTH_EVENT_SUBTYPE = BID EID = 14023 MD_TABLE_CMD_RT = REPLACE_BY_BROKER MBO_TIME_RT = 2012-05-25T19:24:14.000+00:00 MBO_BID_RT = 560.60009765625 MBO_BID_BROKER_RT = "ARCX" MBO_BID_BROKER_MODE_RT = OPEN MBO_BID_COND_CODE_RT = "" MBO_BID_COND_CODE_SRC_RT = "" MBO_BID_LSRC_RT = "UP" MBO_BID_SIZE_RT = 100 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { } MBO_TABLE_BID[] = { } }
Notes: The first message above is the initial paint (as indicated by the TABLE_INITPAINT event subtype (i.e. MKTDEPTH_EVENT_SUBTYPE)) and indicates that it is a Market-By-Order message, as indicated by the MARKET_BY_ORDER event type (i.e. MKTDEPTH_EVENT_TYPE). Within the initial paint message, you will find a table of asks and bids. In this case, it is an MBO request, so the table will be of MBO bids and asks (indicated by MBO_TABLE_BID[] and MBO_TABLE_ASK[] array items). When you receive an initial paint message, you should clear your book prior to populating with the array of Asks and Bids. Because this is a Request-By-Broker (RBB) MBO Book Type, the MD_TABLE_CMD_RT field in the initial paint and subsequent update is REPLACE_BY_BROKER. The only other valid table command for a RBB type is REPLACE_CLEAR, which is sent by the exchange.
9 Managed B-Pipe
125
9 Managed B-Pipe
126
MBL_TABLE_BID[] = { MBL_TABLE_BID = { MBL_BID_POSITION_RT = 1 MBL_BID_RT = 1314.5 MBL_BID_COND_CODE_RT = "" MBL_BID_NUM_ORDERS_RT = 65 MBL_TIME_RT = 2012-05-25T20:05:13.043+00:00 MBL_BID_SIZE_RT = 427 MD_TABLE_CMD_RT = REPLACE } MBL_TABLE_BID = { MBL_BID_POSITION_RT = 2 MBL_BID_RT = 1314.25 MBL_BID_COND_CODE_RT = "" MBL_BID_NUM_ORDERS_RT = 69 MBL_TIME_RT = 2012-05-25T20:05:11.351+00:00 MBL_BID_SIZE_RT = 631 MD_TABLE_CMD_RT = REPLACE } (more) } } Processing SUBSCRIPTION_DATA MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_LEVEL MKTDEPTH_EVENT_SUBTYPE = ASK EID = 14002 MD_TABLE_CMD_RT = REPLACE MD_MULTI_TICK_UPD_RT = 0 MBL_ASK_POSITION_RT = 2 MBL_ASK_RT = 1315 MBL_ASK_COND_CODE_RT = "" MBL_ASK_NUM_ORDERS_RT = 66 MBL_ASK_SIZE_RT = 398 MBL_TIME_RT = 2012-05-25T20:05:14.085+00:00 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { } MBO_TABLE_BID[] = { } }
9 Managed B-Pipe
127
Processing SUBSCRIPTION_DATA MarketDepthUpdates = { MKTDEPTH_EVENT_TYPE = MARKET_BY_LEVEL MKTDEPTH_EVENT_SUBTYPE = ASK EID = 14002 MD_TABLE_CMD_RT = REPLACE MD_MULTI_TICK_UPD_RT = 0 MBL_ASK_POSITION_RT = 2 MBL_ASK_RT = 1315 MBL_ASK_COND_CODE_RT = "" MBL_ASK_NUM_ORDERS_RT = 65 MBL_ASK_SIZE_RT = 397 MBL_TIME_RT = 2012-05-25T20:05:14.148+00:00 MBL_TABLE_ASK[] = { } MBL_TABLE_BID[] = { } MBO_TABLE_ASK[] = { } MBO_TABLE_BID[] = { } }
Notes: The first message above is the initial paint (as indicated by the TABLE_INITPAINT event subtype (i.e. MKTDEPTH_EVENT_SUBTYPE)) and indicates that it is a Market-By-Level (MBL) message, as indicated by the MARKET_BY_LEVEL event type (i.e. MKTDEPTH_EVENT_TYPE). Within the initial paint message, you will find the MBL_WINDOW_SIZE. This indicates the number of levels in the book, along with the table command (i.e. MD_TABLE_CMD_RT) with a value of "REPLACE" and book type (i.e. MD_BOOK_TYPE) with a value of "MBL-RBL". Because this is a Request-By-Level (RBL) MBL Book Type, the MD_TABLE_CMD_RT field in the initial paint is REPLACE and all subsequent updates will possess a table command of either REPLACE_CLEAR, REPLACE or CLEARALL. This is true for both MBO and MBL event types. The output above includes a sample BID/REPLACE and ASK/ REPLACE_CLEAR message.
9 Managed B-Pipe
128
The MBL_SEQNUM_RT and MBL_SEQNUM_RT fields are sequentially increasing numbers included only in AMD order book market depth messages. They allow the client application to detect gaps in the AMD market depth messages. A sequence number 5 followed by 7 indicates that a gap of one message occurred.
Gap Detection
Data gaps occur as a result of missed network messages. While rare, as in every complex networked system, missed messages can occur at any level and for many reasons. If a data gap occurs between the Managed B-Pipe order book systems and the application, it is the client application's responsibility to take action to restore the order book to an accurate state. If the gap is detected by the Bloomberg upstream order book systems, Managed B-Pipe will automatically initiate the recap without any action by the client application. When Managed B-Pipe detects a gap in the MBL or MBO "AMD" order book, the MD_GAP_DETECTED field is present and set to "true" in every market depth update message for each effected order book. This informs the client application that Managed BPipe has detected the gap and to expect an automatic recap. MD_GAP_DETECTED will not be present once the recap is sent. Therefore, even though a client application detects a gap, if this field is present in market depth update messages, no further action is required by the client application except to begin reading the recap messages, which will follow immediately and be indicated with a MKTDEPTH_EVENT_SUBTYPE of BID_RETRANS and ASK_RETRANS in each message update. In cases where a sequence number gap is detected but the MD_GAP_DETECTED field is not present in the message, it is the responsibility of the client application to request a recap (i.e., resubscribe) to the order book. Table 9-1: Fields Affected by Recaps
Fields
MKTDEPTH_EVENT_SUBTYPE
Descriptions
Present in every market depth message for all styles of orderbook. When an unsolicited recap is in progress, this field will have a value of "BID_RETRANS" or "ASK_RETRANS". Present in every market depth message for AMD, and only AMD, order books. They will have a value of 0 if the message is part of an order book recap, regardless of how initiated. Gap detection does not apply to recaps. The value of these fields in the first non-recap market depth update message following the recap will have a nonzero value which should be used to detect any gaps following the recap. Present in every market depth message, it indicates the action to take for this market depth message. The behavior of this field is unchanged. A value of "DELSIDE" indicates that the appropriate side of the order book (bid or ask) should be cleared of all values. All recaps start with a DELSIDE. All other values should be applied as already documented.
MD_TABLE_CMD_RT
9 Managed B-Pipe
129
Fields
MD_MULTI_TICK_UPD_RT
Descriptions
When present, indicates that a market depth message is one of multiple messages that make up a single update to an order book. A value of 1 indicates that additional market depth messages that are part of the same order book update will follow this message. A value of 0 indicates that this is the last message in the update and that the update is complete. All recaps for every style of order book are sent as multi-tick updates. Multi-tick updates may also be used to send non-recap RBL style order book updates.
9 Managed B-Pipe
130
/secids
<topic type>
/cusip /sedol /isin /bsid /bsym /buid /eid /source /gdco /bpkbl /esym
<topic key>a
The following topic types consist of source and the value of a given identifier separated by the forward slash. <source>/<identifier>
9 Managed B-Pipe
131
Code Examples
You will find two separate examples in the Managed B-Pipe SDK for C++, Java, and .NET. They are as follows:
MarketListSubscriptionExample This example demonstrates how to make a simple Market List "chain" subscription for one, or more, securities and displays all of the messages to the console window.
MarketListSnapshotExample This example demonstrates how to make a Market List "secids" snapshot request and displays the message to the console window.
Now that you have a better understanding as to how a //blp/mktlist subscription or snapshot string is formed, it is now time to use it in your application. The following sections provide further details as to how to subscribe to a chain of instruments and request a Snapshot of a list of members.
9 Managed B-Pipe
132
members, the Bloomberg Data Center is queried for the list of members. This list contains the terminal ticker (ParseKeyable symbol) for each member, which is resolved to an instrument on Managed B-Pipe. It is possible that an index or curve list member is not available on Managed B-Pipe. In this case, the list member will be included in the list, but return only the ParseKeyable symbol. This allows the requestor to contact Bloomberg about getting the missing instrument added to Managed B-Pipe. The default security class of the list members depends on the security class of the underlying instrument specified in the request. The default can be overridden using the optional parameter "secclass". Table 9-3 defines the default security class of the list members for each underlying instrument security class . Table 9-3: Default Security Class of List Members Underlying Security Class Currency Equity Fixed Income Fund Future Root Future Contract Index Option Warrant Curve Default Chain Member Security Class Option Option N/A Option Future Option Members N/A N/A Members
An alternate security class for the returned members is available and can be specified in the subscription string using a parameter. For example, the following chain requests are equivalent because the default member security class is Option: //blp/mktlist/chain/bsym/US/IBM //blp/mktlist/chain/bsym/US/IBM;secclass=Option However, by using a parameter, we can obtain a list of Futures with IBM as the underlying instrument: //blp/mktlist/chain/bsym/US/IBM;secclass=Future In order to further qualify the subscription string, a parameter "source" can be applied. The value of this parameter is assigned by the user or application to limit the amount of returned members to those belonging to the specified source(s) only. More than one value is allowed for this parameter. The "source" can be substituted by a "~". This value can be used when the client assumes that there is only one source for the security and there is no actual need to specify it. If this is
9 Managed B-Pipe
133
the case, the subscription request will be processed successfully, but if the security has more than one source and the request is ambiguous, then the client will receive a SubscriptionFailure response with a NOTUNIQUE description. An example of such a subscription string would be "//blp/mktlist/chain/cusip/~/459200101". Table 9-4: Chain Subservice Examples
Type of Chain List Option Chains Example Subscription String //blp/mktlist/chain/bsym/LN/BP/ //blp/mktlist/chain/bsid/678605350316 //blp/mktlist/chain/buid/LN/EQ0010160500001000 //blp/mktlist/chain/bbid/LN/EQ0010160500001000 //blp/mktlist/chain/bpkbl/BP/LN Equity //blp/mktlist/chain/esym/LN/BP //blp/mktlist/chain/cusip/UN/594918104 //blp/mktlist/chain/isin/LN/GB00B16GWD56 //blp/mktlist/chain/sedol/UN/2588173 Index List Yield Curve GDCO EID List Source List Secids List //blp/mktlist/chain/bsym/FTUK/UKX Index;secclass=Option //blp/mktlist/chain/bpkbl/YCMM0010 Index //blp/mktlist/chain/gdco/broker/id //blp/mktlist/chain/eid/14014 //blp/mktlist/chain/source/UN;secclass=Equity //blp/mktlist/secids/buid/EQ0010160500001000 Topic Typea /bsym /bsid /buid /bbid /bpkbl /esym /cusip /isin /sedol /bsym /bpkbl /gdco /eid /source /buid Topic Keyb /<DX282>/<DY003> /<ID122> /<DX282>/<ID059> /<DX194> /<DX282>/<EX005> /<DX282>/<ID032> /<DX282>/<ID032> /<DX282>/<ID005> /<DX282>/<ID002> /<DX282>/<DY003> /<identifier> /<broker_id>/<mon_id> /<source> /<source> /<source>/<identifier> Refreshesc No No No No No No No No No Daily Daily N/A No No N/A
a.The "//blp/mktlist" service currently does not support the "/ticker" topic type b.The FLDS <GO> identifier associated with the expected key values for that particular topic is listed, where applicable, which can be found on FLDS <GO> on the Bloomberg Professional service c.Denotes whether that particular subscription (based on the <topic type> of the subscription string) will refresh and at what periodicity. For Daily refreshes, this will occur at the start of a new market day.
9 Managed B-Pipe
134
Returns
Returns options on the UKX Index Returns options on the UKX Index traded on source LN SubscriptionFailure: ErrorCode=2; Description=NOTUNIQUE; Category=BAD_SEC Note: NOTUNIQUE is returned because the security has more than one source and the request is ambiguous.
//blp/mktlist/chain/bsid/1086627109973 //blp/mktlist/chain/bsym/US/IBM;secclass=Future //blp/mktlist/chain/bpkbl/YCMM0010 Index //blp/mktlist/chain/eid/38736 //blp/mktlist/chain/bsym/US/HP //blp/mktlist/chain/bsym/DJI/INDU Index //blp/mktlist/chain/bsid/1086627109973 //blp/mktlist/chain/isin/LN/GB00B16GWD56,secclass=Warrant //blp/mktlist/chain/bsym/FTUK/UKX Index;secclass=Index
Options for IBM Equity Returns futures for Equity GBP LIBOR Curve members (Yield Curve) List of all currencies available on EID 38736 Returns a chain of options for the composite equity HP Returns a chain of the members of the index. This resolves to currency (/IT/UBY) so will return an option chain. Returns a chain of warrants for the underlying instrument. Returns a chain of members for the specified index identifier (equivalent to //blp/mktlist/chain/bsym/FTUK/UKX Index) Returns a list of Equities under source UN Returns the list of members for the curve "YCCF0009 Index" This resolves to currency (/IT/UBY) so will return an option chain. Returns a chain of options (equivalent to //blp/mktlist/chain/bsid/399432473346; secclass=Option). Returns a chain of warrants for the underlying instrument. Returns a chain of futures for the underlying instrument
//blp/mktlist/chain/isin/LN/GB00B16GWD56;secclass=Warrant //blp/mktlist/chain/bsym/eNYL/XG1;secclass=Future
The following code snippet demonstrates how to subscribe for streaming market list chain data and assumes that a session already exists and that the "//blp/mktlist" service has been successfully opened.
const char *security = "//blp/mktlist/chain/esym/LN/BP"; SubscriptionList subscriptions; subscriptions.add(security, CorrelationId((char *)security)); session.susbcribe (subscriptions);
9 Managed B-Pipe
135
Response Overview
The Market List response will be a series of SUBSCRIPTION_DATA events, which you will be familiar with if you have developed Bloomberg API applications using any of the other streaming services, such as //blp/mktdata, //blp/mktvwap or //blp/mktdepth. A SUBSCRIPTION_DATA event message will either be of type ListRecap or ListData. The initial such event message(s) will be of type ListRecap. These represent the initial paint of your chain of instruments. Within a single ListRecap message, you will find a LIST_LISTTYPE, comprising zero, or more, LIST_INSERT_ENTRIES. If a subscription is made for a chain that does not contain any members, an empty list will be returned. An example of this is requesting the options for an equity that does not have any options. Although, there are no options for the equity, the subscription succeeds and a single ListRecap message will be received with LIST_INSERT_ENTRIES[] showing no elements. If the LIST_MUTABLE field value, from the ListRecap message is equal to 'MUTABLE', then that means there could be ListData items received later on, so you may wish to keep the subscription alive. The newly created members are then added to the previously empty list. However, if the LIST_MUTABLE field is 'IMMUTABLE', then that means it will not return any further updates and you may wish to terminate the subscription by unsubscribing. This is explained further in the following paragraph. Various types of lists are available for a subscription. Though the subscription formats are the same, the lists could be: ORDERED When a list is subscribed and the LIST_ORDERED field within the ListRecap message equals 'ORDERED', the items on the list are returned in ordered format. When a list is subscribed and the LIST_ORDERED field within the ListRecap message equals 'NOTORDERED', the returned list of instruments could be in any order.
UNORDERED
Similarly, a list subscription can be: MUTABLE If the LIST_MUTABLE field within the ListRecap message equals 'MUTABLE', the constituent instruments of a list can change. All subsequent updates will be received as ListData messages. If the LIST_MUTABLE field within the ListRecap message equals 'IMMUTABLE', the list of instruments will never change.
IMMUTABLE
9 Managed B-Pipe
136
Table 9-6: List Actions ListAction Enumerator CLEAR ADD CLEAR_AND_ADD DELETE Description Delete all of the existing list members. This implies there is more data to come Add all of the list members in this set Delete all of the existing list members and then Add all of the list members in this sequence Delete all of the list members in this set. Member Identifiers much match the current Member Identifers exactly This is the last set in the sequence. Delete all of the existing list members, as there are no more entries to follow (i.e. the list is empty) Add all of the list members in this set and end. There are no more entries in this sequence Delete all of the existing list members, add this entry and end. There are no more entries in this sequence. Delete all of the list members in this set. Identifiers much match the current Member Identifiers exactly. Then end, as there are no more entries in this sequence.
9 Managed B-Pipe
137
ListRecap = { LIST_ID = //blp/mktlist/chain/source/TQ EID = 35009 LIST_LISTTYPE = Source List LIST_INSERT_ENTRIES[] = LIST_INSERT_ENTRIES = { ID_BB_SEC_NUM_SRC = 7992941317759 FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = RHI ID_BB_UNIQUE = EQ0000000006685436 SECURITY_TYP2 = Equity } LIST_INSERT_ENTRIES = { ID_BB_SEC_NUM_SRC = 7992941317760 FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = GIL ID_BB_UNIQUE = EQ0000000006687052 SECURITY_TYP2 = Equity } ...MORE... LIST_INSERT_ENTRIES = { ID_BB_SEC_NUM_SRC = 7992961685384 FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = ECONB ID_BB_UNIQUE = EQ0000000023559102 SECURITY_TYP2 = Equity } LIST_INSERT_ENTRIES = { ID_BB_SEC_NUM_SRC = 7992961685385 FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = FIS1V ID_BB_UNIQUE = EQ0000000023561882 SECURITY_TYP2 = Equity } LIST_INSERT_ENTRIES = { ID_BB_SEC_NUM_SRC = 7992961842174 FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = ENQ1 ID_BB_UNIQUE = EQ0000000023716301 SECURITY_TYP2 = Equity } LIST_ORDERED = NOTORDERED LIST_MUTABLE = MUTABLE } ListData = { LIST_ID = //blp/mktlist/chain/source/TQ EID = 35009 LIST_ACTION = ADD_AND_END FEED_SOURCE = TQ ID_BB_SEC_NUM_DES = SNOP }
In the above sample output, a ListRecap message was returned first with a large number of list entries (only the partial recap is shown, however) and a single ListData message, which is
9 Managed B-Pipe
138
an actual update to the subscription. Although, the ListRecap does not possess a LIST_ACTION value, you are to treat such a message as a CLEAR_AND_ADD action. In other words, you will clear your cache and add the entries included in the message. In the ListRecap message, you will notice a few other pieces of information in addition to the entries, such as the LIST_LISTTYPE field (in our case, its value is "Source List", which you will find included in the "TABLE OF SUBSERVICE NAME EXAMPLES" shown earlier in this section), the EID and the LIST_MUTABLE value, which is MUTABLE in this case. This indicates that the constituent instruments of a list can change. After the ListRecap message, you will see one such change to the list, which is returned in the form of a ListData message. This message includes the LIST_ACTION, among other fields. In this case, it is indicating that you will ADD this message to your list at the END (as indicated by ADD_AND_END).
Enumerator
FRAGMENT_NONE FRAGMENT_START FRAGMENT_INTERMEDIATE FRAGMENT_END
Description
Message is not fragmented The first fragmented message Intermediate fragmented messages The last fragmented message
To check for the Fragment Type, you will call the fragmentType property of the Message object (e.g. msg.fragmentType()). Within your application, you will check to see if the fragment type of the ListRecap message is FRAGMENT_NONE or FRAGMENT_START. If one of these are determined, then you will want to clear your list and begin adding the entries included in that part of the ListRecap message. In the case where FRAGMENT_START is determined, then you will know to continue reading the ListRecap messages and adding the entries to your list from those messages until you receive a ListRecap with a fragment type for FRAGMENT_END. At this point, you know you are finished building your list and it is now time to wait for any subsequent ListData updates.
9 Managed B-Pipe
139
Topic Type
/bpkbl /bsid /bsym /buid /cusip /esym /isin /sedol
Topic Key
/<identifier> /<identifier> /<identifier> /<identifier> /<identifier> /<identifier> /<identifier> /<identifier>
FLDS<GO> Field
DX194 and DS587 ID122 DY003 ID059 ID032 EX005->EX011 ID005 ID002
Note: The "//blp/mktlist" service currently does not support the "/ticker" topic type. Market list requests with the secids subservice name are always IMMUTABLE, which means that the returned list of instruments does not receive update messages and must be rerequested to discover any new pricing sources that emerge after the initial request. Table 9-9: Market List Requests with the Secids Subservice Name
Key Field
Bloomberg Unique ID Bloomberg Symbol SEDOL CUSIP ISIN Parsekeyable
Format
//blp/mktlist/secids/buid/uniqueid //blp/mktlist/secids/buid/EQ0010080100001000 //blp/mktlist/secids/bsym/symbol //blp/mktlist/secids/bsym/VOD //blp/mktlist/secids/sedol/sedol //blp/mktlist/secids/sedol/2005973 //blp/mktlist/secids/cusip/cusip //blp/mktlist/secids/cusip/459200101 //blp/mktlist/secids/isin/isin //blp/mktlist/secids/isin/US4592001014 //blp/mktlist/secids/bpkbl/parsekeyable //blp/mktlist/secids/bpkbl/UKX Index
Result
All instrument IDs for the given buid All instrument IDs for the given bsym All instrument IDs for the given SEDOL All instrument IDs for the given CUSIP All instrument IDs for the given ISIN All instrument IDs for the given parsekeyable
9 Managed B-Pipe
140
Table 9-9: Market List Requests with the Secids Subservice Name
Key Field
Message Scraping (MSG1)
Format
//blp/mktlist/secids/bsym/MSGSCRP //blp/mktlist/secids/bsym/MSGSCRP
Result
The list of MSG1 instruments.
A security-based secids request can also be modified to limit the source using the 'source' parameter. This table demonstrates such an instrument with and without the "source" parameter. Table 9-10: SecidsRequests with and without Source Parameter
Subscription String
//blp/mktlist/secids/cusip/459200101 //blp/mktlist/secids/cusip/459200101;source=US
Returns
This example returns all IDs for the given CUSIP. This example returns all IDs for the given CUSIP, but limited to source US.
The following code snippet demonstrates how to request static market list snapshot data and assumes that a session already exists and that the "//blp/mktlist" service has been successfully opened.
const char *security = "//blp/mktlist/secids/cusip/459200101;source=US"; Service mktListService = session.getService("//blp/mktlist"); Request request = mktListService.createRequest("SnapshotRequest"); request.set("security", security);
9 Managed B-Pipe
141
SnapshotRequest = { security = //blp/mktlist/secids/cusip/ 459200101;source=US } LIST_ID = //blp/mktlist/secids/cusip/459200101;source=US EID = 35009 LIST_LISTTYPE = Security IDs LIST_INSERT_ENTRIES ID_BB_SEC_NUM_SRC = 399432473346 FEED_SOURCE = US ID_BB_SEC_NUM_DES = IBM ID_BB_UNIQUE = EQ0010080100001000 SECURITY_TYP2 = Equity LIST_ORDERED = NOTORDERED LIST_MUTABLE = IMMUTABLE
In your application, you will handle the data response the same way, initially, as you would any static request. This is accomplished by checking the event type of the incoming message. If its event type is PARTIAL_RESPONSE, then that indicates that there is at least one more message to be received to fulfill that request. You will continue reading the incoming messages until you receive a RESPONSE event type, which indicates that the request has been fully served. Further information is available in "Appendix A Schemas".
9 Managed B-Pipe
142
Here is a sample event handler written in C++. It was extracted from the "MarketListSnapshotExample" example found in the Managed B-Pipe C++ API SDK, and is the event handler that is responsible for displaying the above output to a console window.
void eventLoop(Session &session) { bool done = false; while (!done) { Event event = session.nextEvent(); if (event.eventType() == Event::PARTIAL_RESPONSE) { std::cout << "Processing Partial Response" << std::endl; processResponseEvent(event); } else if (event.eventType() == Event::RESPONSE) { std::cout << "Processing Response" << std::endl; processResponseEvent(event); done = true; } else { MessageIterator msgIter(event); while (msgIter.next()) { Message msg = msgIter.message(); if (event.eventType() == Event::SESSION_STATUS) { if (msg.messageType() == SESSION_TERMINATED || msg.messageType() == SESSION_STARTUP_FAILURE) { done = true; } } } } } }
9 Managed B-Pipe
143
// return true if processing is completed, false otherwise void processResponseEvent(Event event) { MessageIterator msgIter(event); while (msgIter.next()) { Message msg = msgIter.message(); Element responseCode; if ((msg.asElement().getElement(&responseCode, "responseCode") == 0) && !responseCode.isNull()) { int resultCode = responseCode.getElementAsInt32("resultCode"); if (resultCode > 0) { std::string message = responseCode.getElementAsString("resultCode"); std::string sourceId = responseCode.getElementAsString("sourceId"); std::cout << "Request Failed: "<< message << std::endl; std::cout << "Source ID: " << sourceId << std::endl; std::cout << "Result Code: " << resultCode << std::endl; continue; } } Element snapshot = msg.getElement("snapshot"); size_t numElements = snapshot.numElements(); for (size_t i = 0; i < numElements; ++i) { const Element dataItem = snapshot.getElement(i); // Checking if the data item is Bulk data item if (dataItem.isArray()){ processBulkData(dataItem); }else{ std::cout << "\t" << dataItem.name() << " = " << dataItem.getValueAsString() << std::endl; } } } }
If you examine the response from the example market list request, which is "//blp/mktlist/ secids/cusip/459200101;source=US", you will find that the data is all returned in a single message, which means that the message will have an event type of "RESPONSE". Within that block of code, there is a call to processResponseEvent(). It is here that we first check for the responseCode element. To understand why we are checking for this element, you will first need to understand the structure of the schema for the //blp/mktlist service. Here is a screenshot capturing the sub-elements of the SnapshotRequest/Responses node.
9 Managed B-Pipe
144
If the responseCode is found in the message, then you will check to see if the resultCode is greater than zero. If it is, then this is an indication that there was a problem with the request and that this message contains an error. The details of the error will be provided by the message's resultCode, resultText and sourceId values. If the resultCode equals zero, then data can be expected to be contained within the message. In this case, we will retrieve the snapshot element of the message. You will see in the above processResponseEvent() handler that the number of elements contained in the snapshot are determined by a call to numElements() and then each of those elements are then read into a dataItem variable, of type Element, one at a time. You can check to see if the dataItem is an array by calling its isArray() function. If it returns true, then it is an array containing one, or more, items and must be processed differently than if containing a single item. You will see in the schema screenshot that there are a total of ten possible single field elements and one array element in a snapshot. The array element is indicated by the SEQUENCE type. In our case, the resultCode is zero (i.e. no errors) and there are 6 elements contained in the snapshot element. The first 3 of them are single field elements (e.g. LIST_ID, EID, LIST_LISTTYPE), which means that isArray() returns false for each of them. However, the 4th element, LIST_INSERT_ENTRIES, is an array (a.k.a. SEQUENCE type). This element is then processed in the processBulkData() function. The remaining two elements (LIST_ORDERED and LIST_MUTABLE) are also single field elements.
9 Managed B-Pipe
145
All possible values of FEED_SOURCE for the EID and a short description of the source Whether or not the source is a composite and all the local sources for composites All of the Broker codes and names All condition codes with a short description
where <topic> is comprised of '<topic type>/<topic key>. Table 9-11 provides further details. Table 9-11: Source Reference String Definitions <service owner> <service name> <subservice name> <topic type> <topic key> For Managed B-Pipe is "blp" Source Reference and Tick Size subscription service name is "/srcref" /brokercodes, /conditioncodes, /tradingstatuses or /ticksizes (see Table 9-11.) /eid EID-Number (FEED_EID1 => FEED_EID4)
There are currently four subservices that can be used in your subscription string. Table 9-12: Subservice Definitions
Subservice /brokercodes /conditioncodes Subscription String Format //blp/srcref/brokercodes/eid/<eid> //blp/srcref/conditioncodes/eid/<eid> Description List of all possible broker codes for a specified EID List of Market Depth, Quote, and Trade condition codes for a specified EID List of trading statuses and trading periods for a specified EID. List of Tick Sizes for a specified EID.
/tradingstatuses /ticksizes
//blp/srcref/tradingstatuses/eid/<eid> //blp/srcref/ticksizes/eid/<eid>
9 Managed B-Pipe
146
Filters can be used for /conditioncodes and /tradingstatuses subscription only. Here are the possible filters available for each: Table 9-13: Filters for Events
Filter Name (type)
Subservice Name: /conditioncodes
Subscription String Format //blp/srcref/conditioncodes/eid/<eid>?type=TRADE //blp/srcref/conditioncodes/eid/<eid>?type=QUOTE //blp/srcref/conditioncodes/eid/<eid>?type= MKTDEPTH //blp/srcref/conditioncodes/eid/<eid>?type=TRADE,QUOTE //blp/srcref/conditioncodes/eid/<eid>?type= TRADE,MKTDEPTH //blp/srcref/conditioncodes/eid/<eid>?type= QUOTE,MKTDEPTH //blp/srcref/conditioncodes/eid/<eid>?type= TRADE,QUOTE,MKTDEPTH //blp/srcref/tradingstatuses/eid/<eid>?type=PERIOD //blp/srcref/tradingstatuses/eid/<eid>?type=STATUS //blp/srcref/tradingstatuses/eid/<eid>?type=PERIOD,STATUS
For subscriptions without a filter, users will receive all event types of that subservice name in the initial snapshot, as well as within subsequent daily updates. However, for subscriptions with filters, users will receive all events in the initial snapshot, but only specified events within subsequent daily updates. Important BPOD Upgrade Notes: 1. Managed B-Pipe breaks down the subscriptions into a more granular format. With BPOD, you would have subscribed to "//blp/mktref/srcref/eid/<eid>" to obtain all source references for that EID, which included the broker codes, trade condition codes, quote condition codes, market depth condition codes, period suspense codes, security suspense codes and ticksizes. Now, by using Managed B-Pipe, you can break down these source references into four main subscriptions: "//blp/srcref/ brokercodes/eid/<eid>", "//blp/srcref/conditioncodes/eid/<eid>", "//blp/srcref/ tradingstatuses/eid/<eid>" and "//blp/srcref/ticksizes/eid/<eid>". Managed B-Pipe has introduced filters for some of its subservices to allow you to subscribe to the data you are most interested. With Managed B-Pipe, we return a description message for each subservice's sources. With Managed B-Pipe, Bloomberg now offers intraday updating for tick size changes. If you are looking for the sources on contributor EIDs (or any EID), you should subscribe to //blp/srcref for any of the subservices (i.e. /ticksizes, /brokercode, etc) and the list of descriptions for that source will be included even if the subservice doesn't apply. For example, "//blp/srcref/ticksizes/eid/14240" will return the sources for 14240, but there will not be any ticksizes information.
2. 3. 4. 5.
9 Managed B-Pipe
147
Code Example
You will find a SourceRefSubscriptionExample in the Managed B-Pipe SDK for C++, Java and .NET. This C++ example demonstrates how to make a simple Source Reference subscription for the condition codes associated with EID 14003.
const char *list = "//blp/srcref/conditioncodes/eid/14003"; SubscriptionList subscriptions; subscriptions.add(list, CorrelationId((char *)security)); session.susbcribe (subscriptions);
Figure 9-4: C++ code snippet - subscribing for a list of condition codes for EID 14003
Response Overview
The Source Reference response will be a series of SUBSCRIPTION_DATA events, which you will be familiar with if you have developed Bloomberg API applications using any of the other streaming services, such as //blp/mktdata, //blp/mktlist or //blp/mktdepth. All SUBSCRIPTION_DATA event messages will be of message type SourceReferenceUpdates and will contain a SOURCE_REF_EVENT_TYPE_RT (event type), SOURCE_REF_EVENT_SUBTYPE_RT (event sub-type) and EID field (int32), along with an array of event type field items applicable to the subservice you are subscribing. Table 9-14 lists the possible enumeration values for the event type and event sub-type fields: Table 9-14: Enumeration Values
Name SOURCE_REF_EVENT_TYPE_RT Description This specifies the event type. Values Possible enumeration values: DESCRIPTION BROKER_CODE TRADE_CONDITION_CODE QUOTE_CONDITION_CODE MKTDEPTH_CONDITION_CODE TRADING_PERIOD TRADING_STATUS TICK_SIZE_TABLE SOURCE_REF_EVENT_SUBTYPE_RT This specifies the event sub-type Possible enumeration values: INITPAINT - Initial Paint REFRESH - Daily Refresh* UPDATE - Intraday Update
The subservice name included in your subscription will dictate which event type (SOURCE_REF_EVENT_TYPE_RT) field items will be returned as initial snapshot (INITPAINT) and refresh sub-type messages. Table 9-15 will assist you in determining which
9 Managed B-Pipe
148
a. All subservices will return INITPAINT and REFRESH event messages. However, /ticksizes will also return UPDATE event messages."
For a breakdown of each message returned for your subservice, please see Table 9-16.
BROKER_CODES
SourceReferenceBrokerCodes
TRADE_COND_CODES
SourceReferenceTradeConditionCodes
9 Managed B-Pipe
149
MKTDEPTH_COND_CODES
SourceReferenceMarketDepthConditionCodes
TRADING_PERIODS
SourceReferenceTradingPeriods
TRADING_STATUSES
SourceReferenceTradingStatuses
TICK_SIZE_TABLES
TickSizeTable
As you will see, initial paint messages can be split into one or more smaller messages in the case where the returned data is too large to fit into a single message. It will be up to you to handle this in your application. You will achieve this by checking the Fragment type of any SUBSCRIPTION_DATA event SourceReferenceUpdates message. The Fragment enum is used to indicate whether a message is a fragmented message or not and what position it occurs within the chain of split fragmented messages. If the SourceReferenceUpdates is
9 Managed B-Pipe
150
split into two parts, then the first message will have a Fragment type value of FRAGMENT_START and a last message of FRAGMENT_END. If the SourceReferenceUpdates is split into more than 2 parts, all middle Fragments will be of type FRAGMENT_INTERMEDIATE. Table 9-17: Fragment Type Enumerators
9 Managed B-Pipe
151
*********************************************************************** * DAILY REFRESH *********************************************************************** SourceReferenceUpdates = { SOURCE_REF_EVENT_TYPE_RT = DESCRIPTION SOURCE_REF_EVENT_SUBTYPE_RT = REFRESH EID = 35009 DESCRIPTIONS[] = DESCRIPTIONS = { FEED_SOURCE = LN FEED_EID = 14014 DESCRIPTION[] = DESCRIPTION = { FEED_SOURCE_DES_RT = London Stock Exchange Domestic } } -- MORE -} SourceReferenceUpdates = { SOURCE_REF_EVENT_TYPE_RT = TICK_SIZE_TABLE SOURCE_REF_EVENT_SUBTYPE_RT = REFRESH EID = 35009 TICK_SIZE_TABLES[] = TICK_SIZE_TABLES = { FEED_SOURCE = LN FEED_EID = 14014 TICK_SIZE_TABLE_IDENTIFIER_RT = 5977 TICK_SIZE_TABLE_TYPE_RT = PRICE TICK_SIZE_TABLE_UPDATE_FREQ_RT = DAILY TICK_SIZE_TABLE_FIELD_NAME_RT = LAST_TRADE TICK_SIZE_TABLE_ROW[] = TICK_SIZE_TABLE_ROW = { TICK_SIZE_TABLE_PRICE_TYPE_RT = ABSOLUTE TICK_SIZE_TBL_BAND_TICK_SIZE_RT = 0.000100 TICK_SIZE_TBL_BAND_LOWER_VAL_RT = 0.000100 TICK_SIZE_TBL_BAND_UPPER_VAL_RT = 10.000000 } TICK_SIZE_TABLE_ROW = { TICK_SIZE_TABLE_PRICE_TYPE_RT = ABSOLUTE TICK_SIZE_TBL_BAND_TICK_SIZE_RT = 0.010000 TICK_SIZE_TBL_BAND_LOWER_VAL_RT = 10.000000 TICK_SIZE_TBL_BAND_UPPER_VAL_RT = 100.000000 } } -- MORE -}
9 Managed B-Pipe
152
******************************************************************* * TICKSIZE INTRADAY UPDATE ******************************************************************* SourceReferenceUpdates = { SOURCE_REF_EVENT_TYPE_RT = TICK_SIZE_TABLE SOURCE_REF_EVENT_SUBTYPE_RT = UPDATE EID = 35009 TICK_SIZE_TABLES[] = TICK_SIZE_TABLES = { FEED_SOURCE = LN FEED_EID = 14014 TICK_SIZE_TABLE_IDENTIFIER_RT = 5995 TICK_SIZE_TABLE_TYPE_RT = PRICE TICK_SIZE_TABLE_UPDATE_FREQ_RT = DAILY TICK_SIZE_TABLE_FIELD_NAME_RT = LAST_TRADE TICK_SIZE_TABLE_ROW[] = TICK_SIZE_TABLE_ROW = { TICK_SIZE_TABLE_PRICE_TYPE_RT = ABSOLUTE TICK_SIZE_TBL_BAND_TICK_SIZE_RT = 0.300000 TICK_SIZE_TBL_BAND_LOWER_VAL_RT = 0.250000 TICK_SIZE_TBL_BAND_UPPER_VAL_RT = 100000000.000000 } } -- MORE -}
In the above sample output, a subscription containing the subservice "/ticksizes" was made, which means that you can expect to receive "INITPAINT" and "REFRESH" event types (i.e. SOURCE_REF_EVENT_TYPE_RT) messages containing "DESCRIPTION" and "TICK_SIZE_TABLE" event sub-types (i.e. SOURCE_REF_EVENT_SUBTYPE_RT). In addition to the aforementioned messages, which are standard for all of the subservice requests, you will also receive "UPDATE" event type messages, which are unique to the / ticksizes subservice. However, there will not be an UPDATE "DESCRIPTION" message sent. Taking a look at the sample output above, you will notice that every SourceReferenceUpdates message contains the standard event type, sub-type and EID single-value fields, along with an array of fields applicable for that event type. For instance, in the message containing the event type of "TICK_SIZE_TABLE" you will find an array of "TICK_SIZE_TABLES" fields.
9 Managed B-Pipe
153
A Schemas
A.1 Overview
Each of the following sections provides an overview of the request options and response structure for each request type within each of the Bloomberg API services. A service is defined by a request and a response schema. In the following sections the request schema is broken into tables detailing all options and arguments and example syntax. The response schema is represented graphically.
A.2.1 Operations
Operation Name
HistoricalDataRequest IntraDayTickRequest IntraDayBarRequest ReferenceDataRequest PortfolioDataRequest BeqsRequest
Request Type
HistoricalDataRequest IntraDayTickRequest IntraDayBarRequest ReferenceDataRequest PortfolioDataRequest BeqsRequest
Response Type
HistoricalDataResponse IntraDayTickResponse IntraDayBarResponse ReferenceDataResponse PortfolioDataResponse BeqsResponse
Description
Request Historical Data Request Intraday TIck Data Request Intraday Bar Data Request Reference Data Request Portfolio Data Request EQS Screen Data
A Schemas
154
Fields: the reference fields desired which correspond to data points. See FLDS<GO> for a list of more information. Element fields Element Value Type string Description See Fields on page 54 for additional details.
Example Syntax: Element fields = request.GetElement("fields"); fields.AppendValue("PX_LAST"); Overrides: Append overrides to modify the calculation Element fieldID Element Value Type string Description field mnemonic, PRICING_SOURCE, or field alpha-numeric, PR092. Review FLDS<GO> for list of possible overrides. the desired override value
value
string
Example Syntax: Element overrides = request["overrides"]; Element override1 = overrides.AppendElement(); override1.SetElement("fieldId", "PRICING_SOURCE"); override1.SetElement("value", "CG"); Return Entitlements: returns the entitlement identifiers associated with security. Element returnEids Element Value TRUE or FALSE Type Boolean Description Setting this to true will populate fieldData with an extra element containing a name and value for the EID date.
request.Set("returnEids", true); Element Value TRUE or FALSE Type Boolean Description Setting to true will force all data to be returned as a string.
Return Formatted Value: returns all data as a data type string returnFormattedValue
Example Syntax: request.Set("returnFormattedValue", true); Use UTC Time: return date and time values as Coordinated Universal Time (UTC) values Element useUTCTime Element Value TRUE or FALSE Type Boolean Description Setting to true returns values in UTC. Setting this to false will default to the TZDF<GO> settings of the requestor.
Example Syntax: request.Set("useUTCTime", true); Forced Delay: returns the latest reference data up to the delay period. Element forcedDelay Element Value TRUE or FALSE Type Boolean Description Setting to true will return the latest data up to the delay period specified by the exchange for this security. For example requesting VOD LN Equity and PX_LAST will return a snapshot of the last price from 15mins ago.
A Schemas
155
A Schemas
156
Example Syntax: Element securities = request.GetElement("securities"); securities.AppendValue("VOD LN Equity"); Fields: the reference fields desired which correspond to data points. See FLDS<GO> for a list of more information. Element fields Element Value Type string array Description See Fields on page 54 for additional details.
Example Syntax: Element fields = request.GetElement("fields"); fields.AppendValue("PX_LAST"); Start Date: the first date of the period to retrieve data Element startDate Element Value yyyymmdd Type string Description The start date in a year/month/day format.
Example Syntax: request.Set("startDate", "20090601"); End Date: the end date of the period to retrieve data Element endDate Element Value yyyymmdd Type string Description The end date in a year/month/day format. This will default to the current day if not specified.
Example Syntax: request.Set("endDate", "20100601"); Period Adjustment: Determine the frequency and calendar type of the output. To be used in conjunction with Period Selection. Element periodicityAdjustment Element Value ACTUAL Type string Description These revert to the actual date from today (if the end date is left blank) or from the End Date For pricing fields, these revert to the last business day of the specified calendar period. Calendar Quarterly (CQ), Calendar Semi-Annually (CS) or Calendar Yearly (CY). These periods revert to the fiscal period end for the company - Fiscal Quarterly (FQ), Fiscal SemiAnnually (FS) and Fiscal Yearly (FY) only
CALENDAR
string
FISCAL
string
A Schemas
157
Period Selection: Determine the frequency of the output. To be used in conjunction with Period Adjustment. Element periodicitySelection Element Value DAILY WEEKLY MONTHLY QUARTERLY SEMI_ANNUALLY YEARLY Currency: Amends the value from local to desired currency Element currency Element Value Currency of the ISO code, e.g., USD, GBP Type string Description The 3 letter ISO code. View WCV<GO> on the BLOOMBERG PROFESSIONAL service for a list of currencies. Type string string string string string string Description Returns one data point per day Returns one data point per week Returns one data point per month Returns one data point per quarter Returns one data point per half year Returns one data point per year
Example Syntax: request.Set("currency", "USD"); Override Options: Indicates whether to use the average or the closing price in quote calculation. Element overrideOption Element Value
OVERRIDE_OPTION_CLOS E OVERRIDE_OPTION_GPA
Description Use the closing price in quote calculation Use the average price in quote calculation
Example Syntax: request.Set("overrideOption", "OVERRIDE_OPTION_GPA"); Pricing Options: Sets quote to Price or Yield for a debt instrument whose default value is quoted in yield (depending on pricing source). Element pricingOption Element Value PRICING_OPTION_PRICE PRICING_OPTION_YIELD Type string string Description Set quote to price Set quote to yield
Example Syntax: request.Set("pricingOption", "PRICING_OPTION_PRICE"); Non Trading Day Fill Option: Sets to include/exclude non trading days where no data was generated. Element nonTradingDayFillOption Element Value
NON_TRADING_WEEKDAYS ALL_CALENDAR_DAYS ACTIVE_DAYS_ONLY
Description Include all weekdays (Monday to Friday) in the data set Include all days of the calendar in the data set returned Include only active days (days where the instrument and field pair updated) in the data set returned
A Schemas
158
Non Trading Day Fill Method: If data is to be displayed for non trading days what is the data to be returned. Element nonTradingDayFillMethod Element Value PREVIOUS_VALUE Type string Description Search back and retrieve the previous value available for this security field pair. The search back period is up to one month. Returns blank for the "value" value within the data element for this field.
NIL_VALUE
string
Example Syntax: request.Set("nonTradingDayFillMethod", "PREVIOUS_VALUE"); Max Data Points: the maximum number of data points to return. Element maxDataPoints Element Value Type integer Description The response will contain up to X data points, where X is the integer specified. If the original data set is larger than X, the response will be a subset, containing the last X data points. Hence the first range of data points will be removed.
Example Syntax: request.Set("maxDataPoints", 100); Return Entitlements: returns the entitlement identifiers associated with security. Element returnEids Element Value TRUE or FALSE Type Boolean Description Setting this to TRUE will populate fieldData with an extra element containing a name and value for the EID date.
Example Syntax: request.Set("returnEIDs", true); Return Relative Date: returns data with a relative date. Element returnRelativeDate Element Value TRUE or FALSE Type Boolean Description Setting this to true will populate fieldData with an extra element containing a name and value for the relative date. For example RELATIVE_DATE = 2002 Q2
Example Syntax: request.Set("returnRelativeDate", true); Adjustment Normal: Adjust for "change on day" Element adjustmentNormal Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing to reflect: Regular Cash, Interim, 1st Interim, 2nd Interim, 3rd Interim, 4th Interim, 5th Interim, Income, Estimated, Partnership Distribution, Final, Interest on Capital, Distribution, Prorated.
A Schemas
159
Adjustment Abnormal: Adjusts for Anormal Cash Dividends Element adjustmentAbnormal Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing to reflect: Special Cash, Liquidation, Capital Gains, Long-Term Capital Gains, Short-Term Capital Gains, Memorial, Return of Capital, Rights Redemption, Miscellaneous, Return Premium, Preferred Rights Redemption, Proceeds/Rights, Proceeds/Shares, Proceeds/ Warrants.
Example Syntax: request.Set("adjustmentAbnormal", true); Adjustment Split: Capital Changes Defaults Element adjustmentSplit Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing and/or volume to reflect: Spin-Offs, Stock Splits/Consolidations, Stock Dividend/Bonus, Rights Offerings/ Entitlement.
Example Syntax: request.Set("adjustmentSplit", true); Adjustment Follow DPDF: Follow the BLOOMBERG PROFESSIONAL service function DPDF<GO> Element adjustmentFollowDPDF Element Value TRUE or FALSE Type Boolean Description Setting to true will follow the DPDF<GO> BLOOMBERG PROFESSIONAL service function. True is the default setting for this option.
Example Syntax: request.Set("adjustmentFollowDPDF", true); CalendarCodeOverride: Returns the data based on the calendar of the specified country, exchange, or religion. Element calendarCodeOverride Element Value CDR <GO> calendar type Type String Description Returns the data based on the calendar of the specified country, exchange, or religion from CDR<GO>. Taking a two character calendar code null terminated string. This will cause the data to be aligned according to the calendar and including calendar holidays. Only applies only to DAILY requests.
A Schemas
160
CalendarOverridesInfo: Returns data based on the calendar code of multiple countries, exchanges, or religious calendars from CDR<GO>. Element calendarOverrides Element Value CDR <GO> calendar type Type String array Description Accepts a two-character calendar code null-terminated string of multiple country, exchange, or religious calendars from CDR<GO>. This will cause the data to be aligned according to the set calendar(s) including their calendar holidays. Only applies to DAILY requests. Default value. Returns the intersection of trading days. That is, a data point is returned if a date is a valid trading day in all calendar codes specified in the request. Returns the union of trading days. That is, a data point is returned if a date is a valid trading day for any of the calendar codes specified in the request.
calendareOverrides Operation
CDR_AND
String
CDR_OR
String
Example Syntax: Element cdrOverridesInfo = request.GetElement("calendarOverridesInfo"); Element cdrOverrides = cdrOverridesInfo.GetElement("calendarOverrides"); cdrOverrides.AppendValue("US"); cdrOverrides.AppendValue("JN"); cdrOverridesInfo.SetElement ("calendarOverridesOperation", "CDR_AND"); NOTE: calendarOverridesOperation" can be omitted only if one "calendarOverrides" is specified. Overrides: Append overrides to modify the calculation. Element fieldID Element Value Type string Description Specify a field mnemonic or alphanumeric, such as PR092 or PRICING_SOURCE. Review FLDS<GO> for list of possible overrides. The desired override value
string
Element overrides = request["overrides"]; Element override1 = overrides.AppendElement(); override1.SetElement("fieldId", "BEST_DATA_SOURCE_OVERRIDE"); override1.SetElement("value", "BLI");
A Schemas
161
A Schemas
162
A.2.6
Element securities
IntradayTickRequest: Sequence
Element Value Type string Description See Security/Securities on page 52 for additional details.
Example Syntax: Element securities = request.GetElement("securities"); request.Set("security", "VOD LN Equity"); Start Date: the first date of the period to retrieve data Element startDateTime Element Value yyyy-mm-dd Thh:mm:ss Type string Description The start date and time.
Example Syntax: request.Set("startDateTime", "2010-04-27T15:55:00"); End Date: the end date of the period to retrieve data Element endDateTime Element Value yyyy-mm-dd Thh:mm:ss Type string Description The end date and time.
Example Syntax: request.Set("endDateTime", "2010-04-27T16:00:00"); Event Type: The requested data event type Element eventType Element Value TRADE BID ASK BID_BEST ASK_BEST MID_PRICE Type string string string string string string Description Corresponds to LAST_PRICE Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK. Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK. MID_PRICE only applies to the LSE. The mid price is equal to the sum of the best bid price and the best offer price divided by two, and rounded up to be consistent with the relevant price format. Automatic trade for London Sets stocks. Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK.
A Schemas
163
Include Condition Codes: return any condition codes that may be associated to a tick, which identifies extraordinary trading and quoting circumstances. Element includeConditionCodes Element Value TRUE or FALSE Type Boolean Description A comma delimited list of exchange condition codes associated with the event. Review QR<GO> for more information on each code returned.
Example Syntax: request.Set("includeConditionCodes", true); Include Non Plottable Events: return ticks in the response that have condition codes Element includeNonPlottable Events Element Value TRUE or FALSE Type Boolean Description Returns all ticks, including those with condition codes.
Example Syntax: request.Set("includeNonPlottableEvents", true); Include Exchange Codes: return the exchange code of the trade Element includeExchangeCodes Element Value TRUE or FALSE Type Boolean Description The exchange code where this tick originated. Review QR<GO> for more information.
Example Syntax: request.Set("includeExchangeCodes", true); Return Entitlements: returns the entitlement identifiers associated with security. Element returnEids Element Value TRUE or FALSE Type Boolean Description Option on whether to return EIDs for the security.
Example Syntax: request.Set("returnEids", true); Include Broker Codes: return the broker code of the trade Element includeBrokerCodes Element Value TRUE or FALSE Type Boolean Description The broker code for Canadian, Finnish, Mexican, Philippine, and Swedish equities only. The Market Maker Lookup screen, MMTK<GO>, displays further information on market makers and their corresponding codes.
Example Syntax: request.Set("includeBrokerCodes", true); Include Reporting Party Side Codes: return transaction codes Element includeRpsCodes Element Value TRUE or FALSE Type Boolean Description The Reporting Party Side. The following values appear: -B: A customer transaction where the dealer purchases securities from the customer. -S: A customer transaction where the dealer sells securities to the customer. -D: An inter-dealer transaction (always from the sell side).
A Schemas
164
Include Bank/Market Identifier Codes: return bank or market identifier code Element includeBicMicCodes Element Value TRUE or FALSE Type Boolean Description The BIC, or Bank Identifier Code, as a 4character unique identifier for each bank that executed and reported the OTC trade, as required by MiFID. BICs are assigned and maintained by SWIFT (Society for Worldwide Interbank Financial Telecommunication). The MIC is the Market Identifier Code, and this indicates the venue on which the trade was executed.
A Schemas
165
A Schemas
166
Example Syntax: Element securities = request.GetElement("securities"); request.Set("security", "VOD LN Equity"); Start Date: the first date of the period to retrieve data Element startDateTime Element Value yyyy-mm-dd Thh:mm:ss Type string Description The start date and time.
Example Syntax: request.Set("startDateTime", "2010-04-27T15:55:00"); End Date: the end date of the period to retrieve data Element endDateTime Element Value yyyy-mm-dd Thh:mm:ss Type string Description The end date and time.
Example Syntax: request.Set("endDateTime", "2010-04-27T16:00:00"); Event Type: The requested data event type Element eventType Element Value TRADE BID ASK BID_BEST ASK_BEST BEST_BID BEST_ASK Type string string string string string string string Description Corresponds to LAST_PRICE Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK. Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK. Depending on the exchange bid ticks will be returned as BID, BID_BEST or BEST_BID. Depending on the exchange ask ticks will be returned as ASK, ASK_BEST or BEST_ASK.
Example Syntax: request.Set("eventType", "TRADE"); Interval: the length of each bar returned Element interval Element Value 1...1440 Type integer Description Sets the length of each time bar in the response. Entered as a whole number, between 1 and 1440 in minutes. If omitted, the request will default to one minute. One minute is the lowest possible granularity.
A Schemas
167
Gap Fill Initial Bar: populate an empty bar with previous value Element gapFillInitialBar Element Value TRUE or FALSE Type Boolean Description When set to true, a bar contains the previous bar values if there was no tick during this time interval.
Example Syntax: request.Set("gapFillInitialBar", true); Return Entitlements: returns the entitlement identifiers associated with security. Element returnEids Element Value TRUE or FALSE Type Boolean Description Option on whether to return EIDs for the security.
Example Syntax: request.Set("returnEids", true); Return Relative Date: returns data with a relative date. Element returnRelativeDate Element Value TRUE or FALSE Type Boolean Description Setting this to true will populate fieldData with an extra element containing a name and value for the relative date. For example RELATIVE_DATE = 2002 Q2
Example Syntax: request.Set("returnRelativeDate", true); Adjustment Normal: Adjust "change on day" Element adjustmentNormal Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing to reflect: Regular Cash, Interim, 1st Interim, 2nd Interim, 3rd Interim, 4th Interim, 5th Interim, Income, Estimated, Partnership Distribution, Final, Interest on Capital, Distribution, Prorated.
Example Syntax: request.Set("adjustmentNormal", true); Adjustment Abnormal: Adjust for Abnormal Cash Dividends Element adjustmentAbnormal Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing to reflect: Special Cash, Liquidation, Capital Gains, Long-Term Capital Gains, Short-Term Capital Gains, Memorial, Return of Capital, Rights Redemption, Miscellaneous, Return Premium, Preferred Rights Redemption, Proceeds/Rights, Proceeds/Shares, Proceeds/Warrants.
Example Syntax: request.Set("adjustmentAbnormal", true); Adjustment Split: Capital Changes Defaults Element adjustmentSplit Element Value TRUE or FALSE Type Boolean Description Adjust historical pricing and/or volume to reflect: Spin-Offs, Stock Splits/Consolidations, Stock Dividend/Bonus, Rights Offerings/ Entitlement.
A Schemas
168
Adjustment Follow DPDF: Follow the BLOOMBERG PROFESSIONAL service function DPDF<GO> Element adjustmentFollowDPDF Element Value TRUE or FALSE Type Boolean Description Setting to true will follow the DPDF<GO> BLOOMBERG PROFESSIONAL service function. True is the default setting for this option..
A Schemas
169
Example Syntax: Element securities = request.GetElement("securities"); securities.AppendValue("UXXXXXXX-X Client"); Fields: The desired reference fields. Element fields Element Value Type string Description The fields that can be used are PORTFOLIO_MEMBER PORTFOLIO_MPOSITION, PORTFOLIO_MWEIGHT & PORTFOLIO_DATA.
Example Syntax: Element fields = request.GetElement("fields"); fields.AppendValue("PORTFOLIO_MEMBER "); Overrides: The Portfolio information can also be accessed historically by using the REFERENCE_DATE override field by supplying the date in 'yyyymmdd' format. Element fieldId value Element Value Type string string Description Field mnemonic "REFERENCE_DATE" The date in 'yyyymmdd' format.
Example Syntax: Element overrides = request["overrides"]; Element override1 = overrides.AppendElement(); override1.SetElement("fieldId", "REFERENCE_DATE"); override1.SetElement("value", "20100111");
A Schemas
170
A Schemas
171
Example Syntax: request.Set("screenName", "Global Volume Surges"); screenType: Screen Type. Element screenType Element Value PRIVATE or GLOBAL Type string Description Use PRIVATE for user-defined EQS screen. Use GLOBAL for Bloomberg EQS screen.
Example Syntax: request.Set("screenType", "GLOBAL"); languageId: Specify the language for field names to be returned for screen data Element languageId (optional) Element Value Type string Description The following languages are supported: ENGLISH, KANJI, FRENCH, GERMAN, SPANISH, PORTUGUESE, ITALIAN, CHINESE_TRA, KOREAN, CHINESE_SIM, THAI, SWED, FINNISH, DUTCH, MALAY, RUSSIAN, GREEK, POLISH, DANISH, FLEMISH, ESTONIAN, TURKISH, NORWEGIAN, LATVIAN, LITHUANIAN, INDONESIAN
Example Syntax: request.Set("languageId", "FRENCH"); Group: Specify group name. Element Group (optional) Element Value Type string Description Screen folder name here as defined in EQS<GO>.
A Schemas
172
A Schemas
173
Description
Returned when a request cannot be completed for any reason. It is an errorInfo element. Contains an array of securityData elements Contains the response data for a specific security from a ReferenceDataRequest or a HistoricalDataRequest. It provides the security string specified in the request, the sequence number and can include fieldData[ ], fieldsExceptions[ ] and securityError elements. Contains the response data for an IntradayBarRequest. It can provide a barTickData[ ] element and/or an eidData array element. Contains an array of barTickData elements Contains values associated to the bar, including time, open, high, low, close, volume, numEvents. Contains the response data for an IntradayTickRequest. It can provide a tickData[ ] element and/or an eidData array element. Contains an array of tickData elements Contains values associated to the eventType, including time, type, value, size, condition code, and exchange code. Contains a list of eidData values associated to the securities requested. If the requestor does not have the entitlement as per EXCH<GO> then the identifiers will not be returned. Returned when a request cannot be completed for any reason. It is an errorInfo element. Contains an array of fieldExceptions. Contains a field identifier, message and errorInfo element. Contains an array of fieldData values Reference Data Request: element with the fieldId and value Historical Data Request: element with the relativeDate, Date, fieldId and value
errorInfo
Contains values about the error which has occurred, including the source, code, category, message, and subcategory.
A Schemas
174
Size of an event for intraday tick data (for example, number of shares). A comma delimited list of exchange condition codes associated with the event. Single character indicating exchange tick event origin. Bloomberg internal error source information. Bloomberg internal error code. Bloomberg error classification. Used to determine the general classification of the failure. Human readable description of the failure. (Optional) Bloomberg sub-error classification. Used to determine the specific classification of the failure.
A Schemas
175
brokerBuyCode brokerSellCode
String String
micCode
String
A Schemas
176
Type
FieldInfoRequest FieldSearchRequest CategorizedFieldSearch Request
Description
Request for field information. Field search information. See Categorized Field
Type
FieldResponse CategorizedFieldResponse
Description
Field response information. See Categorized Field Search Request Response on page 184.
Example Syntax: Element idList = request.GetElement("id"); request.Append("id", "LAST_PRICE"); request.Append("id", "pq005"); Return field documenation: Element returnFieldDocumentatio n Element Value TRUE or FALSE Type Boolean Description Returns a description about the field as seen on FLDS<GO>. Default value is false.
A Schemas
177
A Schemas
178
request.Set("searchSpec", "mutual fund"); Element Value New Fields Analysis Corporate Actions Custom Fields Descriptive Earnings Estimates Fundamentals Market Activity Metadata Ratings Trading Systems All Govt Corp Mtge M-Mkt Muni Pfd Equity Cmdty Index Curncy Type String Description Categories for fields
productType
String String String String String String String String String String String
The results will be filtered by fields that are avaliable for this yellow key (security type).
A Schemas
179
fieldType
Results include fields that are both streaming (real-time and delayed) and reference (static) Results include fields that provide streaming data (real-time and delayed) Results include fields that provide reference data (static).
Element element = request.getElement ("include"); element.setElement("productType", "Equity"); element.setElement("fieldType", "Static"); Element element1 = element.GetElement("category"); element1.AppendValue("Ratings"); element1.AppendValue("Analysis"); Exclude options: Element category Element Value New Fields Analysis Corporate Actions Custom Fields Descriptive Earnings Estimates Fundamentals Market Activity Metadata Ratings Trading Systems All Govt Corp Mtge M-Mkt Muni Pfd Equity Cmdty Index Curncy Type String Description Categories for fields
productType
String String String String String String String String String String String
The results will be filtered by fields that are avaliable for this yellow key (security type).
A Schemas
180
fieldType
Results include fields that are both streaming (real-time and delayed) and reference (static) Results include fields that provide streaming data (real-time and delayed) Results include fields that provide reference data (static).
Example Syntax:
Element element = request.getElement ("exclude"); element.setElement("productType", "Equity"); element.setElement("fieldType", "Static"); Element element1 = element.GetElement("category"); element1.AppendValue("Ratings"); element1.AppendValue("Analysis"); Element Value TRUE or FALSE Type Boolean Description Returns a description about the field as seen on FLDS<GO>. Default value is false.
A Schemas
181
A Schemas
182
request.Set("searchSpec", "mutual fund"); Element Value New Fields Analysis Corporate Actions Custom Fields Descriptive Earnings Estimates Fundamentals Market Activity Metadata Ratings Trading Systems All Govt Corp Mtge M-Mkt Muni Pfd Equity Cmdty Index Curncy Type String Description Categories for fields
productType
String String String String String String String String String String String
The results will be filtered by fields that are avaliable for this yellow key (security type).
A Schemas
183
fieldType
Results include fields that are both streaming (real-time and delayed) and reference (static) Results include fields that provide streaming data (real-time and delayed) Results include fields that provide reference data (static).
Example Syntax:
Element element = request.getElement ("exclude"); element.setElement("productType", "Equity"); element.setElement("fieldType", "Static"); Element element1 = element.GetElement("category"); element1.AppendValue("Ratings"); element1.AppendValue("Analysis"); Element Value TRUE or FALSE Type Boolean Description Returns a description about the field as seen on FLDS<GO>. Default value is false.
A Schemas
184
element.setElement("fieldType", "Static"); Element Value TRUE or FALSE Type Boolean Description Returns a description about the field as seen on FLDS<GO>. Default value is false.
request.Set("returnFieldDocumentation", true);
A Schemas
186
A Schemas
187
Description
Returned when a request cannot be completed for any reason. It is an errorInfo element. Contains an array of fieldData values Contains a id corresponding to the requested field identifier, along with either a fieldInfo or fieldError element Contains values on the mnemonic, datatype, categoryName, description, and documentation. Returned when a request cannot be completed for any reason or in the case of a fieldInfoRequest when an invalid field mnemonic or alphanumeric is entered. Returned when a request cannot be completed for any reason. It is an errorInfo element. Contains an array of category elements. Contains categoryName, categoryId, numFields, descriptions, isLeafNode and a fieldData[ ] element. Contains values about the error which has occurred, including the source, code, category, message, and subcategory.
A Schemas
188
Type
String
Description
Resulting field represented as an alphanumeric or a Mnemonic, i.e., PR005 or PX_LAST. Resulting field represented as a mnemonic, i.e., PX_LAST. Enumeration values representing Bloomberg data types. Please see specific SDK documentation for the enum values. Enumeration value representing data types shown in XDM<GO>. Response value for the name of the category. Could be one of the following: New Fields, Analysis, Corporate Actions, Custom Fields, Descriptive, Earnings Estimates, Fundamentals, Market Activity, Metadata, Ratings, and Trading Systems. Is the short description describing the field, for example for the mnemonic LAST_PRICE the description is "Last Trade/Last Price". Corresponds to the definition in FLDS<GO> Tick time for an intraday tick request The event type for an intraday tick Bloomberg internal error source information. Bloomberg internal error code. Bloomberg error classification. Used to determine the general classification of the failure. Human readable description of the failure. Bloomberg sub-error classification. Used to determine the specific classification of the failure.
mnemonic datatype
Integer Enumeration
ftype categoryName
Enumeration String
description
String
message subcategory
String String
A Schemas
189
Type
string
Description
As with any Subscription, a Market Bar Subscription must contain at least one security, field and Correlation ID. The topic is defined as:
"//blp/mktbar/symbology/identifier"
field string The following fields are returned for Market Bars: TIME, OPEN, HIGH, LOW, CLOSE, NUMBER_OF_TICKS, VOLUME. These values are only updated on a trade. For this reason, LAST_PRICE should be submitted in the subscription string. See Fields on page 54 for additional details. Fields can be specified as a alpha numeric or mnemonic. Example Syntax: Subscription mySubscription = new Subscription("//blp/mktbar/ticker/VOD LN Equity", "LAST_PRICE", new CorrelationID(id)); interval string Optional. Interval time defined thelength in minutes of a bar. If undefined it is set to 1 minute. This is the minimum duration. The maximum duration is 1440 minutes, (=24 hours). Optional. This should be in the format hh:mm. If these values are not specified then they default is time of subscription. Optional. This should be in the format hh:mm. If these values are not specified then they default is session end time.
start_time end_time
string string
Example Syntax: Subscription mySubscription = new Subscription(security, field, "interval=5" "start_time=15:00", "end_time=15:30",CorrelationID(id));
Type
datetime Float64
Description
Returns the time of the last TRADE on every update. Returns open price for each bar. Will be returned in the first tick for the bar. Returns high price at the beginning of the bar and subsequently every higher price that occurs until the end of the bar. Returns low price at the beginning of the bar and subsequently every higher price that occurs until the end of the bar.
A Schemas
190
Argument Value
CLOSE NUMBER_OF_TICKS
Type
Float64 Int32
Description
Returns updated close price on every update. Counts tick number on every update until a new bar starts.
Example Syntax: int close = msg.getElementAsFloat64(CLOSE); Example Syntax: int number_of_ticks = msg.getElementAsInt32(NUMBER_OF_TICKS); VOLUME Int64 Volume increments for number of trades in each market bar and is reset at the start of each market bar.
A Schemas
191
Type
MarketDataEvents
Description
Market Data Eventss
Type
string
Description
Sets a defined period in seconds for which updates will be received for the subscription. The range for this argument is 0.10 to 86400.00, which is equal to 100ms to 24hours. For example setting this argument to 30 will result in the requesting application to receive updates every 30 seconds for the requested securities.
Example Syntax: Subscription mySubscription = new Subscription(security, fields, "interval=30.0", new CorrelationID(security)); delayed string Forces the subscription to be delayed even if the requestor has realtime exchange entitlements.
Example Syntax: Subscription mySubscription = new Subscription(security, fields, "delayed", new CorrelationID(security));
Type
Optional Boolean Optional Boolean Optional Boolean Optional Boolean Optional Boolean
Description
Toronto MOC Eligible Nasdaq Closing Cross Eligible MGF Setting (Real-time) Exchange Trading Status Quotation Status
A Schemas
192
Element
IND_BID_FLAG IND_ASK_FLAG TRADING_DT_REALTIME RT_TIME_OF_TRADE CR_OBSERVATION_DATE PRIOR_OBSERVATION_DATE TIME VOLUME BID_YIELD ASK_YIELD RT_OPEN_INTEREST OFF_ON_EXCH_VOLUME_RT OFF_EXCH_VOLUME_RT PX_VOLUME_BAL_RT OPT_DELTA_BID_RT OPT_DELTA_ASK_RT OPT_DELTA_MID_RT OPT_DELTA_LAST_RT OPT_GAMMA_BID_RT OPT_GAMMA_ASK_RT OPT_GAMMA_MID_RT OPT_GAMMA_LAST_RT OPT_VEGA_BID_RT OPT_VEGA_ASK_RT OPT_VEGA_MID_RT OPT_VEGA_LAST_RT OPT_IMPLIED_VOLATILITY_BID_RT OPT_IMPLIED_VOLATILITY_ASK_RT OPT_IMPLIED_VOLATILITY_MID_RT OPT_IMPLIED_VOLATILITY_LAST_RT EQY_SH_FOREIGN_RT LISTED_SH_RT
Type
Optional Boolean Optional Boolean Optional Date Optional Datetime Optional Datetime Optional Datetime Optional Datetime Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Int32 Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32
Description
Indicative Bid Flag Indicative Ask Flag Trading Date Time Trade Occurred Current Observation Date Prior Observation Date Time of Last Update Volume Bid Yield Ask Yield Open Interest (Real-time) Off And On Exchange Volume (Real-time) Off Exchange Volume (Real-time) Volume Balance (Real-time) Delta Bid (Real-time) Delta Ask (Real-time) Delta Mid (Real-time) Delta Last Trade (Real-time) Gamma Bid (Real-time) Gamma Ask (Real-time) Gamma Mid (Real-time) Gamma Last Trade (Real-time) Vega Bid (Real-time) Vega Ask (Real-time) Vega Mid (Real-time) Vega Last Trade (Real-time) Implied Volatility Bid (Real-time) Implied Volatility ASK (Real-time) Implied Volatility Mid (Real-time) Implied Volatility Last Trade (Real-time) Shares Available To Foreign Investors (Real-time) Number Of Listed Shares (Real-time)
A Schemas
193
Element
BLP_SPRD_TO_BENCH_BID_RT BLP_SPRD_TO_BENCH_ASK_RT BLP_SPRD_TO_BENCH_MID_RT BLP_Z_SPRD_MID_RT BLP_ASW_SPREAD_MID_RT BLP_I_SPRD_MID_RT BLP_CDS_BASIS_MID_RT BLP_SPRD_TO_BENCH_CHG_RT BLP_Z_SPRD_CHG_RT BLP_ASW_SPRD_CHG_RT BLP_I_SPRD_CHG_RT BLP_CDS_BASIS_CHG_RT BLP_SPRD_TO_BENCH_PCT_CHG_RT BLP_Z_SPRD_PCT_CHG_RT BLP_ASW_SPRD_PCT_CHG_RT BLP_I_SPRD_PCT_CHG_RT BLP_CDS_BASIS_PCT_CHG_RT PX_SETTLE_ACTUAL_RT ARBITRAGE_ASK_ORD_NOT_MATCHED_RT ARBITRAGE_BID_ORD_NOT_MATCHED_RT NON_ARBITRAGE_ASK_NOT_MATCHED_RT NON_ARBITRAGE_BID_NOT_MATCHED_RT ARBITRAGE_ASK_ORD_VOLUME_RT ARBITRAGE_BID_ORD_VOLUME_RT
Type
Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Int32 Optional Int32
Description
Bloomberg Bid Spread To Benchmark (Real-time) Bloomberg Ask Spread To Benchmark (Real-time) Bloomberg Mid Spread To Benchmark (Real-time) Bloomberg Mid Z Spread (Real-time) Bloomberg Mid ASW Spread (Real-time) Bloomberg Mid I Spread (Real-time) Bloomberg Mid CDS Basis (Real-time) Bloomberg Sprd To Bench Chg On Day (Real-time) Bloomberg Z Spread Change On Day (Real-time) Bloomberg ASW Spread Change On Day (Real-time) Bloomberg I Spread Change On Day (Real-time) Bloomberg CDS Basis Change On Day (Real-time) Bloomberg Spd To Bench % Chg On Day (Real-time) Bloomberg Z Spread % Change On Day (Real-time) Bloomberg ASW Spread % Chg On Day (Real-time) Bloomberg I Spread % Change On Day (Real-time) Bloomberg CDS Basis % Change On Day (Real-time) Settlement Price Actual (Real-time) Arbitrage Ask Orders Not Matched (Realtime) Arbitrage Bid Orders Not Matched (Realtime) Non Arbitrage Ask Orders Not Matched (Real-time) Non Arbitrage Bid Orders Not Matched (Real-time) Arbitrage Ask Orders Volume (Real-time) Arbitrage Bid Orders Volume (Real-time)
A Schemas
194
Element
NON_ARBIT_ASK_ORD_VOLUME_RT NON_ARBIT_BID_ORD_VOLUME_RT PRE_ANNOUNCE_NUM_PROG_ASK_RT PRE_ANNOUNCE_NUM_PROG_BID_RT TRUST_ASK_ORD_VOLUME_RT PROPRIETARY_ASK_ORD_VOLUME_RT TRUST_BID_ORD_VOLUME_RT PROPRIETARY_BID_ORD_VOLUME_RT TOTAL_VOLUME_PROGRAM_TRADE_RT PX_INDICATIVE_BID_SIZE_RT PX_INDICATIVE_ASK_SIZE_RT NUM_TRADES_RT MGF_VOLUME_RT NUM_TRADES_OPENING_AUCTION_RT NUM_TRADES_CLOSING_AUCTION_RT ALL_PRICE_SIZE RT_NYSE_LIQUIDITY_BID_SIZE RT_NYSE_LIQUIDITY_ASK_SIZE VOLUME_THEO SIZE_LAST_AT_TRADE SIZE_LAST_AT_TRADE_TDY OPEN_YLD OPEN_YLD_TDY HIGH_YLD HIGH_YLD_TDY LOW_YLD LOW_YLD_TDY LAST_YLD LAST_YLD_TDY SIZE_LAST_TRADE_TDY
Type
Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Int32
Description
Non Arbitrage Ask Orders Volume (Realtime) Non Arbitrage Bid Orders Volume (Realtime) Pre Announce Num of Program Ask Orders (Real-time) Pre Announce Num of Program Bid Orders (Real-time) Trust Ask Orders Volume (Real-time) Proprietary Ask Orders Volume (Realtime) Trust Bid Orders Volume (Real-time) Proprietary Bid Orders Volume (Realtime) Total Volume of Program Trading (Realtime) Indicative Bid Price Size (Real-time) Indicative Ask Price Size (Real-time) Number Of Trades MGF Volume (Real-time) Number Of Trades In Opening Auction (Real-time) Number Of Trades In Closing Auction (Real-time) All Price Size NYSE Liquidity Quote Bid Size NYSE Liquidity Quote Ask Size Theoretical Volume Size of Last AT Trade Size of Today's Last AT Trade Open Yield Today's Open Yield High Yield Today's High Yield Low Yield Today's Low Yield Last Yield Today's Last Yield Size of Today's Last Trade
A Schemas
195
Element
LAST2_YLD LAST_DIR_YLD LAST2_DIR_YLD PREV_SES_LAST_YLD BID2_YLD ASK2_YLD BID_DIR_YLD ASK_DIR_YLD MID_DIR MID2_DIR RT_PX_CHG_PCT_1D RT_YLD_CHG_NET_1D RT_YLD_CHG_PCT_1D ASK_SIZE_TDY BID_SIZE_TDY VOLUME_TDY BID_YLD_TDY ASK_YLD_TDY UP_LIMIT DOWN_LIMIT LAST_DIR LAST2_DIR BID_DIR ASK_DIR SIZE_LAST_TRADE ASK_SIZE BID_SIZE LAST_PRICE BID ASK HIGH LOW BEST_BID BEST_ASK MID LAST_TRADE OPEN
Type
Optional Float32 Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Int32 Optional Int32 Optional Int32 Optional Float32 Optional Float32 Optional Float32 Optional Float32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64
Description
Last 2 Yield Last Yield Direction Second Last Yield Direction Previous Session Last Yield Bid 2 Yield Ask 2 Yield Bid Yield Direction Ask Yield Direction Mid Direction Second Mid Direction Real-Time Price Change 1 Day Percent Real-Time Yield Change 1 Day Net Real-Time Yield Change 1 Day Percent Today's Ask Size Today's Bid Size Today's Volume Today's Bid Yield Today's Ask Yield Up Limit Down Limit Last Direction Second Last Direction Bid Direction Ask Direction Size of Last Trade Ask Size Bid Size Last Price Bid Price Ask Price High Price Low Price Best Bid Best Ask Mid Price Last Trade Open Price
A Schemas
196
Element
PREV_SES_LAST_PRICE EXCH_VWAP NASDAQ_OPEN NASDAQ_FIRST_TRADE NASDAQ_PREV_BID NASDAQ_PREV_ASK INDICATIVE_FAR INDICATIVE_NEAR IMBALANCE_BID IMBALANCE_ASK ORDER_IMB_BUY_VOLUME ORDER_IMB_SELL_VOLUME VWAP FIXING_RATE_REALTIME HIGH_TEMP_REALTIME LOW_TEMP_REALTIME MEAN_TEMP_REALTIME HEATING_DAYS_REALTIME COOLING_DAYS_REALTIME REL_HUMIDITY_REALTIME WIND_SPEED_REALTIME WEATHER_CODE_REALTIME PRECIPITATION_REALTIME MARKET_DEFINED_VWAP_REALTIME MIN_LIMIT MAX_LIMIT THEO_PRICE MIN_LIMIT_OUT_OF_SESSION MAX_LIMIT_OUT_OF_SESSION BID_WEIGHTED_AVG_SPREAD ASK_WEIGHTED_AVG_SPREAD RT_NYSE_LIQUIDITY_PX_BID RT_NYSE_LIQUIDITY_PX_ASK INDICATIVE_BID INDICATIVE_ASK PX_EVAL_JAPANESE_REALTIME LAST_ALL_SESSIONS
Type
Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Int32 Optional Int32 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64
Description
Previous Session Last Price Exchange VWAP NASDAQ Official Open Price NASDAQ First Actual Trade NASDAQ Prevailing Bid Price NASDAQ Prevailing Ask Price Far Indicative Price Near Indicative Price Net Order Imbalance Bid Price Net Order Imbalance Ask Price Net Order Imbalance Bid Volume Net Order Imbalance Ask Volume Eqty intraday VWAP Fixing Rate High Temperature Low Temperature Mean Temperature Heating Degree Days Cooling Degree Days Relative Humidity Wind Speed Weather Condition Code Precipitation Market Defined VWAP (Real-time) Minimum Limit Price Maximum Limit Price Theoretical Price Minimum Limit Price Out Of Session Maximum Limit Price Out Of Session Bid Weighted Average Spread Ask Weighted Average Spread NYSE Liquidity Quote Bid Price NYSE Liquidity Quote Ask Price Indicative Bid Price Indicative Ask Price Japanese Evaluation Price Last Price All Sessions
A Schemas
197
Element
PX_NASDAQ_VWOP_REALTIME BLP_I_SPRD_LAST_RT PREV_CLOSE_VALUE_REALTIME BID_ALL_SESSION ASK_ALL_SESSION EBS_TOUCH_HIGH_REALTIME EBS_TOUCH_LOW_REALTIME PX_PREV_TO_LAST_REALTIME PX_TARGIN_SERVICE_REALTIME PX_TARGIN_OFFCIAL_REALTIME FOREIGN_HOLDING_PCT_RT OWNERSHIP_LIMIT_RATIO_RT RT_EVAL_JAPANESE_CHG_ON_DAY RT_EVAL_JAPANESE_PCT_CHG_ON_DAY BLP_Z_SPRD_LAST_RT BLP_ASW_SPREAD_LAST_RT BLP_RT_SPRD_TO_BENCH_LAST_RT TRUST_ASK_ORD_VALUE_RT PROPRIETARY_ASK_ORD_VALUE_RT TRUST_BID_ORD_VALUE_RT PROPRIETARY_BID_ORD_VALUE_RT TOTAL_VALUE_PROGRAM_TRADE_RT PX_OFFICIAL_AUCTION_RT NYSE_LRP_HIGH_PRICE_RT NYSE_LRP_LOW_PRICE_RT ALL_PRICE BEST_BID1 BEST_BID2 BEST_BID3 BEST_BID4 BEST_BID5 BEST_ASK1 BEST_ASK2
Type
Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64
Description
NASDAQ VWOP Price Bloomberg Last I Spread (Real-time) Previous Closing Value Bid Price All Session Ask Price All Session EBS Touch High EBS Touch Low Previous-To-Last Price TARGIN Service Price (Real-time) TARGIN Official Price (Real-time) Percentage Of Foreign Holding (Realtime) Ownership Limit Ratio (Real-time) Japanese Evaluation Price Change On Day (Real-time) Japanese Eval Price Pct Change On Day (Real-time) Bloomberg Last Z Spread (Real-time) Bloomberg Last ASW Spread (Real-time) Bloomberg Last Spread to Benchmark (Real-time) Trust Ask Orders Value (Real-time) Proprietary Ask Orders Value (Real-time) Trust Bid Orders Value (Real-time) Proprietary Bid Orders Value (Real-time) Total Value of Program Trading (Realtime) Official Auction Price (Real-time) NYSE LRP High Price (Real-time) NYSE LRP Low Price (Real-time) All Price Best Bid 1 Best Bid 2 Best Bid 3 Best Bid 4 Best Bid 5 Best Ask 1 Best Ask 2
A Schemas
198
Element
BEST_ASK3 BEST_ASK4 BEST_ASK5 BEST_BID1_SZ BEST_BID2_SZ BEST_BID3_SZ BEST_BID4_SZ BEST_BID5_SZ BEST_ASK1_SZ BEST_ASK2_SZ BEST_ASK3_SZ BEST_ASK4_SZ BEST_ASK5_SZ LAST_AT_TRADE LAST2_AT_TRADE LAST_AT_TRADE_TDY MID_TDY MID2 RT_PX_CHG_NET_1D OPEN_TDY LAST_PRICE_TDY BID_TDY ASK_TDY HIGH_TDY LOW_TDY LAST2_PRICE BID2 ASK2 RT_EXCH_MARKET_STATUS RT_TRADING_PERIOD BID_BROKER_CODE ASK_BROKER_CODE IMBALANCE_INDIC_RT BLP_SPREAD_BENCHMARK_NAME_RT BLP_SWAP_CURVE_NAME_RT
Type
Optional Float64 Optional Float64 Optional Float64 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Int32 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional Float64 Optional String Optional String Optional String Optional String Optional String Optional String Optional String
Description
Best Ask 3 Best Ask 4 Best Ask 5 Best Bid 1 Size Best Bid 2 Size Best Bid 3 Size Best Bid 4 Size Best Bid 5 Size Best Ask 1 Size Best Ask 2 Size Best Ask 3 Size Best Ask 4 Size Best Ask 5 Size Last AT Trade Last 2 AT Trade Today's Last AT Trade Today's Mid Price Mid 2 Price Real-Time Price Change 1 Day Net Today's Open Price Today's Last Price Today's Bid Price Today's Ask Price Today's High Price Today's Low Price Last 2 Price Bid 2 Price Ask 2 Price Exchange Market Status Trading Period Bid Broker Code Ask Broker Code Imbalance Indicator Bloomberg Spread Benchmark Name (Real-time) Bloomberg Swap Curve Name (Realtime)
A Schemas
199
Element
FINANCIAL_STATUS_INDICATOR_RT BID_YLD_COND_CODE YLD_COND_CODE ASK_YLD_COND_CODE ALL_PRICE_COND_CODE BID_COND_CODE ASK_COND_CODE RT_SIMP_SEC_STATUS RT_PRICING_SOURCE NYSE_LRP_SEND_TIME_RT BID_ASK_TIME SES_START SES_END TRADE_SPREAD_TIME NEWS_STORY_TIME BID_TIME BID_BEST_TIME VOLUME_UPDATE_TIME MARKET_DEPTH_TIME CANCEL_CORRECT_TIME MIN_LIMIT_OUT_OF_SESSION_TIME BID_SPREAD_TIME BT_MKT_TURN_TIME HIGH_TIME BT_LSE_LAST_TIME AT_TRADE_TIME ASK_YEILD_TIME PRICE_UPDATE_TIME OPEN_INTEREST_TIME VOLUME_TIME EVAL_JAPANESE_TIME ASK_WEIGHTED_AVG_SPREAD_TIME THEO_PRICE_TIME BUY_SELL_INFO_TIME SETS_MID_PRICE_TIME
Type
Optional String Optional String Optional String Optional String Optional String Optional String Optional String Optional String Optional String Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time
Description
Financial Status Indicator (Real-time) Bid Yield Condition Code Yield Condition Code Ask Yield Condition Code Bid Condition Codes Ask Condition Codes Simplified Security Status Real-Time Pricing Source NYSE LRP Send Time (Real-time) Time of Last Bid/Ask Update Session Start Session End Time of TRADE_SPREAD tick Time of NEWS_STORY tick Time of BID tick Time of BID_BEST tick Time of VOLUME_UPDATE tick Time of MARKET_DEPTH tick Time of CANCEL_CORRECT tick Time of MIN_LIMIT_OUT_OF_SESSION tick Time of BID_SPREAD tick Time of BT_MKT_TURN tick Time of HIGH tick Time of BT_LSE_LAST tick Time of AT_TRADE tick Time of ASK_YEILD tick Time of PRICE_UPDATE tick Time of OPEN_INTEREST tick Time of VOLUME tick Time of EVAL_JAPANESE tick Time of ASK_WEIGHTED_AVG_SPREAD tick Time of THEO_PRICE tick Time of BUY_SELL_INFO tick Time of SETS_MID_PRICE tick
A Schemas
200
Element
TAKE_TIME TICK_NUM_TIME SMART_TIME INDICATIVE_ASK_TIME BT_SEC_ASK_TIME LOW_TIME BT_SEC_BID_TIME LOW_YIELD_TIME MAX_LIMIT_TIME TRADING_PERIOD_TIME INDICATIVE_BID_TIME API_INTERNAL_TIME ASK_LIFT_TIME NYSE_LIQUIDITY_ASK_TIME BID_YEILD_TIME ASK_BEST_TIME MKT_INDICATOR_TIME NYSE_LIQUIDITY_BID_TIME SMART_QUOTE_TIME NEW_MKT_DAY_TIME MAN_TRADE_WITH_SIZE_TIME BT_ASK_RECAP_TIME BT_MID_PRICE_TIME BID_MKT_MAKER_TIME SETTLE_TIME HIT_TIME BT_LAST_RECAP_TIME LAST_TRADE_TIME PRE_POST_MARKET_TIME ALL_PRICE_TIME OPEN_TIME HIGH_YIELD_TIME ASK_MKT_MAKER_TIME MAX_LIMIT_OUT_OF_SESSION_TIME SMARTMAX_TIME YIELD_TIME
Type
Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time
Description
Time of TAKE tick Time of TICK_NUM tick Time of SMART tick Time of INDICATIVE_ASK tick Time of BT_SEC_ASK tick Time of LOW tick Time of BT_SEC_BID tick Time of LOW_YIELD tick Time of MAX_LIMIT tick Time of TRADING_PERIOD tick Time of INDICATIVE_BID tick Time of API_INTERNAL tick Time of ASK_LIFT tick Time of NYSE_LIQUIDITY_ASK tick Time of BID_YEILD tick Time of ASK_BEST tick Time of MKT_INDICATOR tick Time of NYSE_LIQUIDITY_BID tick Time of SMART_QUOTE tick Time of NEW_MKT_DAY tick Time of MAN_TRADE_WITH_SIZE tick Time of BT_ASK_RECAP tick Time of BT_MID_PRICE tick Time of BID_MKT_MAKER tick Time of SETTLE tick Time of HIT tick Time of BT_LAST_RECAP tick Time of LAST_TRADE Time of PRE_POST_MARKET tick Time of ALL_PRICE tick Time of OPEN tick Time of HIGH_YIELD tick Time of ASK_MKT_MAKER tick Time of MAX_LIMIT_OUT_OF_SESSION tick Time of SMARTMAX tick Time of YIELD tick
A Schemas
201
Element
VWAP_TIME BID_WEIGHTED_AVG_SPREAD_TIME ASK_TIME MIN_LIMIT_TIME ASK_SPREAD_TIME SETTLE_YIELD_TIME BID_LIFT_TIME BT_BID_RECAP_TIME
Type
Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time Optional Time
Description
Time of VWAP tick Time of BID_WEIGHTED_AVG_SPREAD tick Time of ASK tick Time of MIN_LIMIT tick Time of ASK_SPREAD tick Time of SETTLE_YIELD tick Time of BID_LIFT tick Time of BT_BID_RECAP tick
A Schemas
202
Type
string
Description
Start trade time in the format, HH:MM. HH is in 24-hr format. Only trades at this or past this time are considered for VWAP computation. Specified in TZDF<GO> timing for Desktop API and UTC for Server API.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_START_TIME=11:00", new CorrelationID(security) ); VWAP_END_TIME string End trade time in the format, HH:MM. HH is in 24-hr format. Only trades at this or before this time are considered for VWAP computation. Specified in TZDF<GO> timing for Desktop API and UTC for Server API.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_END_TIME=12:00", new CorrelationID(security) ); VWAP_MIN_SIZE string Minimum trade volume for a trade to be included in VWAP computation. Values are taken as signed integers.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_MIN_SIZE=1000", new CorrelationID(security) ); VWAP_MAX_SIZE string Maximum trade volume for a trade to be included in VWAP computation. Values are taken as signed integers.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_MAX_SIZE=2000", new CorrelationID(security) ); VWAP_MIN_PX string Minimum trade price for a trade to be included in VWAP computation. Values are taken as floats.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_MIN_PX=23.5", new CorrelationID(security) ); VWAP_MAX_PX string Maximum trade price for a trade to be included in VWAP computation. Values are taken as floats.
Example Syntax: Subscription mySubscription = new Subscription( topic + security, fields, "&VWAP_MAX_PX=25.5", new CorrelationID(security) );
A Schemas
203
Description
Requests Bloomberg to check if a given Bloomberg Anywhere user is logged into the BLOOMBERG PROFESSIONAL service at a specified location.
Deprecated. Requests a list of exchange entitlements for a security by user. Deprecated. Requests a token.
Require ASID equivalence: Deprecated. Sets a flag to check the user has a superset of entitlements compared to the ServerAPI. Used for the All-or-None model of permissioning.
Element requireAsidEquivalence Element Value TRUE or FALSE Type Boolean Description When set to 'true', the AuthorizationRequest will succeed only if the users permission are equal to or greater than that of the Server API.
Token: Deprecated. Authorizes the user with the token based approach.
Element token Element Value Type Description Token returned by TokenRequest for a user. (Optional. Either ipAddress or token must be supplied.)
A Schemas
204
A Schemas
205
Example Syntax:
Request request = authSvc.CreateRequest("LogonStatusRequest"); Element userinfo = request.GetElement("userInfo"); userinfo.SetElement("uuid", 11223344); IP Address: The location where the user is viewing API data Element ipAddress Element Value Type string Description The location where the user is viewing API data
A Schemas
206
Example Syntax:
Request request = authSvc.CreateRequest("UserEntitlementsRequest"); Element userinfo = request.GetElement("userInfo"); userinfo.SetElement("uuid", 11223344);
A Schemas
207
Example Syntax: Request request = authSvc.CreateRequest("SecurityEntitlementsRequest"); Element securities = request.GetElement("securities"); securities.AppendValue("IBM US Equity");
A Schemas
208
Label: A label that identifies which Server API application is requesting the token.
Element label Element Value Type string Description String identifier for the requesting ServerAPI application
A Schemas
209
Description
Returned for an authorization request when the UUID provided is logged into the Bloomberg Anywhere at the specified IP address. Returned for an authorization request on failure. It is an errorInfo element. An AuthorizationFailure message will contain one "reason" element Returned when a request cannot be completed for any reason. It is an errorInfo element. Contains values about the error which has occurred, including the source, code, category, message, and subcategory. Contains a list of eidData elements, each associated to a security requested. Contains status, sequence number and list of entitlement identifiers. Contains a list of entitlementId values associated to the user.
Description
Bloomberg internal error source information. Bloomberg internal error code. Bloomberg error classification. Used to determine the general classification of the failure. Human readable description of the failure. (Optional) Bloomberg sub-error classification. Used to determine the specific classification of the failure. Entitlement identifier (EID) Status where success = 0. Any other code indicates failure. Security sequence number, specifying the position of the security in the request. Returns true when the UUID specified in logged into the BLOOMBERG PROFESSIONAL service at the specified IP address.
A Schemas
210
B Java Examples
This section contains the following code examples and sample output from each example:
Request Response Paradigm on page 212 Subscription Paradigm on page 215 Asynchronous Event Handling on page 219 Request Response Multiple on page 223 Subscription Multiple on page 227 Authorization by IP Address on page 237
B Java Examples
211
/ RequestResponseParadigm.java package BloombergLP; import import import import import import import import com.bloomberglp.blpapi.CorrelationID; com.bloomberglp.blpapi.Event; com.bloomberglp.blpapi.Message; com.bloomberglp.blpapi.MessageIterator; com.bloomberglp.blpapi.Request; com.bloomberglp.blpapi.Service; com.bloomberglp.blpapi.Session; com.bloomberglp.blpapi.SessionOptions;
public class RequestResponseParadigm { public static void main(String[] args) throws Exception { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session = new Session(sessionOptions); if (!session.start()) { System.out.println("Could not start session."); System.exit(1); } if (!session.openService("//blp/refdata")) { System.out.println("Could not open service " + "//blp/refdata"); System.exit(1); } CorrelationID requestID = new CorrelationID(1); Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "PX_LAST"); session.sendRequest(request, requestID);
boolean continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: // final event continueToLoop = false; // fall through case Event.EventType.Constants.PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } } } private static void handleResponseEvent(Event event) throws Exception { System.out.println("EventType =" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType =" + message.messageType()); message.print(System.out); } } private static void handleOtherEvent(Event event) throws Exception { System.out.println("EventType=" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType=" + message.messageType()); message.print(System.out); if (Event.EventType.Constants.SESSION_STATUS == event.eventType().intValue() && "SessionTerminated" == message.messageType().toString()){ System.out.println("Terminating: " + message.messageType()); System.exit(1); } } } }
B Java Examples
213
B Java Examples
214
// SubscriptionParadigm.java package BloombergLP; import import import import import import import import com.bloomberglp.blpapi.CorrelationID; com.bloomberglp.blpapi.Event; com.bloomberglp.blpapi.Message; com.bloomberglp.blpapi.MessageIterator; com.bloomberglp.blpapi.Session; com.bloomberglp.blpapi.SessionOptions; com.bloomberglp.blpapi.Subscription; com.bloomberglp.blpapi.SubscriptionList;
public class SubscriptionParadigm { public static void main(String[] args) throws Exception { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session = new Session(sessionOptions); if (!session.start()) { System.out.println("Could not start session."); System.exit(1); } if (!session.openService("//blp/mktdata")) { System.err.println("Could not start session."); System.exit(1); } CorrelationID subscriptionID = new CorrelationID(2); SubscriptionList subscriptions = new SubscriptionList(); subscriptions.add(new Subscription("AAPL US Equity", "LAST_PRICE", subscriptionID)); session.subscribe(subscriptions);
B Java Examples
215
int updateCount = 0; while (true) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.SUBSCRIPTION_DATA: handleDataEvent(event, updateCount++); break; default: handleOtherEvent(event); break; } } } private static void handleDataEvent(Event event, int updateCount) throws Exception { System.out.println("EventType=" + event.eventType()); System.out.println("updateCount = " + updateCount); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID = " + message.correlationID()); System.out.println("messageType = " + message.messageType()); message.print(System.out); } } private static void handleOtherEvent(Event event) throws Exception { System.out.println("EventType=" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType=" + message.messageType()); message.print(System.out); if (Event.EventType.Constants.SESSION_STATUS == event.eventType().intValue() && "SessionTerminated" == message.messageType().toString()){ System.out.println("Terminating: " + message.messageType()); System.exit(1); } } } }
B Java Examples
216
B Java Examples
217
LAST_PRICE_TDY = 93.0 BID_TDY = 92.92 ASK_TDY = 92.95 HIGH_TDY = 94.34 LOW_TDY = 92.6 RT_PRICING_SOURCE = US ASK_SIZE = 1 BID_SIZE = 1 TIME = 22:20:00.000+00:00 API_MACHINE = n119 EXCH_CODE_LAST = D EXCH_CODE_BID = Q EXCH_CODE_ASK = O EID = 14005 IS_DELAYED_STREAM = false } EventType=SUBSCRIPTION_DATA updateCount = 1 correlationID = User: 2 messageType = MarketDataEvents MarketDataEvents = { LAST_ALL_SESSIONS = 93.0 BID_ALL_SESSION = 92.92 ASK_ALL_SESSION = 92.95 TRADE_SIZE_ALL_SESSIONS_RT = 0 IS_DELAYED_STREAM = false }
B Java Examples
218
// AsynchronousEventHandling.java package BloombergLP; import java.io.IOException; import import import import import import import import import com.bloomberglp.blpapi.CorrelationID; com.bloomberglp.blpapi.Event; com.bloomberglp.blpapi.EventHandler; com.bloomberglp.blpapi.Message; com.bloomberglp.blpapi.MessageIterator; com.bloomberglp.blpapi.Request; com.bloomberglp.blpapi.Service; com.bloomberglp.blpapi.Session; com.bloomberglp.blpapi.SessionOptions;
public class AsynchronousEventHandling { public static void main(String[] args) throws Exception { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session = new Session(sessionOptions, new MyEventHandler()); session.startAsync(); // Wait for events Object object = new Object(); synchronized (object) { object.wait(); } } }
B Java Examples
219
class MyEventHandler implements EventHandler { void dumpEvent(Event event){ System.out.println("eventType=" + event.eventType()); MessageIterator messageIterator = event.messageIterator(); while (messageIterator.hasNext()){ Message message = messageIterator.next(); System.out.println("messageType=" + message.messageType()); System.out.println("CorrelationID=" + message.correlationID()); try { message.print(System.out); } catch (IOException e) { e.printStackTrace(); } } } public void processEvent(Event event, Session session) { switch (event.eventType().intValue()) { case Event.EventType.Constants.SESSION_STATUS: { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); if (message.messageType().equals("SessionStarted")) { try { session.openServiceAsync("//blp/refdata", new CorrelationID(99)); } catch (Exception e) { System.err.println( "Could not open //blp/refdata for async"); System.exit(1); } } else { System.err.println("Could not start session."); System.exit(1); } } break; }
B Java Examples
220
case Event.EventType.Constants.SERVICE_STATUS: { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); if (message.correlationID().value() == 99 && message.messageType().equals("ServiceOpened")) { //Construct and issue a Request Service service = session.getService("//blp/refdata"); Request request = service.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "LAST_PRICE"); try { session.sendRequest(request, new CorrelationID(86)); } catch (Exception e) { System.err.println("Could not send request"); System.exit(1); } } else { System.out.println("Unexpected SERVICE_STATUS message:"); try { message.print(System.err); } catch (Exception e){ e.printStackTrace(); } } } break; }
B Java Examples
221
case Event.EventType.Constants.PARTIAL_RESPONSE: {// dumpEvent(event); // Handle Partial Response break; } case Event.EventType.Constants.RESPONSE:{ dumpEvent(event); // Handle final response // Now, the example is complete. Shut it down. try { session.stop(Session.StopOption.ASYNC); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("terminate process from handler"); System.exit(0); break; } default: { System.err.println("unexpected Event"); dumpEvent(event); System.exit(1); break; } } } }
B Java Examples
222
// RequestResponseMultiple.java package BloombergLP; import import import import import import import import import com.bloomberglp.blpapi.CorrelationID; com.bloomberglp.blpapi.Element; com.bloomberglp.blpapi.Event; com.bloomberglp.blpapi.Message; com.bloomberglp.blpapi.MessageIterator; com.bloomberglp.blpapi.Request; com.bloomberglp.blpapi.Service; com.bloomberglp.blpapi.Session; com.bloomberglp.blpapi.SessionOptions;
public class RequestResponseMultiple { public static void main(String[] args) throws Exception { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session = new Session(sessionOptions); if (!session.start()) { System.out.println("Could not start session."); System.exit(1); } if (!session.openService("//blp/refdata")) { System.out.println("Could not open service " + "//blp/refdata"); System.exit(1); } Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.getElement("securities").appendValue("AAPL US Equity"); request.getElement("securities").appendValue("IBM US Equity"); request.getElement("securities").appendValue( "BLAHBLAHBLAH US Equity"); request.getElement("fields").appendValue("PX_LAST"); // Last Price request.getElement("fields").appendValue("DS002"); // Description request.getElement("fields").appendValue("VWAP_VOLUME"); // Volume used to calculate the Volume Weighted Average Price (VWAP) session.sendRequest(request, new CorrelationID(1));
B Java Examples
223
boolean continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: // final response continueToLoop = false; // fall through case Event.EventType.Constants.PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } } } private static void handleResponseEvent(Event event) throws Exception { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); Element ReferenceDataResponse = message.asElement(); if (ReferenceDataResponse.hasElement("responseError")) { System.exit(1); } Element securityDataArray = ReferenceDataResponse.getElement("securityData"); int numItems = securityDataArray.numValues(); for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.getValueAsElement(i); String security = securityData.getElementAsString( "security"); int sequenceNumber = securityData.getElementAsInt32("sequenceNumber"); if (securityData.hasElement("securityError")) { Element securityError = securityData.getElement("securityError"); System.out.println("* security =" + security); //Element securityError = securityData.getElement( "securityError"); securityError.print(System.out); return; } else { Element fieldData = securityData.getElement("fieldData"); double px_last = fieldData.getElementAsFloat64( "PX_LAST"); String ds002 = fieldData.getElementAsString( "DS002"); double vwap_volume = fieldData.getElementAsFloat64("VWAP_VOLUME");
B Java Examples
224
// Individually output each value System.out.println("* security =" System.out.println("* sequenceNumber=" System.out.println("* px_last =" System.out.println("* ds002 =" System.out.println("* vwap_volume =" System.out.println(""); } } } }
+ + + + +
private static void handleOtherEvent(Event event) throws Exception { System.out.println("EventType=" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType=" + message.messageType()); message.print(System.out); if (Event.EventType.Constants.SESSION_STATUS == event.eventType().intValue() && "SessionTerminated" == message.messageType().toString()){ System.out.println("Terminating: " + message.messageType()); System.exit(1); } } } }
B Java Examples
225
* security =BLAHBLAHBLAH US Equity securityError = { source = 193::bbdbs1 code = 15 category = BAD_SEC message = Unknown/Invalid security [nid:193] subcategory = INVALID_SECURITY }
B Java Examples
226
// SubscriptionMultiple.java package BloombergLP; import java.io.IOException; import java.io.PrintStream; import import import import import import import import import com.bloomberglp.blpapi.CorrelationID; com.bloomberglp.blpapi.Event; com.bloomberglp.blpapi.EventHandler; com.bloomberglp.blpapi.Message; com.bloomberglp.blpapi.MessageIterator; com.bloomberglp.blpapi.Session; com.bloomberglp.blpapi.SessionOptions; com.bloomberglp.blpapi.Subscription; com.bloomberglp.blpapi.SubscriptionList;
class SubscriptionEventHandler implements EventHandler { private String d_label; private PrintStream d_printStream; // CREATORS SubscriptionEventHandler(String label, PrintStream printStream) { d_label = label; d_printStream = printStream; } // MANIPULATORS public void processEvent(Event event, Session session) { switch (event.eventType().intValue()) { case Event.EventType.Constants.SUBSCRIPTION_DATA: handleDataEvent(event, session); break; case Event.EventType.Constants.SESSION_STATUS: case Event.EventType.Constants.SERVICE_STATUS: case Event.EventType.Constants.SUBSCRIPTION_STATUS: handleStatusEvent(event, session); break; default: { handleOtherEvent(event, session); break; } } }
B Java Examples
227
private void dumpEvent(Event event){ d_printStream.println("handler label=" + d_label); d_printStream.println("eventType=" + event.eventType()); MessageIterator messageIterator = event.messageIterator(); while (messageIterator.hasNext()){ Message message = messageIterator.next(); d_printStream.println("messageType=" + message.messageType()); d_printStream.println("CorrelationID=" + message.correlationID()); try { message.print(d_printStream); } catch (IOException e) { e.printStackTrace(); } } } private void handleDataEvent(Event event, Session session){ d_printStream.println("handleDataEvent: enter"); dumpEvent(event); d_printStream.println("handleDataEvent: leave"); } private void handleStatusEvent(Event event, Session session){ d_printStream.println("handleStatusEvent: enter"); dumpEvent(event); d_printStream.println("handleStatusEvent: leave"); } private void handleOtherEvent(Event event, Session session){ d_printStream.println("handleOtherEvent: enter"); dumpEvent(event); d_printStream.println("handleOtherEvent: leave"); } } public class SubscriptionMultiple { public static void main(String[] args) throws Exception{ SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session = new Session(sessionOptions, new SubscriptionEventHandler( "myLabel", System.out)); if (!session.start()) { System.out.println("Could not start session."); System.exit(1); } if (!session.openService("//blp/mktdata")) { System.out.println("Could not open service " + "//blp/mktdata"); System.exit(1); }
B Java Examples
228
SubscriptionList subscriptions = new SubscriptionList(); subscriptions.add(new Subscription("IBM US Equity", "LAST_TRADE", new CorrelationID(10))); subscriptions.add(new Subscription("/ticker/GOOG US Equity", "BID,ASK,LAST_PRICE", new CorrelationID(20))); subscriptions.add(new Subscription("MSFTT US Equity", "LAST_PRICE", "interval=.5", new CorrelationID(30))); subscriptions.add(new Subscription( "/cusip/097023105?fields=LAST_PRICE&interval=5.0", //BA US Equity new CorrelationID(40))); session.subscribe(subscriptions); // Wait for events Object object = new Object(); synchronized (object) { object.wait(); } } }
B Java Examples
229
B Java Examples
230
MarketDataEvents = { LAST_PRICE = 343.32 BID = 343.43 ASK = 343.44 VOLUME = 7283742 HIGH = 345.05 LOW = 340.11 BEST_BID = 343.43 BEST_ASK = 343.44 LAST_TRADE = 343.32 OPEN = 344.54 PREV_SES_LAST_PRICE = 348.67 INDICATIVE_FAR = 343.16 INDICATIVE_NEAR = 343.16 VWAP = 342.842 THEO_PRICE = 343.16 LAST_ALL_SESSIONS = 344.2 IMBALANCE_INDIC_RT = NOIM BID_ALL_SESSION = 343.4 ASK_ALL_SESSION = 344.2 TRADING_DT_REALTIME = 2009-01-29+00:00 EQY_TURNOVER_REALTIME = 2.4559597933911133E9 LAST_UPDATE_BID_RT = 21:00:00.000+00:00 LAST_UPDATE_ASK_RT = 21:00:00.000+00:00 TOT_CALL_VOLUME_CUR_DAY_RT = 3644 TOT_PUT_VOLUME_CUR_DAY_RT = 3623 TOT_OPT_VOLUME_CUR_DAY_RT = 7267 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 0 IN_AUCTION_RT = false RT_API_MACHINE = n242 ALL_PRICE_SIZE = 250 ALL_PRICE = 344.2 VOLUME_THEO = 732968 BID_ASK_TIME = 21:00:00.000+00:00 LAST_AT_TRADE_TDY = 0.0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.0 HIGH_YLD_TDY = 0.0 LOW_YLD_TDY = 0.0 LAST_YLD_TDY = 0.0 MID_TDY = 0.0 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -5.35 RT_PX_CHG_PCT_1D = -1.5344 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 344.54 ASK_SIZE_TDY = 1 BID_SIZE_TDY = 7 VOLUME_TDY = 7283742 LAST_PRICE_TDY = 343.32
B Java Examples
231
BID_TDY = 343.43 ASK_TDY = 343.44 HIGH_TDY = 345.05 LOW_TDY = 340.11 BID_YLD_TDY = 0.0 ASK_YLD_TDY = 0.0 LAST2_PRICE = 340.54 LAST_DIR = 1 LAST2_DIR = -1 BID_DIR = 1 ASK_DIR = -1 BID2 = 343.4 ASK2 = 343.45 ASK_SIZE = 1 BID_SIZE = 7 TIME = 22:20:00.000+00:00 API_MACHINE = n242 TRADE_SIZE_ALL_SESSIONS_RT = 250 EID = 14005 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 20 MarketDataEvents = { VOLUME = 7283742 LAST_AT_TRADE_TDY = 0.0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.0 HIGH_YLD_TDY = 0.0 LOW_YLD_TDY = 0.0 LAST_YLD_TDY = 0.0 MID_TDY = 0.0 RT_PX_CHG_NET_1D = -5.35 RT_PX_CHG_PCT_1D = -1.5344 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 344.54 ASK_SIZE_TDY = 1 BID_SIZE_TDY = 7 VOLUME_TDY = 7283742 LAST_PRICE_TDY = 343.32 BID_TDY = 343.43 ASK_TDY = 343.44 HIGH_TDY = 345.05 LOW_TDY = 340.11 BID_YLD_TDY = 0.0 ASK_YLD_TDY = 0.0
B Java Examples
232
EID = 14005 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 10 MarketDataEvents = { LAST_PRICE = 92.51 BID = 92.56 ASK = 92.62 VOLUME = 9233664 HIGH = 94.58 LOW = 92.02 BEST_BID = 92.56 BEST_ASK = 92.62 LAST_TRADE = 92.51 OPEN = 93.58 PREV_SES_LAST_PRICE = 94.82 IMBALANCE_ASK = 92.52 ORDER_IMB_SELL_VOLUME = 34800.0 VWAP = 93.2768 THEO_PRICE = 92.52 LAST_ALL_SESSIONS = 92.49 IMBALANCE_INDIC_RT = SELL BID_ALL_SESSION = 92.31 ASK_ALL_SESSION = 92.5 TRADING_DT_REALTIME = 2009-01-29+00:00 EQY_TURNOVER_REALTIME = 8.743154979367981E8 LAST_UPDATE_BID_RT = 21:00:00.000+00:00 LAST_UPDATE_ASK_RT = 21:00:00.000+00:00 NYSE_LRP_HIGH_PRICE_RT = 93.63 NYSE_LRP_LOW_PRICE_RT = 91.63 NYSE_LRP_SEND_TIME_RT = 20:59:52.000+00:00 TOT_CALL_VOLUME_CUR_DAY_RT = 4950 TOT_PUT_VOLUME_CUR_DAY_RT = 7369 TOT_OPT_VOLUME_CUR_DAY_RT = 12319 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 1 IN_AUCTION_RT = false RT_API_MACHINE = p065 ALL_PRICE_SIZE = 200 ALL_PRICE = 92.5 VOLUME_THEO = 467100 BID_ASK_TIME = 21:00:00.000+00:00 LAST_AT_TRADE_TDY = 0.0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.0 HIGH_YLD_TDY = 0.0 LOW_YLD_TDY = 0.0 LAST_YLD_TDY = 0.0 MID_TDY = 0.0
B Java Examples
233
SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -2.31 RT_PX_CHG_PCT_1D = -2.43619 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 93.58 ASK_SIZE_TDY = 5 BID_SIZE_TDY = 1 VOLUME_TDY = 9233664 LAST_PRICE_TDY = 92.51 BID_TDY = 92.56 ASK_TDY = 92.62 HIGH_TDY = 94.58 LOW_TDY = 92.02 BID_YLD_TDY = 0.0 ASK_YLD_TDY = 0.0 LAST2_PRICE = 92.51 LAST_DIR = -1 LAST2_DIR = 1 BID_DIR = -1 ASK_DIR = 1 BID2 = 92.56 ASK2 = 92.61 ASK_SIZE = 5 BID_SIZE = 1 TIME = 21:15:12.000+00:00 API_MACHINE = p065 TRADE_SIZE_ALL_SESSIONS_RT = 500 EID = 14003 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 10 MarketDataEvents = { VOLUME = 9233664 VWAP = 93.2764 LAST_ALL_SESSIONS = 92.5 BID_ALL_SESSION = 92.31 ASK_ALL_SESSION = 92.5 EQY_TURNOVER_REALTIME = 8.743154979367981E8 ALL_PRICE_SIZE = 200 ALL_PRICE = 92.5 LAST_AT_TRADE_TDY = 0.0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.0 HIGH_YLD_TDY = 0.0 LOW_YLD_TDY = 0.0
B Java Examples
234
LAST_YLD_TDY = 0.0 MID_TDY = 0.0 RT_PX_CHG_NET_1D = -2.31 RT_PX_CHG_PCT_1D = -2.43619 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 93.58 ASK_SIZE_TDY = 5 BID_SIZE_TDY = 1 VOLUME_TDY = 9233664 LAST_PRICE_TDY = 92.51 BID_TDY = 92.56 ASK_TDY = 92.62 HIGH_TDY = 94.58 LOW_TDY = 92.02 BID_YLD_TDY = 0.0 ASK_YLD_TDY = 0.0 TRADE_SIZE_ALL_SESSIONS_RT = 200 EID = 14003 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 40 MarketDataEvents = { LAST_PRICE = 40.71 BID = 40.71 ASK = 40.77 VOLUME = 8446464 HIGH = 42.76 LOW = 40.37 RT_OPEN_INTEREST = 7953467 BEST_BID = 40.71 BEST_ASK = 40.77 LAST_TRADE = 40.71 OPEN = 42.76 PREV_SES_LAST_PRICE = 43.24 VWAP = 40.9212 TRADING_DT_REALTIME = 2009-01-29+00:00 EQY_TURNOVER_REALTIME = 3.45612128E8 PREV_TRADING_DT_REALTIME = 2009-01-29+00:00 RT_API_MACHINE = p164 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -2.53 RT_PX_CHG_PCT_1D = -5.85106 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 42.76 ASK_SIZE_TDY = 124
B Java Examples
235
BID_SIZE_TDY = 228 VOLUME_TDY = 8446464 LAST_PRICE_TDY = 40.71 BID_TDY = 40.71 ASK_TDY = 40.77 HIGH_TDY = 42.76 LOW_TDY = 40.37 RT_PRICING_SOURCE = US ASK_SIZE = 124 BID_SIZE = 228 TIME = 21:15:02.000+00:00 API_MACHINE = p164 EXCH_CODE_LAST = N EXCH_CODE_BID = N EXCH_CODE_ASK = N EID = 14003 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 40 MarketDataEvents = { LAST_ALL_SESSIONS = 40.71 BID_ALL_SESSION = 40.71 ASK_ALL_SESSION = 40.77 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -2.53 RT_PX_CHG_PCT_1D = -5.85106 TIME = 21:15:02.000+00:00 TRADE_SIZE_ALL_SESSIONS_RT = 0 IS_DELAYED_STREAM = false } handleDataEvent: leave
public class AuthorizationByIpAddress { private static void dumpEvent(Event event) throws IOException{ System.out.println("eventType=" + event.eventType()); MessageIterator messageIterator = event.messageIterator(); while (messageIterator.hasNext()){ Message message = messageIterator.next(); System.out.println("messageType=" + message.messageType()); System.out.println("CorrelationID=" + message.correlationID()); message.print(System.out); } } private static boolean hasMessageType(Event event, String messageType) { MessageIterator messageIterator = event.messageIterator(); while (messageIterator.hasNext()){ Message message = messageIterator.next(); if (message.messageType().equals(messageType)) { return true; } } return false; }
B Java Examples
237
private static void printSecurityData(String security, int sequenceNumber, Element securityData) { Element fieldData = securityData.getElement("fieldData"); double px_last = fieldData.getElementAsFloat64("PX_LAST"); String ds002 = fieldData.getElementAsString("DS002"); double vwap_volume = fieldData.getElementAsFloat64("VWAP_VOLUME"); // Individually output each value System.out.println("* security =" System.out.println("* sequenceNumber=" System.out.println("* px_last =" System.out.println("* ds002 =" System.out.println("* vwap_volume =" System.out.println(""); } private static void handleResponseEvent(Event event, Identity identity) throws IOException { MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); Element ReferenceDataResponse = message.asElement(); if (ReferenceDataResponse.hasElement("responseError")) { message.print(System.out); System.exit(1); } Element securityDataArray = ReferenceDataResponse.getElement("securityData"); int numItems = securityDataArray.numValues(); for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.getValueAsElement(i); String security = securityData.getElementAsString("security"); int sequenceNumber = securityData.getElementAsInt32("sequenceNumber"); if (securityData.hasElement("securityError")) { Element securityError = securityData.getElement("securityError"); System.out.println("* security =" + security); securityError.print(System.out); return; } + + + + + security); sequenceNumber); px_last); ds002); vwap_volume);
B Java Examples
238
ArrayList missingEntitlements = new ArrayList(); Element neededEntitlements = securityData.hasElement("eidData") ? securityData.getElement("eidData") : null; if (null == neededEntitlements) { System.out.println("no entitlements needed"); System.out.println(); printSecurityData(security, sequenceNumber, securityData); } else if (identity.hasEntitlements(neededEntitlements, message.service(), missingEntitlements)) { System.out.println("user has the needed Entitlements for: " + security); System.out.println("provide data to the requesting user"); System.out.println(); printSecurityData(security, sequenceNumber, securityData); } else { System.out.println("user lacks entitlements for: " + security); System.out.println("neededEntitlements = " + neededEntitlements); System.out.println("missingEntitlements = " + missingEntitlements); System.out.println(); System.out.println( "do not provide data to the requesting user"); } } } } private static void handleOtherEvent(Event event) throws Exception { System.out.println("EventType=" + event.eventType()); MessageIterator iter = event.messageIterator(); while (iter.hasNext()) { Message message = iter.next(); System.out.println("correlationID=" + message.correlationID()); System.out.println("messageType=" + message.messageType()); message.print(System.out); if (Event.EventType.Constants.SESSION_STATUS == event.eventType().intValue() && "SessionTerminated" == message.messageType().toString()){ System.out.println("Terminating: " + message.messageType()); System.exit(1); } } }
B Java Examples
239
static private boolean handleAuthenticationResponseEvent(Event event) throws IOException{ if (hasMessageType(event, "AuthorizationSuccess")){ System.out.println("Authorization OK"); return true; } else if (hasMessageType(event, "AuthorizationFailure")) { System.out.println("Authorization Problem"); dumpEvent(event); } else { System.out.println("Authorization: Other Problem"); dumpEvent(event); } return false; } public static void main(String[] args) throws Exception{ int uuid = uuid; String ipAddress = ipAddress; SessionOptions sessionOptions = new SessionOptions(); sessionOptions.setServerHost("localhost"); //default sessionOptions.setServerPort(8194); //default Session session = new Session(sessionOptions); if (!session.start()) { System.out.println("Could not start session."); System.exit(1); } if (!session.openService("//blp/apiauth")) { System.out.println("Could not open service " + "//blp/apiauth"); System.exit(1); }
B Java Examples
240
Service apiAuthSvc = session.getService("//blp/apiauth"); Request authorizationRequest = apiAuthSvc.createAuthorizationRequest(); authorizationRequest.set("uuid", uuid); authorizationRequest.set("ipAddress", ipAddress); Identity identity = session.createIdentity(); CorrelationID authorizationRequestID = new CorrelationID(10); session.sendAuthorizationRequest(authorizationRequest, identity, authorizationRequestID); System.out.println("sent Authorization Request using ipAddress"); // Wait for 'AuthorizationSuccess' message which indicates // that 'identity' can be used. for (boolean continueToLoop = true; continueToLoop; ) { Event event = session.nextEvent(); //dumpEvent(event); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: if (!handleAuthenticationResponseEvent(event)) { System.out.println("Authorization Failed"); System.exit(1); } continueToLoop = false; break; default: handleOtherEvent(event); break; } } if (!session.openService("//blp/refdata")) { System.out.println("Could not open service " + "//blp/refdata"); System.exit(1); } Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "VOD LN Equity"); request.append("fields", "PX_LAST"); request.append("fields", "DS002"); request.append("fields", "VWAP_VOLUME"); request.set("returnEids", true); // new CorrelationID requestID = new CorrelationID(20); session.sendRequest(request, requestID);
B Java Examples
241
for (boolean continueToLoop = true; continueToLoop; ) { Event event = session.nextEvent(); dumpEvent(event); switch (event.eventType().intValue()) { case Event.EventType.Constants.RESPONSE: // final event continueToLoop = false; // fall through case Event.EventType.Constants.PARTIAL_RESPONSE: handleResponseEvent(event, identity); // new argument break; default: handleOtherEvent(event); break; } } } }
B Java Examples
242
C .Net Examples
This section contains the following code examples:
RequestResponseParadigm on page 244 Subscription Paradigm on page 247 Asynchronous Event Handling on page 253 Request Response Multiple on page 258 Subscription Multiple on page 262
C .Net Examples
243
C.1 RequestResponseParadigm
// RequestResponseParadigm.cs using System; using System.Collections.Generic; using System.Text; using using using using using using using using CorrelationID Element Event Message Request Service Session SessionOptions = = = = = = = = Bloomberglp.Blpapi.CorrelationID; Bloomberglp.Blpapi.Element; Bloomberglp.Blpapi.Event; Bloomberglp.Blpapi.Message; Bloomberglp.Blpapi.Request; Bloomberglp.Blpapi.Service; Bloomberglp.Blpapi.Session; Bloomberglp.Blpapi.SessionOptions;
namespace RequestResponseParadigm { class RequestResponseParadigm { static void Main(string[] args) { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerHost = "localhost"; sessionOptions.ServerPort = 8194; Session session = new Session(sessionOptions); if (!session.Start()) { System.Console.WriteLine("Could not start session."); System.Environment.Exit(1); } if (!session.OpenService("//blp/refdata")) { System.Console.WriteLine("Could not open service " + "//blp/refdata"); System.Environment.Exit(1); } CorrelationID requestID = new CorrelationID(1); Service refDataSvc = session.GetService("//blp/refdata"); Request request = refDataSvc.CreateRequest("ReferenceDataRequest"); request.Append("securities", "IBM US Equity"); request.Append("fields", "PX_LAST"); session.SendRequest(request, requestID);
C .Net Examples
244
bool continueToLoop = true; while (continueToLoop) { Event eventObj = session.NextEvent(); switch (eventObj.Type) { case Event.EventType.RESPONSE: // final event continueToLoop = false; handleResponseEvent(eventObj); break; case Event.EventType.PARTIAL_RESPONSE: handleResponseEvent(eventObj); break; default: handleOtherEvent(eventObj); break; } } } private static void handleResponseEvent(Event eventObj) { System.Console.WriteLine("EventType =" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("correlationID=" + message.CorrelationID); System.Console.WriteLine("messageType =" + message.MessageType); message.Print(System.Console.Out); } } private static void handleOtherEvent(Event eventObj) { System.Console.WriteLine("EventType=" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("correlationID=" + message.CorrelationID); System.Console.WriteLine("messageType=" + message.MessageType); message.Print(System.Console.Out); if (Event.EventType.SESSION_STATUS == eventObj.Type && message.MessageType.Equals("SessionTerminated")) { System.Console.WriteLine("Terminating: " + message.MessageType); System.Environment.Exit(1); } } } } } C .Net Examples 245
C .Net Examples
246
// SubscriptionParadigm.cs using System; using System.Collections.Generic; using System.Text; using using using using using using using CorrelationID Event EventHandler Message Session SessionOptions Subscription = = = = = = = Bloomberglp.Blpapi.CorrelationID; Bloomberglp.Blpapi.Event; Bloomberglp.Blpapi.EventHandler; Bloomberglp.Blpapi.Message; Bloomberglp.Blpapi.Session; Bloomberglp.Blpapi.SessionOptions; Bloomberglp.Blpapi.Subscription;
namespace SubscriptionParadigm { class SubscriptionParadigm { static void Main(string[] args) { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerHost = "localhost"; sessionOptions.ServerPort = 8194; Session session = new Session(sessionOptions); if (!session.Start()) { System.Console.WriteLine("Could not start session."); System.Environment.Exit(1); } if (!session.OpenService("//blp/mktdata")) { System.Console.WriteLine("Could not open service " + "//blp/mktdata"); System.Environment.Exit(1); } CorrelationID subscriptionID = new CorrelationID(2); List<Subscription> subscriptions = new List<Subscription>(); subscriptions.Add(new Subscription("AAPL US Equity", "LAST_PRICE", subscriptionID)); session.Subscribe(subscriptions);
C .Net Examples
247
int updateCount = 0; while (true) { Event eventObj = session.NextEvent(); switch (eventObj.Type) { case Event.EventType.SUBSCRIPTION_DATA: handleDataEvent(eventObj, updateCount++); break; default: handleOtherEvent(eventObj); break; } } } private static void handleDataEvent(Event eventObj, int updateCount) { System.Console.WriteLine("EventType=" + eventObj.Type); System.Console.WriteLine("updateCount = " + updateCount); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("correlationID = " + message.CorrelationID); System.Console.WriteLine("messageType = " + message.MessageType); message.Print(System.Console.Out); } } private static void handleOtherEvent(Event eventObj) { System.Console.WriteLine("EventType=" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("correlationID=" + message.CorrelationID); System.Console.WriteLine("messageType=" + message.MessageType); message.Print(System.Console.Out); if (Event.EventType.SESSION_STATUS == eventObj.Type && message.MessageType.Equals("SessionTerminated")) { System.Console.WriteLine("Terminating: " + message.MessageType); System.Environment.Exit(1); } } } } }
C .Net Examples
248
C .Net Examples
249
BID_ASK_TIME = 18:45:46.000+00:00 LAST_AT_TRADE_TDY = 0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0 HIGH_YLD_TDY = 0 LOW_YLD_TDY = 0 LAST_YLD_TDY = 0 MID_TDY = 0 SIZE_LAST_TRADE_TDY = 100 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -2.11 RT_PX_CHG_PCT_1D = -2.26882 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 92.6 ASK_SIZE_TDY = 19 BID_SIZE_TDY = 5 VOLUME_TDY = 14304168 LAST_PRICE_TDY = 90.89 BID_TDY = 90.88 ASK_TDY = 90.9 HIGH_TDY = 93.62 LOW_TDY = 90.6 BID_YLD_TDY = 0 ASK_YLD_TDY = 0 LAST2_PRICE = 90.89 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = -1 ASK_DIR = 1 BID2 = 90.88 ASK2 = 90.9 SIZE_LAST_TRADE = 100 ASK_SIZE = 19 BID_SIZE = 5 TIME = 18:45:45.000+00:00 API_MACHINE = p060 TRADE_SIZE_ALL_SESSIONS_RT = 100 EID = 14005 IS_DELAYED_STREAM = false } EventType=SUBSCRIPTION_DATA updateCount = 1 correlationID = User: 2 messageType = MarketDataEvents MarketDataEvents = { LAST_PRICE = 90.89 BID = 90.88 ASK = 90.9 VOLUME = 14304168 HIGH = 93.62 LOW = 90.6
C .Net Examples
250
BEST_BID = 90.88 BEST_ASK = 90.9 LAST_TRADE = 90.89 VWAP = 91.6348 LAST_ALL_SESSIONS = 90.89 BID_ALL_SESSION = 90.88 ASK_ALL_SESSION = 90.9 EQY_TURNOVER_REALTIME = 1294308731.96565 LAST_UPDATE_BID_RT = 18:45:46.000+00:00 LAST_UPDATE_ASK_RT = 18:45:46.000+00:00 TOT_CALL_VOLUME_CUR_DAY_RT = 12783 TOT_PUT_VOLUME_CUR_DAY_RT = 17211 TOT_OPT_VOLUME_CUR_DAY_RT = 29994 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 1 IN_AUCTION_RT = false ALL_PRICE_SIZE = 100 ALL_PRICE = 90.89 BID_ASK_TIME = 18:45:46.000+00:00 LAST_AT_TRADE_TDY = 0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0 HIGH_YLD_TDY = 0 LOW_YLD_TDY = 0 LAST_YLD_TDY = 0 MID_TDY = 0 SIZE_LAST_TRADE_TDY = 100 RT_PX_CHG_NET_1D = -2.11 RT_PX_CHG_PCT_1D = -2.26882 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 92.6 ASK_SIZE_TDY = 19 BID_SIZE_TDY = 5 VOLUME_TDY = 14304168 LAST_PRICE_TDY = 90.89 BID_TDY = 90.88 ASK_TDY = 90.9 HIGH_TDY = 93.62 LOW_TDY = 90.6 BID_YLD_TDY = 0 ASK_YLD_TDY = 0 LAST2_PRICE = 90.89 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = -1 ASK_DIR = 1 BID2 = 90.88 ASK2 = 90.9 SIZE_LAST_TRADE = 100 ASK_SIZE = 19 BID_SIZE = 5
C .Net Examples
251
C .Net Examples
252
// AsynchronousEventHandling.cs using System; using System.Collections.Generic; using System.Text; using using using using using using using using CorrelationID Event EventHandler Message Request Service Session SessionOptions = = = = = = = = Bloomberglp.Blpapi.CorrelationID; Bloomberglp.Blpapi.Event; Bloomberglp.Blpapi.EventHandler; Bloomberglp.Blpapi.Message; Bloomberglp.Blpapi.Request; Bloomberglp.Blpapi.Service; Bloomberglp.Blpapi.Session; Bloomberglp.Blpapi.SessionOptions;
namespace BloombergLP { class AsynchronousEventHandling { static void Main(string[] args) { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerHost = "localhost"; sessionOptions.ServerPort = 8194; Session session = new Session(sessionOptions, new EventHandler(ProcessEvent)); session.StartAsync(); // Wait for events Object obj = new Object(); lock (obj) { System.Threading.Monitor.Wait(obj); } } static void dumpEvent(Event eventObj) { System.Console.WriteLine("eventType=" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("messageType=" + message.MessageType); System.Console.WriteLine("CorrelationID=" + message.CorrelationID);
C .Net Examples
253
try { message.Print(System.Console.Out); } catch (System.IO.IOException e) { System.Console.WriteLine(e); } } } static public void ProcessEvent(Event eventObj, Session session) { switch (eventObj.Type) { case Event.EventType.SESSION_STATUS: { foreach (Message message in eventObj.GetMessages()) { if (message.MessageType.Equals("SessionStarted")) { try { session.OpenServiceAsync( "//blp/refdata", new CorrelationID(99)); } catch (Exception) { System.Console.Error.WriteLine( "Could not open //blp/refdata for async"); System.Environment.Exit(1); } } else { System.Console.Error.WriteLine( "Could not start session."); System.Environment.Exit(1); } } break; }
C .Net Examples
254
case Event.EventType.SERVICE_STATUS: { foreach (Message message in eventObj.GetMessages()) { if (message.CorrelationID.Value == 99 && message.MessageType.Equals("ServiceOpened")) { //Construct and issue a Request Service service = session.GetService( "//blp/refdata"); Request request = service.CreateRequest( "ReferenceDataRequest"); request.Append("securities", "IBM US Equity"); request.Append("fields", "PX_LAST"); try { session.SendRequest( request, new CorrelationID(86)); } catch (Exception) { System.Console.Error.WriteLine( "Could not send request"); System.Environment.Exit(1); } } else { System.Console.WriteLine( "Unexpected SERVICE_STATUS message:"); try { message.Print(System.Console.Error); } catch (Exception e) { System.Console.WriteLine(e); } } } break; }
C .Net Examples
255
case Event.EventType.PARTIAL_RESPONSE: {// dumpEvent(eventObj); // Handle Partial Response break; } case Event.EventType.RESPONSE: { dumpEvent(eventObj); // Handle final response // Now, the example is complete. Shut it down. try { session.Stop(Session.StopOption.ASYNC); } catch (System.Threading.ThreadInterruptedException e) { System.Console.WriteLine(e); } System.Console.Error.WriteLine( "terminate process from handler"); System.Environment.Exit(0); break; } default: { break; } case Event.EventType.RESPONSE: { dumpEvent(eventObj); // Handle final response System.Console.WriteLine("unexpected Event"); dumpEvent(eventObj); System.Environment.Exit(1); break; } } } } }
C .Net Examples
256
C .Net Examples
257
namespace RequestResponseMultiple { class RequestResponseMultiple { static void Main(string[] args) { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerHost = "localhost"; sessionOptions.ServerPort = 8194; Session session = new Session(sessionOptions); if (!session.Start()) { System.Console.WriteLine("Could not start session."); System.Environment.Exit(1); } if (!session.OpenService("//blp/refdata")) { System.Console.WriteLine("Could not open service " + "//blp/refdata"); System.Environment.Exit(1); } Service refDataSvc = session.GetService("//blp/refdata"); Request request = refDataSvc.CreateRequest( "ReferenceDataRequest"); request.GetElement("securities").AppendValue("AAPL US Equity"); request.GetElement("securities").AppendValue("IBM US Equity"); request.GetElement("securities").AppendValue( "BLAHBLAHBLAH US Equity"); request.GetElement("fields").AppendValue("PX_LAST"); // Last Price request.GetElement("fields").AppendValue("DS002"); // Description request.GetElement("fields").AppendValue("VWAP_VOLUME"); // Volume used to calculate the Volume Weighted Average Price session.SendRequest(request, new CorrelationID(1));
C .Net Examples
258
bool continueToLoop = true; while (continueToLoop) { Event eventObj = session.NextEvent(); switch (eventObj.Type) { case Event.EventType.RESPONSE: // final response continueToLoop = false; handleResponseEvent(eventObj); break; case Event.EventType.PARTIAL_RESPONSE: handleResponseEvent(eventObj); break; default: handleOtherEvent(eventObj); break; } } } private static void handleResponseEvent(Event eventObj) { foreach (Message message in eventObj.GetMessages()) { Element ReferenceDataResponse = message.AsElement; if (ReferenceDataResponse.HasElement("responseError")) { System.Environment.Exit(1); } Element securityDataArray = ReferenceDataResponse.GetElement("securityData"); int numItems = securityDataArray.NumValues; for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.GetValueAsElement(i); String security = securityData.GetElementAsString("security"); int sequenceNumber = securityData.GetElementAsInt32("sequenceNumber"); if (securityData.HasElement("securityError")) { Element securityError = securityData.GetElement("securityError"); System.Console.WriteLine("* security =" + security); Element securityError = securityData.GetElement("securityError"); securityError.Print(System.Console.Out); return; }
C .Net Examples
259
else { Element fieldData = securityData.GetElement("fieldData"); double px_last = fieldData.GetElementAsFloat64("PX_LAST"); String ds002 = fieldData.GetElementAsString("DS002"); double vwap_volume = fieldData.GetElementAsFloat64("VWAP_VOLUME"); // Individually output each value System.Console.WriteLine("* security =" security); System.Console.WriteLine("* sequenceNumber=" sequenceNumber); System.Console.WriteLine("* px_last =" px_last); System.Console.WriteLine("* ds002 =" ds002); System.Console.WriteLine("* vwap_volume =" vwap_volume); System.Console.WriteLine(""); } } } } private static void handleOtherEvent(Event eventObj) { System.Console.WriteLine("EventType=" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { System.Console.WriteLine("correlationID=" + message.CorrelationID); System.Console.WriteLine("messageType=" + message.MessageType); message.Print(System.Console.Out); if (Event.EventType.SESSION_STATUS == eventObj.Type && message.MessageType.Equals("SessionTerminated")) { System.Console.WriteLine("Terminating: " + message.MessageType); System.Environment.Exit(1); } } } } } + + + + +
C .Net Examples
260
* security =BLAHBLAHBLAH US Equity securityError = { source = 236::bbdbs2 code = 15 category = BAD_SEC message = Unknown/Invalid security [nid:236] subcategory = INVALID_SECURITY }
C .Net Examples
261
namespace SubscriptionMultiple { class SubscriptionEventHandler { private String d_label; private TextWriter d_printStream; // CREATORS public SubscriptionEventHandler(String label, TextWriter printStream) { d_label = label; d_printStream = printStream; } // MANIPULATORS public void ProcessEvent(Event eventObj, Session session) { switch (eventObj.Type) { case Event.EventType.SUBSCRIPTION_DATA: handleDataEvent(eventObj, session); break; case Event.EventType.SESSION_STATUS: case Event.EventType.SERVICE_STATUS: case Event.EventType.SUBSCRIPTION_STATUS: handleStatusEvent(eventObj, session); break; default: { handleOtherEvent(eventObj, session); break; } } }
C .Net Examples
262
private void dumpEvent(Event eventObj) { d_printStream.WriteLine("handler label=" + d_label); d_printStream.WriteLine("eventType=" + eventObj.Type); foreach (Message message in eventObj.GetMessages()) { d_printStream.WriteLine("messageType=" + message.MessageType); d_printStream.WriteLine("CorrelationID=" + message.CorrelationID); try { message.Print(d_printStream); } catch (IOException e) { System.Console.WriteLine(e); } } } private void handleDataEvent(Event eventObj, Session session) { d_printStream.WriteLine("handleDataEvent: enter"); dumpEvent(eventObj); d_printStream.WriteLine("handleDataEvent: leave"); } private void handleStatusEvent(Event eventObj, Session session) { d_printStream.WriteLine("handleStatusEvent: enter"); dumpEvent(eventObj); d_printStream.WriteLine("handleStatusEvent: leave"); } private void handleOtherEvent(Event eventObj, Session session) { d_printStream.WriteLine("handleOtherEvent: enter"); dumpEvent(eventObj); d_printStream.WriteLine("handleOtherEvent: leave"); } } class SubscriptionMultiple { static void Main(string[] args) { SessionOptions sessionOptions = new SessionOptions(); sessionOptions.ServerHost = "localhost"; sessionOptions.ServerPort = 8194; Session session = new Session(sessionOptions, new EventHandler( new SubscriptionEventHandler( "myLabel", System.Console.Out).ProcessEvent)); C .Net Examples 263
if (!session.Start()) { System.Console.WriteLine("Could not start session."); System.Environment.Exit(1); } if (!session.OpenService("//blp/mktdata")) { System.Console.WriteLine("Could not open service " + "//blp/mktdata"); System.Environment.Exit(1); } List<Subscription> subscriptions = new List<Subscription>(); subscriptions.Add(new Subscription("IBM US Equity", "LAST_TRADE", new CorrelationID(10))); subscriptions.Add(new Subscription("/ticker/GOOG US Equity", "BID,ASK,LAST_PRICE", new CorrelationID(20))); subscriptions.Add(new Subscription("MSFTT US Equity", "LAST_PRICE", "interval=.5", new CorrelationID(30))); subscriptions.Add(new Subscription( //BA US Equity "/cusip/097023105?fields=LAST_PRICE&interval=5.0", new CorrelationID(40))); session.Subscribe(subscriptions); // Wait for events Object obj = new Object(); lock (obj) { System.Threading.Monitor.Wait(obj); } } } }
C .Net Examples
264
C .Net Examples
265
handleStatusEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 20 MarketDataEvents = { LAST_PRICE = 340.7 BID = 340.74 ASK = 340.92 VOLUME = 2630520 HIGH = 348.8 LOW = 337.62 BEST_BID = 340.74 BEST_ASK = 340.92 LAST_TRADE = 340.7 OPEN = 344.69 PREV_SES_LAST_PRICE = 343.32 INDICATIVE_FAR = 344.69 INDICATIVE_NEAR = 344.69 IMBALANCE_ASK = 344.76 VWAP = 341.6714 LAST_ALL_SESSIONS = 340.7 IMBALANCE_INDIC_RT = SELL BID_ALL_SESSION = 340.74 ASK_ALL_SESSION = 340.92 TRADING_DT_REALTIME = 2009-01-30+00:00 EQY_TURNOVER_REALTIME = 891123786.45166 LAST_UPDATE_BID_RT = 18:46:07.000+00:00 LAST_UPDATE_ASK_RT = 18:46:09.000+00:00 TOT_CALL_VOLUME_CUR_DAY_RT = 2146 TOT_PUT_VOLUME_CUR_DAY_RT = 2887 TOT_OPT_VOLUME_CUR_DAY_RT = 5033 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 1 IN_AUCTION_RT = false RT_API_MACHINE = p060 ALL_PRICE_SIZE = 300 ALL_PRICE = 340.7 BID_ASK_TIME = 18:46:09.000+00:00 LAST_AT_TRADE_TDY = 0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0 HIGH_YLD_TDY = 0 LOW_YLD_TDY = 0 LAST_YLD_TDY = 0 MID_TDY = 0 SIZE_LAST_TRADE_TDY = 300 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -2.62 RT_PX_CHG_PCT_1D = -0.763135 IND_BID_FLAG = false IND_ASK_FLAG = false
C .Net Examples
266
OPEN_TDY = 344.69 ASK_SIZE_TDY = 3 BID_SIZE_TDY = 3 VOLUME_TDY = 2630520 LAST_PRICE_TDY = 340.7 BID_TDY = 340.74 ASK_TDY = 340.92 HIGH_TDY = 348.8 LOW_TDY = 337.62 BID_YLD_TDY = 0 ASK_YLD_TDY = 0 LAST2_PRICE = 340.77 LAST_DIR = -1 LAST2_DIR = -1 BID_DIR = 1 ASK_DIR = -1 BID2 = 340.74 ASK2 = 340.92 SIZE_LAST_TRADE = 300 ASK_SIZE = 3 BID_SIZE = 3 TIME = 18:46:02.000+00:00 API_MACHINE = p060 TRADE_SIZE_ALL_SESSIONS_RT = 300 EID = 14005 IS_DELAYED_STREAM = false } handleDataEvent: leave handleDataEvent: enter handler label=myLabel eventType=SUBSCRIPTION_DATA messageType=MarketDataEvents CorrelationID=User: 10 MarketDataEvents = { LAST_PRICE = 91.88 BID = 91.85 ASK = 91.88 VOLUME = 4625564 HIGH = 93.48 LOW = 91.56 BEST_BID = 91.85 BEST_ASK = 91.88 LAST_TRADE = 91.88 OPEN = 92.23 PREV_SES_LAST_PRICE = 92.51 VWAP = 92.5054 THEO_PRICE = 0 LAST_ALL_SESSIONS = 91.88 IMBALANCE_INDIC_RT = NOIM BID_ALL_SESSION = 91.85 ASK_ALL_SESSION = 91.88 TRADING_DT_REALTIME = 2009-01-30+00:00 EQY_TURNOVER_REALTIME = 426434047.387161
C .Net Examples
267
FINANCIAL_STATUS_INDICATOR_RT = 0 LAST_UPDATE_BID_RT = 18:46:09.000+00:00 LAST_UPDATE_ASK_RT = 18:46:09.000+00:00 NYSE_LRP_HIGH_PRICE_RT = 92.85 NYSE_LRP_LOW_PRICE_RT = 90.85 NYSE_LRP_SEND_TIME_RT = 18:46:08.000+00:00 TOT_CALL_VOLUME_CUR_DAY_RT = 1507 TOT_PUT_VOLUME_CUR_DAY_RT = 2122 TOT_OPT_VOLUME_CUR_DAY_RT = 3629 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 1 IN_AUCTION_RT = false RT_API_MACHINE = n160 ALL_PRICE_SIZE = 100 ALL_PRICE = 91.88 VOLUME_THEO = 0 BID_ASK_TIME = 18:46:09.000+00:00 LAST_AT_TRADE_TDY = 0 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0 HIGH_YLD_TDY = 0 LOW_YLD_TDY = 0 LAST_YLD_TDY = 0 MID_TDY = 0 SIZE_LAST_TRADE_TDY = 100 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 RT_PX_CHG_NET_1D = -0.6299 RT_PX_CHG_PCT_1D = -0.680898 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 92.23 ASK_SIZE_TDY = 1 BID_SIZE_TDY = 3 VOLUME_TDY = 4625564 LAST_PRICE_TDY = 91.88 BID_TDY = 91.85 ASK_TDY = 91.88 HIGH_TDY = 93.48 LOW_TDY = 91.56 BID_YLD_TDY = 0 ASK_YLD_TDY = 0 LAST2_PRICE = 91.87 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1
C .Net Examples
268
BID2 = 91.85 ASK2 = 91.88 SIZE_LAST_TRADE = 100 ASK_SIZE = 1 BID_SIZE = 3 TIME = 18:46:09.000+00:00 API_MACHINE = n160 TRADE_SIZE_ALL_SESSIONS_RT = 100 EID = 14003 IS_DELAYED_STREAM = false }
C .Net Examples
269
D C++ Examples
This section contains the following code examples:
RequestResponseParadigm on page 271 Subscription Paradigm on page 274 Asynchronous Event Handling on page 279 Request Response Multiple on page 283 Subscription Multiple on page 287
Note: These examples use assert statements to make manifest the program state at various key points. Follow your organizations guidelines for best practices on the use of assert statements in production code.
D C++ Examples
270
D.1 RequestResponseParadigm
// RequestResponseParadigm.cpp #include #include #include #include #include <blpapi_correlationid.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> // for strcmp(3C)
using namespace BloombergLP; using namespace blpapi; static void handleResponseEvent(const Event& event) { std::cout << "EventType =" << event.eventType() << std::endl; MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); std::cout << "correlationId=" << message.correlationId() << std::endl; std::cout << "messageType =" << message.messageType() << std::endl; message.print(std::cout); } } static void handleOtherEvent(const Event& event) { std::cout << "EventType=" << event.eventType() << std::endl; MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); std::cout << "correlationId=" << message.correlationId() << std::endl; std::cout << "messageType=" << message.messageType() << std::endl;
D C++ Examples
271
message.print(std::cout); if (Event::SESSION_STATUS == event.eventType() && 0 == ::strcmp("SessionTerminated", message.messageType().string())) { std::cout << "Terminating: " << message.messageType() << std::endl; ::exit(1); } } } int main() { SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session(sessionOptions); // Establish session // Start Session if (!session.start()) { std::cerr << "Failed to start session." << std::endl; return 1; } if (!session.openService("//blp/refdata")){ std::cerr << "Failed to open service //blp/refdata." << std::endl; return 1; } CorrelationId requestId(1); Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "PX_LAST"); session.sendRequest(request, requestId);
D C++ Examples
272
bool continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType()) { case Event::RESPONSE: // final event continueToLoop = false; // fall through case Event::PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } } session.stop(); return 0; }
D C++ Examples
273
// SubscriptionParadigm.cpp #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <blpapi_subscriptionlist.h>
#include <iostream> using namespace BloombergLP; using namespace blpapi; static void handleDataEvent(const Event& event, int updateCount) { std::cout << "EventType=" << event.eventType() << std::endl; std::cout << "updateCount = " << updateCount << std::endl; MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); std::cout << "correlationId = " << message.correlationId() << std::endl; std::cout << "messageType = " << message.messageType() << std::endl; message.print(std::cout); } } static void handleOtherEvent(const Event& event) { std::cout << "EventType=" << event.eventType() << std::endl;
D C++ Examples
274
MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); std::cout << "correlationId=" << message.correlationId() << std::endl; std::cout << "messageType=" << message.messageType() << std::endl; message.print(std::cout); if (Event::SESSION_STATUS == event.eventType() && 0 == ::strcmp("SessionTerminated", message.messageType().string())) { std::cout << "Terminating: " << message.messageType() << std::endl; ::exit(1); } } } int main(int argc, char **argv) { SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session(sessionOptions); if (!session.start()) { std::cerr <<"Failed to start session." << std::endl; return 1; } if (!session.openService("//blp/mktdata")) { std::cerr <<"Failed to open //blp/mktdata" << std::endl; return 1; }
D C++ Examples
275
CorrelationId subscriptionId((long long)2); SubscriptionList subscriptions; subscriptions.add("AAPL US Equity", "LAST_PRICE", "", subscriptionId); session.subscribe(subscriptions); int updateCount = 0; while (true) { Event event = session.nextEvent(); switch (event.eventType()) { case Event::SUBSCRIPTION_DATA: handleDataEvent(event, updateCount++); break; default: handleOtherEvent(event); break; } } return 0; }
D C++ Examples
276
D C++ Examples
277
LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 93.090000 ASK_SIZE_TDY = 1 BID_SIZE_TDY = 1 VOLUME_TDY = 21170839 LAST_PRICE_TDY = 93.000000 BID_TDY = 92.920000 ASK_TDY = 92.950000 HIGH_TDY = 94.340000 LOW_TDY = 92.600000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 93.070000 LAST_DIR = -1 LAST2_DIR = 1 RT_PRICING_SOURCE = US SIZE_LAST_TRADE = ASK_SIZE = 1 BID_SIZE = 1 API_MACHINE = n208 EXCH_CODE_LAST = EXCH_CODE_BID = Q EXCH_CODE_ASK = O TRADE_SIZE_ALL_SESSIONS_RT = 400 IS_DELAYED_STREAM = false EID = 14005 PREV_SES_LAST_PRICE = 94.200000 RT_PX_CHG_NET_1D = -1.200000 RT_PX_CHG_PCT_1D = -1.273890 TIME = 22:20:00.000+00:00 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 }
D C++ Examples
278
// AsynchronousEventHandling.cpp #include #include #include #include #include <blpapi_correlationid.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> // for strcmp(3C) // for pause(2)
using namespace BloombergLP; using namespace blpapi; namespace { // ========================= // class RefDataEventHandler // ========================= class RefDataEventHandler: public EventHandler { private: static void dumpEvent(const Event& event); public: // CREATORS RefDataEventHandler(); ~RefDataEventHandler(); // MANIPULATORS bool processEvent(const Event& event, Session *session); }; // CREATORS RefDataEventHandler::RefDataEventHandler() { } RefDataEventHandler::~RefDataEventHandler() { }
D C++ Examples
279
// MANIPULATORS bool RefDataEventHandler::processEvent(const Event& event, Session *session) { switch (event.eventType()) { case Event::SESSION_STATUS: { MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); if (0 == ::strcmp("SessionStarted", message.messageType().string())) { session->openServiceAsync("//blp/refdata", CorrelationId((long long)99)); } else { std::cerr << "Session Start Failure" << std::endl; message.print(std::cerr); ::exit(1); } } break; } case Event::SERVICE_STATUS: { MessageIterator iter(event); iter.next(); Message message = iter.message(); if (message.correlationId() == 99 && 0 == ::strcmp("ServiceOpened", message.messageType().string())) { // Construct and issue a Request Service service = session->getService("//blp/refdata"); Request request = service.createRequest("ReferenceDataRequest"); request.append("securities", "IBM US Equity"); request.append("fields", "LAST_PRICE"); session->sendRequest(request, CorrelationId((long long)86)); } else { std::cerr << "Unexpected message" << std::endl; message.print(std::cerr); ::exit(1); } break; } case Event::PARTIAL_RESPONSE: { dumpEvent(event); break; } case Event::RESPONSE: { dumpEvent(event); session->stop(); std::cout << "terminate process from handler" << std::endl; ::exit(0); break; }
D C++ Examples
280
default: { std::cerr << "Unxepected Event Type" << event.eventType() << std::endl; ::exit(1); break; } } return true; } void RefDataEventHandler::dumpEvent(const Event& event) { std::cout << "eventType=" << event.eventType() << std::endl; MessageIterator messageIterator(event); while (messageIterator.next()) { Message message = messageIterator.message(); std::cout << "messageType=" << message.messageType() << std::endl; std::cout << "CorrelationId=" << message.correlationId() << std::endl; message.print(std::cout); } } } // close unnamed namespace
int main() { SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); RefDataEventHandler refDataEventHandler; Session session(sessionOptions, &refDataEventHandler); // Start Session if (!session.startAsync()) { std::cerr << "Failed to start async session." << std::endl; return 1; } ::pause(); return 0; }
D C++ Examples
281
D C++ Examples
282
// RequestResponseParadigm.cpp #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> // for strcmp(3C)
using namespace BloombergLP; using namespace blpapi; static void handleResponseEvent(const Event& event) { MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); Element referenceDataResponse = message.asElement(); if (referenceDataResponse.hasElement("responseError")) { message.print(std::cout); ::exit(1); } Element securityDataArray = referenceDataResponse.getElement("securityData"); int numItems = securityDataArray.numValues(); for (int i = 0; i < numItems; ++i) { Element securityData = securityDataArray.getValueAsElement(i); std::string security = securityData.getElementAsString("security"); int sequenceNumber = securityData.getElementAsInt32("sequenceNumber"); if (securityData.hasElement("securityError")) { Element securityError = securityData.getElement("securityError"); std::cout << "* security =" << security << std::endl; securityError.print(std::cout); return;
D C++ Examples
283
fieldData = securityData.getElement("fieldData"); px_last = fieldData.getElementAsFloat64("PX_LAST"); ds002 = fieldData.getElementAsString("DS002"); vwap_volume = fieldData.getElementAsFloat64("VWAP_VOLUME"); ouput each value. security =" << sequenceNumber=" << px_last =" << ds002 =" << vwap_volume =" << security sequenceNumber px_last ds002 vwap_volume << << "\n" << "\n" << "\n" << "\n" << "\n" std::endl;
// Individually std::cout << "* << "* << "* << "* << "* } } } }
static void handleOtherEvent(const Event& event) { std::cout << "EventType=" << event.eventType() << std::endl; MessageIterator iter(event); while (iter.next()) { Message message = iter.message(); std::cout << "correlationId=" << message.correlationId() << std::endl; std::cout << "messageType=" << message.messageType() << std::endl; message.print(std::cout); if (Event::SESSION_STATUS == event.eventType() && 0 == ::strcmp("SessionTerminated", message.messageType().string())){ std::cout << "Terminating: " << message.messageType() << std::endl; ::exit(1); } } }
D C++ Examples
284
int main() { SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); Session session(sessionOptions); // Establish session // Start Session if (!session.start()) { std::cerr << "Failed to start session." << std::endl; return 1; } if (!session.openService("//blp/refdata")){ std::cerr << "Failed to open service //blp/refdata." << std::endl; return 1; } CorrelationId requestId(1); Service refDataSvc = session.getService("//blp/refdata"); Request request = refDataSvc.createRequest("ReferenceDataRequest"); // append fields to request std::cout << "Initialize Request" << std::endl; request.getElement("securities").appendValue("AAPL US Equity"); request.getElement("securities").appendValue("IBM US Equity"); request.getElement("securities").appendValue("BLAHBLAHBLAH US Equity"); request.getElement("fields").appendValue("PX_LAST"); request.getElement("fields").appendValue("DS002"); request.getElement("fields").appendValue("VWAP_VOLUME"); // Volume used to calcuate the Volume Weighted Average Price (VWAP) session.sendRequest(request, CorrelationId(1)); bool continueToLoop = true; while (continueToLoop) { Event event = session.nextEvent(); switch (event.eventType()) { case Event::RESPONSE: // final event continueToLoop = false; // fall through case Event::PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } }
D C++ Examples
285
session.stop(); return 0; }
* security =BLAHBLAHBLAH US Equity securityError = { source = 119::bbdbs1 code = 15 category = BAD_SEC message = Unknown/Invalid security [nid:119] subcategory = INVALID_SECURITY }
D C++ Examples
286
// SubscriptionMultiple.cpp #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <blpapi_subscriptionlist.h>
#include <iostream> #include <cassert> #include <string> #include <unistd.h> // for pause(2)
using namespace BloombergLP; using namespace blpapi; namespace { // ============================== // class SubscriptionEventHandler // ============================== class SubscriptionEventHandler: public EventHandler { std::string d_label; std::ostream *d_stream; // held void void void handleDataEvent (const const handleStatusEvent(const const handleOtherEvent (const const Event& Session& Event& Session& Event& Session& event, session); event, session); event, session);
void dumpEvent(const Event& event); public: // CREATORS SubscriptionEventHandler(const std::string& label, std::ostream *stream); ~SubscriptionEventHandler(); // MANIPULATORS bool processEvent(const Event& event, Session *session); };
D C++ Examples
287
// CREATORS SubscriptionEventHandler::SubscriptionEventHandler(const std::string& label, std::ostream *stream) : d_label(label) , d_stream(stream) { assert(d_stream); } SubscriptionEventHandler::~SubscriptionEventHandler() { } // MANIPULATORS bool SubscriptionEventHandler::processEvent(const Event& event, Session *session) { assert(session); switch (event.eventType()) { case Event::SUBSCRIPTION_DATA: handleDataEvent(event, *session); break; case Event::SESSION_STATUS: case Event::SERVICE_STATUS: case Event::SUBSCRIPTION_STATUS: handleStatusEvent(event, *session); break; default: handleOtherEvent(event, *session); break; } return true; } void SubscriptionEventHandler::dumpEvent(const Event& event) { *d_stream << "handler label=" << d_label << std::endl << "eventType=" << event.eventType() << std::endl;
D C++ Examples
288
MessageIterator messageIterator(event); while (messageIterator.next()) { Message message = messageIterator.message(); *d_stream << "messageType=" << message.messageType() << std::endl << "CorrelationId=" << message.correlationId() << std::endl; message.print(*d_stream); } } void SubscriptionEventHandler::handleDataEvent(const Event& event, const Session& session) { *d_stream << "handleDataEventHandler: enter" << std::endl; dumpEvent(event); *d_stream << "handleDataEventHandler: leave" << std::endl; } void SubscriptionEventHandler::handleStatusEvent(const Event& event, const Session& session) { *d_stream << "handleStatusEventHandler: enter" << std::endl; dumpEvent(event); *d_stream << "handleStatusEventHandler: leave" << std::endl; } void SubscriptionEventHandler::handleOtherEvent(const Event& event, const Session& session) { *d_stream << "handleOtherEvent: enter" << std::endl; dumpEvent(event); *d_stream << "handleOtherEvent: leave" << std::endl; } } // close unnamed namespace
D C++ Examples
289
int main(int argc, char **argv) { SessionOptions sessionOptions; sessionOptions.setServerHost("localhost"); sessionOptions.setServerPort(8194); SubscriptionEventHandler subscriptionEventHandler(std::string("myLabel"), &std::cout); Session session(sessionOptions, &subscriptionEventHandler); if (!session.start()) { std::cerr <<"Failed to start session." << std::endl; return 1; } if (!session.openService("//blp/mktdata")) { std::cerr <<"Failed to open //blp/mktdata" << std::endl; return 1; } SubscriptionList subscriptions; subscriptions.add("IBM US Equity", "LAST_TRADE", "", CorrelationId((long long)10)); subscriptions.add("/ticket/GOOG US Equity", "BID,ASK,LAST_PRICE", "", CorrelationId((long long)20)); subscriptions.add("MSFTT US Equity", "LAST_PRICE", "interval=.5", CorrelationId((long long)30)); subscriptions.add("/cusip/097023105?fields=LAST_PRICE&interval=5.0", "", "", CorrelationId((long long)40)); session.subscribe(subscriptions); ::pause(); return 0; }
D C++ Examples
290
D C++ Examples
291
handleStatusEventHandler: leave handleDataEventHandler: enter handler label=myLabel eventType=8 messageType=MarketDataEvents CorrelationId=[ valueType=INT classId=0 value=20 ] MarketDataEvents = { LAST_PRICE = 338.460000 BID = 338.360000 ASK = 338.500000 VOLUME = 4068281 HIGH = 348.800000 LOW = 336.001000 BEST_BID = 338.360000 BEST_ASK = 338.500000 LAST_TRADE = 338.460000 OPEN = 344.690000 INDICATIVE_FAR = 344.690000 INDICATIVE_NEAR = 344.690000 IMBALANCE_BID = IMBALANCE_ASK = 344.760000 VWAP = 341.666700 LAST_ALL_SESSIONS = 338.460000 IMBALANCE_INDIC_RT = SELL PREV_CLOSE_VALUE_REALTIME = 343.320000 BID_ALL_SESSION = 338.360000 ASK_ALL_SESSION = 338.500000 TRADING_DT_REALTIME = 2009-01-30 EQY_TURNOVER_REALTIME = 1379007507.741211 TOT_CALL_VOLUME_CUR_DAY_RT = 3266 TOT_PUT_VOLUME_CUR_DAY_RT = 4650 TOT_OPT_VOLUME_CUR_DAY_RT = 7916 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 1 IN_AUCTION_RT = false RT_API_MACHINE = p060 ALL_PRICE_SIZE = 100 ALL_PRICE = 338.460000 ALL_PRICE_COND_CODE = BID_COND_CODE = ASK_COND_CODE = LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 100 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 344.690000
D C++ Examples
292
ASK_SIZE_TDY = 2 BID_SIZE_TDY = 3 VOLUME_TDY = 4068281 LAST_PRICE_TDY = 338.460000 BID_TDY = 338.360000 ASK_TDY = 338.500000 HIGH_TDY = 348.800000 LOW_TDY = 336.001000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 338.450000 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1 BID2 = 338.360000 ASK2 = 338.500000 SIZE_LAST_TRADE = 100 ASK_SIZE = 2 BID_SIZE = 3 API_MACHINE = p060 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 100 IS_DELAYED_STREAM = false EID = 14005 PREV_SES_LAST_PRICE = 343.320000 RT_PX_CHG_NET_1D = -4.860000 RT_PX_CHG_PCT_1D = -1.415590 TIME = 20:48:30.000+00:00 LAST_UPDATE_BID_RT = 20:48:33.000+00:00 LAST_UPDATE_ASK_RT = 20:48:32.000+00:00 BID_ASK_TIME = 20:48:33.000+00:00 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 } handleDataEventHandler: leave handleDataEventHandler: enter handler label=myLabel eventType=8 messageType=MarketDataEvents CorrelationId=[ valueType=INT classId=0 value=10 ] MarketDataEvents = { LAST_PRICE = 91.830000 BID = 91.820000 ASK = 91.830000 VOLUME = 7233307 HIGH = 93.480000 LOW = 91.250000 BEST_BID = 91.820000 BEST_ASK = 91.830000 LAST_TRADE = 91.830000
D C++ Examples
293
OPEN = 92.230000 IMBALANCE_BID = IMBALANCE_ASK = 91.780000 ORDER_IMB_BUY_VOLUME = ORDER_IMB_SELL_VOLUME = 54500.000000 VWAP = 92.495700 THEO_PRICE = 0.000000 LAST_ALL_SESSIONS = 91.830000 IMBALANCE_INDIC_RT = SELL PREV_CLOSE_VALUE_REALTIME = 92.510000 BID_ALL_SESSION = 91.820000 ASK_ALL_SESSION = 91.830000 TRADING_DT_REALTIME = 2009-01-30 EQY_TURNOVER_REALTIME = 666435537.542725 FINANCIAL_STATUS_INDICATOR_RT = 0 NYSE_LRP_HIGH_PRICE_RT = 92.850000 NYSE_LRP_LOW_PRICE_RT = 90.850000 TOT_CALL_VOLUME_CUR_DAY_RT = 2345 TOT_PUT_VOLUME_CUR_DAY_RT = 2282 TOT_OPT_VOLUME_CUR_DAY_RT = 4627 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 0 IN_AUCTION_RT = false RT_API_MACHINE = n160 ALL_PRICE_SIZE = 100 ALL_PRICE = 91.830000 ALL_PRICE_COND_CODE = BID_COND_CODE = ASK_COND_CODE = VOLUME_THEO = 0 LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 100 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 92.230000 ASK_SIZE_TDY = 1 BID_SIZE_TDY = 2 VOLUME_TDY = 7233307 LAST_PRICE_TDY = 91.830000 BID_TDY = 91.820000 ASK_TDY = 91.830000 HIGH_TDY = 93.480000 LOW_TDY = 91.250000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 91.839000
D C++ Examples
294
LAST_DIR = -1 LAST2_DIR = 1 BID_DIR = -1 ASK_DIR = -1 BID2 = 91.820000 ASK2 = 91.830000 SIZE_LAST_TRADE = 100 ASK_SIZE = 1 BID_SIZE = 2 API_MACHINE = n160 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 100 IS_DELAYED_STREAM = false EID = 14003 PREV_SES_LAST_PRICE = 92.510000 RT_PX_CHG_NET_1D = -0.679900 RT_PX_CHG_PCT_1D = -0.734947 TIME = 20:48:34.000+00:00 LAST_UPDATE_BID_RT = 20:48:34.000+00:00 LAST_UPDATE_ASK_RT = 20:48:34.000+00:00 NYSE_LRP_SEND_TIME_RT = 20:48:34.000+00:00 BID_ASK_TIME = 20:48:34.000+00:00 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 }
D C++ Examples
295
E C Examples
This section contains the following code examples:
RequestResponseParadigm on page 297 Subscription Paradigm on page 302 Asynchronous Event Handling on page 311 Request Response Multiple on page 316 Subscription Multiple on page 324
Note: These examples use assert statements to make manifest the program state at various key points. Follow your organizations guidelines for best practices on the use of assert statements in production code. Note: When using the C language interface the programmer must explicitly recover allocated resources such as sessions, session options, requests, and message iterators. In general, a pointer to a resource obtained from a function containing the word create must be recovered by invoking a similarly named function containing the word destroy. For example, the blpapi_Service_createRequest function delivers a pointer to a blpapi_Request_t type and that pointer, when no longer needed, must be passed to the blpapi_Request_destroy function.
E C Examples
296
E.1 RequestResponseParadigm
/* RequestResponseParadigm.c */ #include #include #include #include #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <assert.h> <stdio.h> <stdlib.h> <string.h>
static int streamWriter(const char* data, int length, void *stream) { assert(data); assert(stream); return fwrite(data, length, 1, (FILE *)stream); } static void handleResponseEvent(const blpapi_Event_t *event) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("Event Type = %d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue);
E C Examples
297
printf("messageType =%s\n", blpapi_Message_typeString(message)); messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); } blpapi_MessageIterator_destroy(iter); } static void handleOtherEvent(const blpapi_Event_t *event) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("EventType=%d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue); printf("messageType=%s\n", blpapi_Message_typeString(message)); messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); if (BLPAPI_EVENTTYPE_SESSION_STATUS == blpapi_Event_eventType(event) && 0 == strcmp("SessionTerminated", blpapi_Message_typeString(message))){ fprintf(stdout, "Terminating: %s\n", blpapi_Message_typeString(message)); exit(1); } } blpapi_MessageIterator_destroy(iter); }
E C Examples
298
int main() { blpapi_SessionOptions_t blpapi_Session_t blpapi_CorrelationId_t blpapi_Service_t blpapi_Request_t blpapi_Element_t blpapi_Element_t blpapi_Element_t int blpapi_CorrelationId_t
*sessionOptions *session requestId; *refDataSvc *request *elements *securitiesElements *fieldsElements continueToLoop correlationId;
= 0; = 0; = = = = = = 0; 0; 0; 0; 0; 1;
sessionOptions = blpapi_SessionOptions_create(); assert(sessionOptions); blpapi_SessionOptions_setServerHost(sessionOptions, "localhost"); blpapi_SessionOptions_setServerPort(sessionOptions, "8194") session = blpapi_Session_create(sessionOptions, 0, 0, 0); assert(session); blpapi_SessionOptions_destroy(sessionOptions); if (0 != blpapi_Session_start(session)) { fprintf(stderr, "Failed to start session.\n"); blpapi_Session_destroy(session); return 1; } if (0 != blpapi_Session_openService(session, "//blp/refdata")){ fprintf(stderr, "Failed to open service //blp/refdata.\n"); blpapi_Session_destroy(session); return 1; } memset(&requestId, '\0', sizeof(requestId)); requestId.size = sizeof(requestId); requestId.valueType = BLPAPI_CORRELATION_TYPE_INT; requestId.value.intValue = (blpapi_UInt64_t)1; blpapi_Session_getService(session, &refDataSvc, "//blp/refdata"); blpapi_Service_createRequest(refDataSvc, &request, "ReferenceDataRequest"); assert(request);
E C Examples
299
elements = blpapi_Request_elements(request); assert(elements); blpapi_Element_getElement(elements, &securitiesElements, "securities", 0); assert(securitiesElements); blpapi_Element_setValueString(securitiesElements, "IBM US Equity", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_getElement(elements, &fieldsElements, "fields", 0); blpapi_Element_setValueString(fieldsElements, "PX_LAST", BLPAPI_ELEMENT_INDEX_END); memset(&correlationId, '\0', correlationId.size correlationId.valueType correlationId.value.intValue 0); while (continueToLoop) { blpapi_Event_t *event = 0; blpapi_Session_nextEvent(session, &event, 0); assert(event); switch (blpapi_Event_eventType(event)) { case BLPAPI_EVENTTYPE_RESPONSE: // final event continueToLoop = 0; // fall through case BLPAPI_EVENTTYPE_PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } blpapi_Event_release(event); } blpapi_Session_stop(session); blpapi_Request_destroy(request); blpapi_Session_destroy(session); return 0; } sizeof(correlationId)); = sizeof(correlationId); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)1;
E C Examples
300
E C Examples
301
/* SubscriptionParadigm.c */ #include #include #include #include #include #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <blpapi_subscriptionlist.h> <assert.h> <stdio.h> <stdlib.h> <string.h>
static int streamWriter(const char* data, int length, void *stream) { assert(data); assert(stream); return fwrite(data, length, 1, (FILE *)stream); } static void handleDataEvent(const blpapi_Event_t *event, int updateCount) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("EventType=%d\n", blpapi_Event_eventType(event)); printf("updateCount = %d\n", updateCount); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue);
E C Examples
302
printf("messageType = %s\n", blpapi_Message_typeString(message)); messageElements = blpapi_Message_elements(message); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); } blpapi_MessageIterator_destroy(iter); } static void handleOtherEvent(const blpapi_Event_t *event) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("EventType=%d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue); printf("messageType=%s\n", blpapi_Message_typeString(message)); messageElements = blpapi_Message_elements(message); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); if (BLPAPI_EVENTTYPE_SESSION_STATUS == blpapi_Event_eventType(event) && 0 == strcmp("SessionTerminated", blpapi_Message_typeString(message))){ fprintf(stdout, "Terminating: %s\n", blpapi_Message_typeString(message)); exit(1); } } blpapi_MessageIterator_destroy(iter); }
E C Examples
303
int main() { blpapi_SessionOptions_t *sessionOptions blpapi_Session_t *session blpapi_CorrelationId_t subscriptionId; blpapi_SubscriptionList *subscriptions const char *fields[1] const char **options int updateCount setbuf(stdout, 0); /* NO SHOW */
= 0; = 0; = = = = 0; {"LAST_PRICE"}; 0; 0;
sessionOptions = blpapi_SessionOptions_create(); assert(sessionOptions); blpapi_SessionOptions_setServerHost(sessionOptions, "localhost"); blpapi_SessionOptions_setServerPort(sessionOptions, "8194"); session = blpapi_Session_create(sessionOptions, 0, 0, 0); assert(session); blpapi_SessionOptions_destroy(sessionOptions); if (0 != blpapi_Session_start(session)) { fprintf(stderr, "Failed to start session.\n"); blpapi_Session_destroy(session); return 1; } if (0 != blpapi_Session_openService(session, "//blp/mktdata")){ fprintf(stderr, "Failed to open service //blp/mktdata.\n"); blpapi_Session_destroy(session); return 1; } memset(&subscriptionId, '\0', subscriptionId.size subscriptionId.valueType subscriptionId.value.intValue sizeof(subscriptionId)); = sizeof(subscriptionId); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)2;
E C Examples
304
blpapi_SubscriptionList_add(subscriptions, "AAPL US Equity", &subscriptionId, fields, options, 1, 0); blpapi_Session_subscribe(session, subscriptions, 0, 0, 0); while (1) { blpapi_Event_t *event = 0; blpapi_Session_nextEvent(session, &event, 0); assert(event); switch (blpapi_Event_eventType(event)) { case BLPAPI_EVENTTYPE_SUBSCRIPTION_DATA: handleDataEvent(event, updateCount++); break; default: handleOtherEvent(event); break; } blpapi_Event_release(event); } return 0; }
E C Examples
305
E C Examples
306
ALL_PRICE = 90.886000 ALL_PRICE_COND_CODE = BID_COND_CODE = ASK_COND_CODE = LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 1000 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 89.100000 ASK_SIZE_TDY = 5 BID_SIZE_TDY = 7 VOLUME_TDY = 7596090 LAST_PRICE_TDY = 90.886000 BID_TDY = 90.880000 ASK_TDY = 90.910000 HIGH_TDY = 91.640000 LOW_TDY = 88.900000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 90.900000 LAST_DIR = -1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1 BID2 = 90.880000 ASK2 = 90.910000 SIZE_LAST_TRADE = 1000 ASK_SIZE = 5 BID_SIZE = 7 API_MACHINE = n166 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 1000 IS_DELAYED_STREAM = false EID = 14005 PREV_SES_LAST_PRICE = 90.130000 RT_PX_CHG_NET_1D = 0.756000 RT_PX_CHG_PCT_1D = 0.838788 TIME = 16:36:33.000+00:00 LAST_UPDATE_BID_RT = 16:36:35.000+00:00 LAST_UPDATE_ASK_RT = 16:36:32.000+00:00 BID_ASK_TIME = 16:36:35.000+00:00 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 }
E C Examples
307
EventType=8 updateCount = 1 correlationId=1 0 2 messageType = MarketDataEvents MarketDataEvents = { LAST_PRICE = 90.886000 BID = 90.880000 ASK = 90.910000 VOLUME = 7596090 HIGH = 91.640000 LOW = 88.900000 BEST_BID = 90.880000 BEST_ASK = 90.910000 LAST_TRADE = 90.886000 VWAP = 90.644800 LAST_ALL_SESSIONS = 90.886000 BID_ALL_SESSION = 90.880000 ASK_ALL_SESSION = 90.910000 EQY_TURNOVER_REALTIME = 682873786.088959 TOT_CALL_VOLUME_CUR_DAY_RT = 4886 TOT_PUT_VOLUME_CUR_DAY_RT = 3457 TOT_OPT_VOLUME_CUR_DAY_RT = 8343 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 0 IN_AUCTION_RT = false ALL_PRICE_SIZE = 1000 ALL_PRICE = 90.886000 ALL_PRICE_COND_CODE = LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 1000 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 89.100000 ASK_SIZE_TDY = 5 BID_SIZE_TDY = 7 VOLUME_TDY = 7596090 LAST_PRICE_TDY = 90.886000 BID_TDY = 90.880000 ASK_TDY = 90.910000 HIGH_TDY = 91.640000 LOW_TDY = 88.900000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 90.900000 LAST_DIR = -1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1 BID2 = 90.880000 E C Examples 308
ASK2 = 90.910000 SIZE_LAST_TRADE = 1000 ASK_SIZE = 5 BID_SIZE = 7 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 1000 IS_DELAYED_STREAM = false EID = 14005 RT_PX_CHG_NET_1D = 0.756000 RT_PX_CHG_PCT_1D = 0.838788 TIME = 16:36:33.000+00:00 LAST_UPDATE_BID_RT = 16:36:35.000+00:00 LAST_UPDATE_ASK_RT = 16:36:32.000+00:00 BID_ASK_TIME = 16:36:35.000+00:00 } EventType=8 updateCount = 2 correlationId=1 0 2 messageType = MarketDataEvents MarketDataEvents = { LAST2_PRICE = 90.886000 LAST_PRICE = 90.910000 LAST_ALL_SESSIONS = 90.910000 LAST_PRICE_TDY = 90.910000 LAST2_DIR = -1 LAST_DIR = 1 EQY_TURNOVER_REALTIME = 682882877.088959 SIZE_LAST_TRADE = 100 SIZE_LAST_TRADE_TDY = 100 TRADE_SIZE_ALL_SESSIONS_RT = 100 VOLUME = 7596190 VOLUME_TDY = 7596190 LAST_TRADE = 90.910000 ALL_PRICE = 90.910000 ALL_PRICE_SIZE = 100 EID = 14005 RT_PX_CHG_NET_1D = 0.780000 RT_PX_CHG_PCT_1D = 0.865417 IS_DELAYED_STREAM = false TIME = 16:36:37.000+00:00 EVENT_TIME = 16:36:37.000+00:00 }
E C Examples
309
EventType=8 updateCount = 3 correlationId=1 0 2 messageType = MarketDataEvents MarketDataEvents = { LAST2_PRICE = 90.910000 LAST_PRICE = 90.910000 LAST_ALL_SESSIONS = 90.910000 LAST_PRICE_TDY = 90.910000 LAST2_DIR = 1 EQY_TURNOVER_REALTIME = 682891968.088959 SIZE_LAST_TRADE = 100 SIZE_LAST_TRADE_TDY = 100 TRADE_SIZE_ALL_SESSIONS_RT = 100 VOLUME = 7596290 VOLUME_TDY = 7596290 LAST_TRADE = 90.910000 ALL_PRICE = 90.910000 ALL_PRICE_SIZE = 100 EID = 14005 RT_PX_CHG_NET_1D = 0.780000 RT_PX_CHG_PCT_1D = 0.865417 IS_DELAYED_STREAM = false TIME = 16:36:37.000+00:00 EVENT_TIME = 16:36:37.000+00:00 } correlationId=1 0 2 messageType = MarketDataEvents MarketDataEvents = { LAST2_PRICE = 90.910000 LAST_PRICE = 90.910000 LAST_ALL_SESSIONS = 90.910000 LAST_PRICE_TDY = 90.910000 LAST2_DIR = 1 EQY_TURNOVER_REALTIME = 682901059.088959 SIZE_LAST_TRADE = 100 SIZE_LAST_TRADE_TDY = 100 TRADE_SIZE_ALL_SESSIONS_RT = 100 VOLUME = 7596390 VOLUME_TDY = 7596390 LAST_TRADE = 90.910000 ALL_PRICE = 90.910000 ALL_PRICE_SIZE = 100 EID = 14005 RT_PX_CHG_NET_1D = 0.780000 RT_PX_CHG_PCT_1D = 0.865417 IS_DELAYED_STREAM = false TIME = 16:36:37.000+00:00 EVENT_TIME = 16:36:37.000+00:00 }
E C Examples
310
/* RequestResponseParadigm.c */ #include #include #include #include #include #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <assert.h> <stdio.h> <stdlib.h> <string.h> <unistd.h>
static int streamWriter(const char* data, int length, void *stream) { assert(data); assert(stream); return fwrite(data, length, 1, (FILE *)stream); } static void dumpEvent(blpapi_Event_t *event) /* not const! */ { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("eventType=%d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); printf("messageType=%s\n", blpapi_Message_typeString(message)); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue);
E C Examples
311
messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); } } #ifdef __cplusplus extern "C" #endif static void processEvent(blpapi_Event_t *event, blpapi_Session_t *session, void *userData) { assert(event); assert(session); switch (blpapi_Event_eventType(event)) { case BLPAPI_EVENTTYPE_SESSION_STATUS: { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { if (0 == strcmp("SessionStarted", blpapi_Message_typeString(message))) { blpapi_CorrelationId_t correlationId;
memset(&correlationId, '\0', sizeof(correlationId)); correlationId.size = sizeof(correlationId); correlationId.valueType = BLPAPI_CORRELATION_TYPE_INT; correlationId.value.intValue = (blpapi_UInt64_t)99; blpapi_Session_openServiceAsync(session, "//blp/refdata", &correlationId); } else { blpapi_Element_t *messageElements = 0; messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); exit(1); } } break;
E C Examples
312
} case BLPAPI_EVENTTYPE_SERVICE_STATUS: { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; blpapi_Service_t *refDataSvc = 0; blpapi_CorrelationId_t correlationId; iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { assert(message); correlationId = blpapi_Message_correlationId(message, 0); if (correlationId.value.intValue == (blpapi_UInt64_t)99 && 0 == strcmp("ServiceOpened", blpapi_Message_typeString(message))) { blpapi_Request_t *request = 0; blpapi_Element_t *elements = 0; blpapi_Element_t *securitiesElements = 0; blpapi_Element_t *fieldsElements = 0; /* Construct and issue a Request */ blpapi_Session_getService(session, &refDataSvc, "//blp/refdata"); blpapi_Service_createRequest(refDataSvc, &request, "ReferenceDataRequest"); assert(request); elements = blpapi_Request_elements(request); assert(elements); blpapi_Element_getElement(elements, &securitiesElements, "securities", 0); assert(securitiesElements); blpapi_Element_setValueString(securitiesElements, "IBM US Equity", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_getElement(elements, &fieldsElements, "fields", 0); blpapi_Element_setValueString(fieldsElements, "PX_LAST", BLPAPI_ELEMENT_INDEX_END);
E C Examples
313
memset(&correlationId, '\0', sizeof(correlationId)); correlationId.size = sizeof(correlationId); correlationId.valueType = BLPAPI_CORRELATION_TYPE_INT; correlationId.value.intValue = (blpapi_UInt64_t)86; blpapi_Session_sendRequest(session, request, &correlationId, 0, 0, 0, 0); } else { blpapi_Element_t *messageElements = 0; fprintf(stderr, "Unexpected message\n"); messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); } } break; } case BLPAPI_EVENTTYPE_PARTIAL_RESPONSE: { dumpEvent(event); break; } case BLPAPI_EVENTTYPE_RESPONSE: { dumpEvent(event); assert(session); printf("terminate process from handler\n"); blpapi_Session_stop(session); exit(0); break; } default: { fprintf(stderr, "default-case\n"); fprintf(stderr, "Unxepected Event Type %d\n", blpapi_Event_eventType(event)); exit(1); break; } } }
E C Examples
314
= 0; = 0;
sessionOptions = blpapi_SessionOptions_create(); assert(sessionOptions); blpapi_SessionOptions_setServerHost(sessionOptions, "localhost"); blpapi_SessionOptions_setServerPort(sessionOptions, "8194"); session = blpapi_Session_create(sessionOptions, &processEvent, 0, 0); assert(session); blpapi_SessionOptions_destroy(sessionOptions); if (0 != blpapi_Session_start(session)) { fprintf(stderr, "Failed to start async session.\n"); blpapi_Session_destroy(session); return 1; } pause(); blpapi_Session_destroy(session); return 0; }
E C Examples
315
/* RequestResponseParadigm.c */ #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h>
/* for strcmp(3C) */
static int streamWriter(const char* data, int length, void *stream) { assert(data); assert(stream); return fwrite(data, length, 1, (FILE *)stream); } static void handleResponseEvent(const blpapi_Event_t *event) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_Element_t *referenceDataResponse = 0; blpapi_Element_t *securityDataArray = 0; int numItems = 0; assert(message); referenceDataResponse = blpapi_Message_elements(message); assert(referenceDataResponse); if (blpapi_Element_hasElement(referenceDataResponse, "responseError", 0)) {
E C Examples
316
fprintf(stderr, "has responseError\n"); blpapi_Element_print(referenceDataResponse, &streamWriter, stdout, 0, 4); exit(1); } blpapi_Element_getElement(referenceDataResponse, &securityDataArray, "securityData", 0); numItems = blpapi_Element_numValues(securityDataArray); for (int i = 0; i < numItems; ++i) { blpapi_Element_t *securityData blpapi_Element_t *securityElement const char *security blpapi_Element_t *sequenceNumberElement int sequenceNumber = 0; = 0; = 0; = 0; = -1;
blpapi_Element_getValueAsElement(securityDataArray, &securityData, i); assert(securityData); blpapi_Element_getElement(securityData, &securityElement, "security", 0); assert(securityElement); blpapi_Element_getValueAsString(securityElement, &security, 0); assert(security); blpapi_Element_getElement(securityData, &sequenceNumberElement, "sequenceNumber", 0); assert(sequenceNumberElement); blpapi_Element_getValueAsInt32(sequenceNumberElement, &sequenceNumber, 0);
E C Examples
317
blpapi_Element_getElement(securityData, &securityErrorElement, "securityError", 0); assert(securityErrorElement); blpapi_Element_print(securityErrorElement, &streamWriter, stdout, 0, 4); return; } else { blpapi_Element_t *fieldDataElement = 0; blpapi_Element_t *PX_LAST_Element = 0; blpapi_Element_t *DS002_Element = 0; blpapi_Element_t *VWAP_VOLUME_Element = 0; double px_last = (double)777; const char *ds002 = 0; double vwap_volume = (double)666; blpapi_Element_getElement(securityData, &fieldDataElement, "fieldData", 0); assert(fieldDataElement); blpapi_Element_getElement(fieldDataElement, &PX_LAST_Element, "PX_LAST", 0); assert(PX_LAST_Element); blpapi_Element_getValueAsFloat64(PX_LAST_Element, &px_last, 0); blpapi_Element_getElement(fieldDataElement, &DS002_Element, "DS002", 0); assert(DS002_Element); blpapi_Element_getValueAsString(DS002_Element, &ds002, 0);
E C Examples
318
blpapi_Element_getElement(fieldDataElement, &VWAP_VOLUME_Element, "VWAP_VOLUME", 0); assert(VWAP_VOLUME_Element); blpapi_Element_getValueAsFloat64(VWAP_VOLUME_Element, &vwap_volume, 0); printf("*security =%s\n", printf("*sequenceNumber=%d\n", printf("*px_last =%f\n", printf("*ds002 =%s\n", printf("*vwap_volume =%f\n", printf("\n"); } } } blpapi_MessageIterator_destroy(iter); } static void handleOtherEvent(const blpapi_Event_t *event) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); printf("EventType=%d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter); while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue); printf("messageType=%s\n", blpapi_Message_typeString(message)); messageElements = blpapi_Message_elements(message); assert(messageElements); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); security); sequenceNumber); px_last); ds002); vwap_volume);
E C Examples
319
if (BLPAPI_EVENTTYPE_SESSION_STATUS == blpapi_Event_eventType(event) && 0 == strcmp("SessionTerminated", blpapi_Message_typeString(message))){ fprintf(stdout, "Terminating: %s\n", blpapi_Message_typeString(message)); exit(1); } } blpapi_MessageIterator_destroy(iter); } int main() { blpapi_SessionOptions_t blpapi_Session_t blpapi_CorrelationId_t blpapi_Service_t blpapi_Request_t blpapi_Element_t blpapi_Element_t blpapi_Element_t blpapi_CorrelationId_t int
*sessionOptions *session requestId; *refDataSvc *request *elements *securitiesElements *fieldsElements correlationId; continueToLoop
= 0; = 0; = = = = = 0; 0; 0; 0; 0;
= 1;
sessionOptions = blpapi_SessionOptions_create(); assert(sessionOptions); blpapi_SessionOptions_setServerHost(sessionOptions, "localhost"); blpapi_SessionOptions_setServerPort(sessionOptions, "8194"); session = blpapi_Session_create(sessionOptions, 0, 0, 0); assert(session); blpapi_SessionOptions_destroy(sessionOptions); if (0 != blpapi_Session_start(session)) { fprintf(stderr, "Failed to start session.\n"); blpapi_Session_destroy(session); return 1; } if (0 != blpapi_Session_openService(session,"//blp/refdata")){ fprintf(stderr, "Failed to open service //blp/refdata.\n"); blpapi_Session_destroy(session); return 1; }
E C Examples
320
blpapi_Session_getService(session, &refDataSvc, "//blp/refdata"); blpapi_Service_createRequest(refDataSvc, &request, "ReferenceDataRequest"); assert(request); elements = blpapi_Request_elements(request); assert(elements); blpapi_Element_getElement(elements, &securitiesElements, "securities", 0); assert(securitiesElements); blpapi_Element_setValueString(securitiesElements, "AAPL US Equity", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_setValueString(securitiesElements, "IBM US Equity", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_setValueString(securitiesElements, "BLAHBLAHBLAH US Equity", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_getElement(elements, &fieldsElements, "fields", 0); blpapi_Element_setValueString(fieldsElements, "PX_LAST", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_setValueString(fieldsElements, "DS002", BLPAPI_ELEMENT_INDEX_END); blpapi_Element_setValueString(fieldsElements, "VWAP_VOLUME", BLPAPI_ELEMENT_INDEX_END); memset(&correlationId, '\0', correlationId.size correlationId.valueType correlationId.value.intValue 0); sizeof(correlationId)); = sizeof(correlationId); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)1;
E C Examples
321
while (continueToLoop) { blpapi_Event_t *event = 0; blpapi_Session_nextEvent(session, &event, 0); assert(event); switch (blpapi_Event_eventType(event)) { case BLPAPI_EVENTTYPE_RESPONSE: /* final event */ continueToLoop = 0; /* fall through */ case BLPAPI_EVENTTYPE_PARTIAL_RESPONSE: handleResponseEvent(event); break; default: handleOtherEvent(event); break; } blpapi_Event_release(event); } blpapi_Session_stop(session); blpapi_Request_destroy(request); blpapi_Session_destroy(session); return 0; }
E C Examples
322
E C Examples
323
/* SubscriptionMultiple.c */ #include #include #include #include #include #include #include #include #include #include #include <blpapi_correlationid.h> <blpapi_element.h> <blpapi_event.h> <blpapi_message.h> <blpapi_request.h> <blpapi_session.h> <blpapi_subscriptionlist.h> <assert.h> <stdio.h> <string.h> <unistd.h>
static int streamWriter(const char* data, int length, void *stream) { assert(data); assert(stream); return fwrite(data, length, 1, (FILE *)stream); } typedef struct UserData { const char *d_label; FILE *d_stream; } UserData_t; static void dumpEvent(const blpapi_Event_t *event, const UserData_t *userData) { blpapi_MessageIterator_t *iter = 0; blpapi_Message_t *message = 0; assert(event); assert(userData); assert(userData->d_label); assert(userData->d_stream); fprintf(userData->d_stream, "handler label=%s\n", userData->d_label); fprintf(userData->d_stream, "eventType=%d\n", blpapi_Event_eventType(event)); iter = blpapi_MessageIterator_create(event); assert(iter);
E C Examples
324
while (0 == blpapi_MessageIterator_next(iter, &message)) { blpapi_CorrelationId_t correlationId; blpapi_Element_t *messageElements = 0; assert(message); printf("messageType=%s\n", blpapi_Message_typeString(message)); messageElements=blpapi_Message_elements(message); correlationId = blpapi_Message_correlationId(message, 0); printf("correlationId=%d %d %lld\n", correlationId.valueType, correlationId.classId, correlationId.value.intValue); blpapi_Element_print(messageElements, &streamWriter, stdout, 0, 4); } } static void handleDataEvent(const blpapi_Event_t *event, const blpapi_Session_t *session, const UserData_t *userData) { assert(event); assert(userData); fprintf(userData->d_stream, "handleDataEventHandler: enter\n"); dumpEvent(event, userData); fprintf(userData->d_stream, "handleDataEventHandler: leave\n"); } static void handleStatusEvent(const blpapi_Event_t *event, const blpapi_Session_t *session, const UserData_t *userData) { assert(event); assert(session); assert(userData); /* this application expects userData */ fprintf(userData->d_stream, "handleStatusEventHandler: enter\n"); dumpEvent(event, userData); fprintf(userData->d_stream, "handleStatusEventHandler: leave\n"); } static void handleOtherEvent(const blpapi_Event_t *event, const blpapi_Session_t *session, const UserData_t *userData) { assert(event); assert(userData); assert(userData->d_stream);
E C Examples
325
fprintf(userData->d_stream, "handleOtherEventHandler: enter\n"); dumpEvent(event, userData); fprintf(userData->d_stream, "handleOtherEventHandler: leave\n"); } #ifdef __cplusplus extern "C" #endif static void processEvent(blpapi_Event_t *event, blpapi_Session_t *session, void *buffer) { UserData_t *userData = (UserData_t *)buffer; assert(event); assert(session); assert(buffer); switch (blpapi_Event_eventType(event)) { case BLPAPI_EVENTTYPE_SUBSCRIPTION_DATA: handleDataEvent(event, session, userData); break; case BLPAPI_EVENTTYPE_SESSION_STATUS: case BLPAPI_EVENTTYPE_SERVICE_STATUS: case BLPAPI_EVENTTYPE_SUBSCRIPTION_STATUS: handleStatusEvent(event, session, userData); break; default: handleOtherEvent(event, session, userData); break; } } int main() { blpapi_SessionOptions_t *sessionOptions = 0; blpapi_Session_t *session = 0; UserData_t userData = { "myLabel", stdout }; /* IBM */ const char *topic_IBM = "IBM US Equity"; const char *fields_IBM[] = { "LAST_TRADE" }; const char **options_IBM = 0; int numFields_IBM = sizeof(fields_IBM)/sizeof(*fields_IBM); int numOptions_IBM = 0; /* GOOG */ const char *topic_GOOG const char *fields_GOOG[] const char **options_GOOG int numFields_GOOG sizeof(*fields_GOOG); int numOptions_GOOG = = = = "/ticket/GOOG US Equity"; { "BID", "ASK", "LAST_TRADE" }; 0; sizeof(fields_GOOG)/
= 0;
E C Examples
326
/* MSFT */ const char *topic_MSFT const char *fields_MSFT[] const char *options_MSFT[] int numFields_MSFT sizeof(*fields_MSFT); int numOptions_MSFT sizeof(*options_MSFT);
= = = =
= sizeof(options_MSFT)/
/* CUSIP 097023105 */ const char *topic_097023105 = "/cusip/ 097023105?fields=LAST_PRICE&interval=5.0"; const char **fields_097023105 = 0; const char **options_097023105 = 0; int numFields_097023105 = 0; int numOptions_097023105 = 0; setbuf(stdout, 0); /* DO NOT SHOW */ blpapi_CorrelationId_t blpapi_CorrelationId_t blpapi_CorrelationId_t blpapi_CorrelationId_t subscriptionId_IBM; subscriptionId_GOOG; subscriptionId_MSFT; subscriptionId_097023105; sizeof(subscriptionId_IBM)); = sizeof(subscriptionId_IBM); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)10; sizeof(subscriptionId_GOOG)); = sizeof(subscriptionId_GOOG); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)20; sizeof(subscriptionId_MSFT)); = sizeof(subscriptionId_MSFT); = BLPAPI_CORRELATION_TYPE_INT; = (blpapi_UInt64_t)30;
memset(&subscriptionId_IBM, '\0', subscriptionId_IBM.size subscriptionId_IBM.valueType subscriptionId_IBM.value.intValue memset(&subscriptionId_GOOG, '\0', subscriptionId_GOOG.size subscriptionId_GOOG.valueType subscriptionId_GOOG.value.intValue memset(&subscriptionId_MSFT, '\0', subscriptionId_MSFT.size subscriptionId_MSFT.valueType subscriptionId_MSFT.value.intValue
memset(&subscriptionId_097023105, '\0', sizeof(subscriptionId_097023105)); subscriptionId_097023105.size = sizeof(subscriptionId_097023105); subscriptionId_097023105.valueType = BLPAPI_CORRELATION_TYPE_INT; subscriptionId_097023105.value.intValue = (blpapi_UInt64_t)40; sessionOptions = blpapi_SessionOptions_create(); assert(sessionOptions); blpapi_SessionOptions_setServerHost(sessionOptions, "localhost"); blpapi_SessionOptions_setServerPort(sessionOptions, "8194");
E C Examples
327
session = blpapi_Session_create(sessionOptions, &processEvent, 0, &userData); assert(session); blpapi_SessionOptions_destroy(sessionOptions); if (0 != blpapi_Session_start(session)) { fprintf(stderr, "Failed to start session.\n"); blpapi_Session_destroy(session); return 1; } if (0 != blpapi_Session_openService(session,"//blp/mktdata")){ fprintf(stderr, "Failed to open service //blp/mktdata.\n"); blpapi_Session_destroy(session); return 1; } blpapi_SubscriptionList_t *subscriptions = blpapi_SubscriptionList_create(); blpapi_SubscriptionList_add(subscriptions, topic_IBM, &subscriptionId_IBM, fields_IBM, options_IBM, numFields_IBM, numOptions_IBM); blpapi_SubscriptionList_add(subscriptions, topic_GOOG, &subscriptionId_GOOG, fields_GOOG, options_GOOG, numFields_GOOG, numOptions_GOOG); blpapi_SubscriptionList_add(subscriptions, topic_MSFT, &subscriptionId_MSFT, fields_MSFT, options_MSFT, numFields_MSFT, numOptions_MSFT); blpapi_SubscriptionList_add(subscriptions, topic_097023105, &subscriptionId_097023105, fields_097023105, options_097023105, numFields_097023105, numOptions_097023105); E C Examples 328
E C Examples
329
E C Examples
330
} handleStatusEventHandler: leave handleDataEventHandler: enter handler label=myLabel eventType=8 messageType=MarketDataEvents correlationId=1 0 10 MarketDataEvents = { LAST_PRICE = 92.410000 BID = 92.360000 ASK = 92.390000 VOLUME = 11337256 HIGH = 93.200000 LOW = 91.220000 BEST_BID = 92.360000 BEST_ASK = 92.390000 LAST_TRADE = 92.410000 OPEN = 92.130000 IMBALANCE_BID = 92.390000 IMBALANCE_ASK = ORDER_IMB_BUY_VOLUME = 44300.000000 ORDER_IMB_SELL_VOLUME = VWAP = 92.213100 THEO_PRICE = 0.000000 LAST_ALL_SESSIONS = 92.410000 IMBALANCE_INDIC_RT = BUY BID_ALL_SESSION = 92.030000 ASK_ALL_SESSION = 92.370000 TRADING_DT_REALTIME = 2009-02-05 EQY_TURNOVER_REALTIME = 1042895294.262009 NYSE_LRP_HIGH_PRICE_RT = 93.360000 NYSE_LRP_LOW_PRICE_RT = 91.360000 TOT_CALL_VOLUME_CUR_DAY_RT = 5625 TOT_PUT_VOLUME_CUR_DAY_RT = 2314 TOT_OPT_VOLUME_CUR_DAY_RT = 7939 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 0 IN_AUCTION_RT = false RT_API_MACHINE = p142 ALL_PRICE_SIZE = 1200 ALL_PRICE = 92.379200 ALL_PRICE_COND_CODE = BID_COND_CODE = ASK_COND_CODE = VOLUME_THEO = 0 LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 579500 IND_BID_FLAG = false
E C Examples
331
IND_ASK_FLAG = false OPEN_TDY = 92.130000 ASK_SIZE_TDY = 79 BID_SIZE_TDY = 5 VOLUME_TDY = 11337256 LAST_PRICE_TDY = 92.410000 BID_TDY = 92.360000 ASK_TDY = 92.390000 HIGH_TDY = 93.200000 LOW_TDY = 91.220000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 92.410000 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1 BID2 = 92.360000 ASK2 = 92.390000 SIZE_LAST_TRADE = 579500 ASK_SIZE = 79 BID_SIZE = 5 API_MACHINE = p142 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 579500 IS_DELAYED_STREAM = false EID = 14003 PREV_SES_LAST_PRICE = 92.780000 RT_PX_CHG_NET_1D = -0.369900 RT_PX_CHG_PCT_1D = -0.398684 TIME = 21:00:27.000+00:00 LAST_UPDATE_BID_RT = 21:00:22.000+00:00 LAST_UPDATE_ASK_RT = 21:00:22.000+00:00 NYSE_LRP_SEND_TIME_RT = 20:59:57.000+00:00 BID_ASK_TIME = 21:00:22.000+00:00 SES_START = 14:30:00.000+00:00 SES_END = 21:30:00.000+00:00 } handleDataEventHandler: leave handleDataEventHandler: enter handler label=myLabel eventType=8 messageType=MarketDataEvents correlationId=1 0 10 MarketDataEvents = { LAST_PRICE = 92.410000 BID = 92.360000 ASK = 92.390000 VOLUME = 11337256 BEST_BID = 92.360000 BEST_ASK = 92.390000
E C Examples
332
LAST_TRADE = 92.410000 IMBALANCE_BID = 92.390000 IMBALANCE_ASK = ORDER_IMB_BUY_VOLUME = 44300.000000 ORDER_IMB_SELL_VOLUME = VWAP = 92.251200 THEO_PRICE = 92.390000 LAST_ALL_SESSIONS = 92.410000 IMBALANCE_INDIC_RT = BUY BID_ALL_SESSION = 92.030000 ASK_ALL_SESSION = 92.370000 EQY_TURNOVER_REALTIME = 1042895294.262009 NYSE_LRP_HIGH_PRICE_RT = 93.360000 NYSE_LRP_LOW_PRICE_RT = 91.360000 TOT_CALL_VOLUME_CUR_DAY_RT = 5625 TOT_PUT_VOLUME_CUR_DAY_RT = 2314 TOT_OPT_VOLUME_CUR_DAY_RT = 7939 PUT_CALL_VOLUME_RATIO_CUR_DAY_RT = 0 IN_AUCTION_RT = false ALL_PRICE_SIZE = 1200 ALL_PRICE = 92.379200 ALL_PRICE_COND_CODE = VOLUME_THEO = 545600 LAST_AT_TRADE_TDY = 0.000000 SIZE_LAST_AT_TRADE_TDY = 0 OPEN_YLD_TDY = 0.000000 HIGH_YLD_TDY = 0.000000 LOW_YLD_TDY = 0.000000 LAST_YLD_TDY = 0.000000 MID_TDY = 0.000000 SIZE_LAST_TRADE_TDY = 579500 IND_BID_FLAG = false IND_ASK_FLAG = false OPEN_TDY = 92.130000 ASK_SIZE_TDY = 79 BID_SIZE_TDY = 5 VOLUME_TDY = 11337256 LAST_PRICE_TDY = 92.410000 BID_TDY = 92.360000 ASK_TDY = 92.390000 HIGH_TDY = 93.200000 LOW_TDY = 91.220000 BID_YLD_TDY = 0.000000 ASK_YLD_TDY = 0.000000 LAST2_PRICE = 92.410000 LAST_DIR = 1 LAST2_DIR = 1 BID_DIR = 1 ASK_DIR = 1 BID2 = 92.360000 ASK2 = 92.390000 SIZE_LAST_TRADE = 579500 ASK_SIZE = 79
E C Examples
333
BID_SIZE = 5 EXCH_CODE_LAST = EXCH_CODE_BID = EXCH_CODE_ASK = TRADE_SIZE_ALL_SESSIONS_RT = 579500 IS_DELAYED_STREAM = false EID = 14003 RT_PX_CHG_NET_1D = -0.369900 RT_PX_CHG_PCT_1D = -0.398684 TIME = 21:00:27.000+00:00 LAST_UPDATE_BID_RT = 21:00:22.000+00:00 LAST_UPDATE_ASK_RT = 21:00:22.000+00:00 NYSE_LRP_SEND_TIME_RT = 20:59:57.000+00:00 BID_ASK_TIME = 21:00:22.000+00:00 }
To learn more about the Bloomberg Open Market Data Initiative, visit open.bloomberg.com. Questions and comments about BLPAPI can be sent to [email protected]. Questions and comments about BSYM can be sent to [email protected].
open.bloomberg.com
New York
+1 212 318 2000
London
Frankfurt
San Francisco
Hong Kong
Sao Paulo
Singapore
Toyko
The BLOOMBERG PROFESSIONAL service, BLOOMBERG Data and BLOOMBERG Order Management Systems (the "Services") are owned and distributed locally by Bloomberg Finance L.P. ("BFLP") and its subsidiaries in all jurisdictions other than Argentina, Bermuda, China, India, Japan and Korea (the "BLP Countries"). BFLP is a wholly-owned subsidiary of Bloomberg L.P. ("BLP"). BLP provides BFLP with all global marketing and operational support and service for the Services and distributes the Services either directly or through a non-BFLP subsidiary in the BLP Countries. The Services include electronic trading and order-routing services, which are available only to sophisticated institutional investors and only where the necessary legal clearances have been obtained. BFLP, BLP and their affiliates do not provide investment advice or guarantee the accuracy of prices or information in the Services. Nothing on the Services shall constitute an offering of financial instruments by BFLP, BLP or their affiliates.
BLOOMBERG is a trademark of BFLP or its subsidiaries. 2012 Bloomberg Finance L.P. 47354486 0212