Skip to main content

Bloomberg API

The Genesis Bloomberg module provides all the tools you need to connect easily to a Bloomberg API instance. This enables you to consume data directly in your Genesis application.

There are two important components:

  • The Genesis Bloomberg Client
  • The Genesis Bloomberg Connector

For a simple and quick connection, you can use the Genesis Bloomberg Connector in the Data Pipelines integration framework. You only need to deploy minimal lines of code to connect and consume Bloomberg data.

For full control and complete flexibility in how you consume the data from Bloomberg, you can use the Genesis Bloomberg Client. This is the code object that interacts with all aspects of the Bloomberg API. You can use the Genesis Bloomberg Client directly in your custom code.

info

The Genesis Bloomberg Connector uses the Genesis Bloomberg Client to implement its connection.

Adding Bloomberg to your project

To use this module, you must add the following dependency to your application:

implementation("global.genesis:bloomberg-genesis:${properties["genesisIntegrationVersion"]}")

You can also use the genx CLI to add dependencies and configuration files manually.

Powershell
npx -y @genesislcap/genx@latest add app-folder-name -x -s genesislcap/bloomberg-genesis-seed

Consuming data

Common configuration

Whether you are creating Data Pipelines or using Bloomberg Client directly in your custom code, there is a common configuration structure in GPAL. This offers auto-complete and type-safe configuration for initializing a Bloomberg Client.

bloomberg {
addServer(hostName = "localhost", port = 8194)
applicationName = "Genesis:Demo Application"
pathToPk7 = "./src/test/resources/rootCert.pk7"
pathToPk12 = "./src/test/resources/cert.pk12"
pkPassword = "********"
defaultSubscriptionService = "//blp/mktdata"
clientName = "BloombergClient"
numberOfStartAttempts = 10
reconnectionDelayMillis = 10000L
enableEntitlementChecks = true
wrapData = true
}

The addServer function enables you to add multiple IP address/port combinations, which enable the Client to connect. Each function adds a server to the underlying array, and the Client connects in a round-robin fashion. The port is optional, and defaults to 8194.

The other configuration options are :

OptionMandatoryDescription
applicationNameYesThis is the identifier for the application. When the Client connects, it first authenticates the application before requesting data. This value will be set up on the Bloomberg remote server as part of onboarding.
pathToPk7NoIf you are using a Bloomberg cloud-hosted B-PIPE instance, also referred to as 'zero footprint', a set of certificates and a password will be provided to you in order to secure the connection.
pathToPk12NoSee pathToPk7.
pkPasswordNoSee pathToPk7.
defaultSubscriptionServiceYesThe identifier for the Bloomberg service to send subscriptions to. See the Bloomberg Developer documentation for a full list of services.
clientNameNoThe name of the Client as used by process monitoring and healthchecks. Defaults to 'BloombergClient'. Change this if you want more granularity of monitoring on different Client instances within your application.
numberOfStartAttemptsNoThe number of connection attempts to make to the remote server. This is a direct configuration option on the Bloomberg API library. When this number has been exhausted, the Genesis Client will wait for the reconnection delay and then restart the session. Defaults to 10.
reconnectionDelayMillisNoThe time in milliseconds to wait before attempting to recreate and restart the session connection to Bloomberg. This configures the Genesis Client, not the underlying library. While the Genesis Client is running, it will continually attempt to connect.
enableEntitlementChecksNoBoolean flag indicating whether the Client should emit events detailing user entitlement changes to the application. If consuming data from a service that requires EID checking, the application MUST handle these events correctly in order to enforce Bloomberg EMRS entitlements and pass certification.
wrapDataNoBoolean flag indicating whether data points should be wrapped in a DataField wrapper class, which supports interrogation for data-type information. Defaults to true. Wrapping the data makes writing the consumer logic easier, at the cost of additional memory overhead in the application. For applications with a large number of topic subscriptions, or requirements to handle a large number of updates, it may be prudent to set this to false.

Using the Client directly

In order to use the Bloomberg Client directly in your code, you can inject it via dependency injection. To initialize automatically, the Client attempts to find a file matching the pattern *-bloomberg.kts included as part of the process definition.

Code Examples
import javax.inject.Inject;

public class BloombergSubscriber {
private BloombergClient client;

@Inject
public BloombergSubscriber(BloombergClient client) {
this.client = client;
}
}

Using Data Pipelines

In order to create an instance of the BloombergGateway, you can set up a Data Pipeline, which acts as both a source of Events, and a Sink for requests. To do this, you can use the bloomberg GPAL extension.

pipelines {

val bloomberg = bloomberg {
addServer("localhost", 8194)
applicationName = "TestApp"
pathToPk7 = "/certs/root.pk7"
pathToPk12 = "certs/cert.pk12"
pkPassword = "***********"
defaultSubscriptionService = "//blp/mktdata"
}

pipeline(name = "Bloomberg Subscriptions") {
source(dbBulkSubscribe<Instruments>())
.map { element ->
// Convert instrument to DataSubscription here
}
.sink(bloomberg)
}

pipeline(name = "Bloomberg Data Updates") {
source(bloomberg)
.map { element ->
// Convert Data Update to market data record here
}
.sink(dbSink())
}
}

In addition to the configuration properties detailed above, the Gateway configuration also exposes additional config options:

OptionMandatoryDescription
pipelineBufferSizeNoThe number of elements to buffer while they are waiting to be consumed by the sink. Defaults to 1000. Note that only data updates will be discarded. User entitlement updates will not be discarded and the buffer will have to clear before they can be processed.

Client API

Requests

Sending a request is how you interact with the Bloomberg Client. All requests that are sent to Bloomberg have a common supertype, BloombergRequest, which is the input type supported by the Bloomberg Sink in Data Pipelines.

DataSubscription

The DataSubscription contains the information required to subscribe to a real-time data feed from a Bloomberg API service. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.
topicStringAn identifier for the feed to subscribe to. For example, when using the market data service (//blp/mktdata) as the default subscription service, the topic should be the Bloomberg Instrument Ticker (VOD LN Equity).
fieldsList of StringA list of valid Bloomberg field identifiers (FIDs) that you want to subscribe for. See the Bloomberg Developer Documentation for more details on which FIDs are available per service.
optionsList of StringA list of additional options, such as the update frequency, or whether to subscribe for delayed data.

If using the Client directly, you can pass an instance of this request to the subscribe method.

Code Examples
import global.genesis.bloomberg.api.DataSubscription;
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.SubscriptionDataEvent;

import javax.inject.Inject;
import java.util.Arrays;
import java.util.Collections;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

public void subscribe() {
DataSubscription subscription = new DataSubscription(
"CorrelationId",
"BARC LN Equity",
Arrays.asList("BID", "ASK", "BID_SIZE", "ASK_SIZE"),
Collections.emptyList()
);

client.subscribe(subscription);
}
DataUnsubscribe

The DataUnsubscribe contains the information required to unsubscribe from a previously registered subscription. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.

If using the Client directly, you only need to pass the string value correlationId to the unsubscribe method, not the request object. If using data pipelines, you must construct the request.

Code Examples
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.SubscriptionDataEvent;

import javax.inject.Inject;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

public void unsubscribe() {
client.unsubscribe("CorrelationId");
}
}
DataRequest

Most services either support real-time subscriptions, or single (one-off) data requests. The DataRequest represents a single request for data sent to a Bloomberg API service. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.
topicStringAn identifier for the feed to subscribe to. For example, when using the market data service (//blp/mktdata) as the default subscription service, the topic should be the Bloomberg Instrument Ticker (VOD LN Equity).
fieldsList of StringA list of valid Bloomberg field identifiers (FIDs) that you want to receive data for. See the Bloomberg Developer Documentation for more details on which FIDs are available per service.
requestTypeStringThe type of request you want to send to the service. For example, ReferenceDataRequest.

If you are using the Client directly, you can pass an instance of this request to the requestData method.

Code Examples
import global.genesis.bloomberg.api.DataRequest;
import global.genesis.bloomberg.api.EventListener;

import javax.inject.Inject;
import java.util.Arrays;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

public void sendRequest() {
DataRequest request = new DataRequest(
"CorrelationId",
"ReferenceDataRequest",
"BARC LN Equity",
Arrays.asList("BID", "ASK")
);
client.requestData(request);
}
}
UserLogon

The UserLogon request triggers an authentication check with the Bloomberg entitlement system (EMRS) for the specified user. It then starts a flow of entitlement events for every user that is successfully authenticated. It contains the following fields:

FieldTypeDescription
userNameStringThe identifier of the user account within the Genesis Application
emrsIdStringThe identifier of the user as stored on the Bloomberg entitlement system (EMRS).
ipAddressStringThe IP address from which the user is currently logged into the Genesis application.

If using the Client directly, you can pass an instance of this request to the logonUser method.

Code Examples
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.UserLogon;

import javax.inject.Inject;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

public void logonUser() {
UserLogon logon = new UserLogon(
"JohnDoe",
"123456",
"127.0.0.1"
);
client.logonUser(logon);
}
}

Events

Events are received from Bloomberg. They have a common supertype, BloombergEvent, which is the output type supported by the Bloomberg Source in Data Pipelines. Receiving and processing events is how you consume data from Bloomberg.

Registering an Event Listener

In order to register a callback to receive events from the Client, call the addEventListener method, passing an instance of an object that implements the EventListener interface.

The interface has callbacks corresponding to each of the following event types. Each one has a default no-op implementation, as not all of them are applicable to every application. See below for details on each of the supported event types, and their associated methods in the EventListener.

SubscriptionDataEvent

The SubscriptionDataEvent represents an update to an active data subscription. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.
dataMap<String, DataField>The fields that were updated as part of this event. The DataField class is a wrapper for data points that can be interrogated for type information in ways friendly to Java switch and Kotlin when statements.

The following field types are supported:

Wrapper typeValue type
BooleanFieldBoolean
CharFieldChar
FloatFieldFloat
DoubleFieldDouble
IntFieldInt
LongFieldLong
StringFieldString
DateFieldorg.joda.LocalDate
TimeFieldorg.joda.LocalTime
DateTimeFieldorg.joda.LocalDateTime
ByteArrayFieldbyte[]
MapFieldMap<String, DataField>
ListFieldList<DataField>

Each time a topic update is received from Bloomberg, a SubscriptionDataEvent is passed to all registered listeners via the onSubscriptionUpdated method. This is the main callback to receive subscription data updates if wrapData is set to true in configuration, which is the default.

Code Examples
import global.genesis.bloomberg.api.DataField;
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.SubscriptionDataEvent;

import javax.inject.Inject;
import java.util.Map;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onSubscriptionUpdated(SubscriptionDataEvent event) {
// We can read the correlation ID so we know which subscription the update is for
String correlationId = event.getCorrelationId();

// We can access the wrapped data from the event
Map<String, DataField> data = event.getData();
for (Map.Entry<String, DataField> entry: data.entrySet()) {
// Here we can inspect the types provided and do any necessary conversions
switch (entry.getValue().getType()) {
case BOOLEAN -> {}
case BYTE_ARRAY -> {}
case CHAR -> {}
case DATE -> {}
case DATE_TIME -> {}
case DOUBLE -> {}
case FLOAT -> {}
case INT -> {}
case LONG -> {}
case STRING -> {}
case TIME -> {}
case MAP -> {}
case LIST -> {}
}
}
}
}
SubscriptionRawDataEvent

The SubscriptionRawDataEvent represents an update to an active data subscription. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.
dataMap<String, DataField>The fields that were updated as part of this event. The values are the raw data values extracted from the Bloomberg message.

The following field types are supported:

Value type
Boolean
Char
Float
Double
Int
Long
String
org.joda.LocalDate
org.joda.LocalTime
org.joda.LocalDateTime
byte[]
Map<String, Object>
List<Object>

Each time a topic update is received from Bloomberg, a SubscriptionRawDataEvent is passed to all registered listeners via the onSubscriptionUpdated method. This is the main callback to receive subscription data updates if wrapData is set to false in configuration.

Code Examples
import global.genesis.bloomberg.api.DataField;
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.SubscriptionRawDataEvent;

import javax.inject.Inject;
import java.util.Map;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onSubscriptionUpdated(SubscriptionDataEvent event) {
// We can read the correlation ID so we know which subscription the update is for
String correlationId = event.getCorrelationId();

// We can access the raw data from the event
Map<String, Object> data = event.getData();
}
}
DataResponseEvent

The DataResponseEvent represents a response to a previously issued one-off data request. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the request.
dataMap<String, Object>The fields returned by the response. The values are the raw data values extracted from the Bloomberg message.
moreDataBooleanIndicates whether or not there are additional responses pending. Sometimes, depending on the size of the request, multiple responses can be received.
Code Examples
import global.genesis.bloomberg.api.DataResponseEvent;
import global.genesis.bloomberg.api.EventListener;

import javax.inject.Inject;
import java.util.Map;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onDataResponse(DataResponseEvent event) {
// We can read the correlation ID so we know which request the response is for
String correlationId = event.getCorrelationId();

// We can access the raw data from the response
Map<String, Object> data = event.getData();

Integer bidSize = (Integer) data.get("BID_SIZE");
}
}
SubscriptionStatusEvent

The SubscriptionStatusEvent is sent when a subscription changes status. It contains the following fields:

FieldTypeDescription
correlationIdStringA unique identifier for the subscription.
messageStringA message providing more information about the status change.
statusSubscriptionStatus EnumThe status of the subscription. The supported status values are listed in the table below.

The supported status values are:

StatusDescription
ACTIVEThe subscription is healthy and updates are being published.
STALEThe subscription has paused, and the last received update should not be considered 'current'. The subscription can resume at a later time. There is no need to re-subscribe.
CANCELLEDThe subscription has been terminated either by Client or server request. Re-subscribing restarts the subscription.
REJECTEDThe subscription was rejected, either by being malformed or containing incorrect data. Re-subscribing will not fix the problem, and it is suggestive of an issue with the logic that is building the subscription. For example, an invalid ticker symbol could be the cause of a subscription being rejected.
Code Examples
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.SubscriptionStatusEvent;

import javax.inject.Inject;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onSubscriptionStatus(SubscriptionStatusEvent event) {
// We can read the correlation ID so we know which subscription the status event is for
String correlationId = event.getCorrelationId();

switch (event.getStatus()) {
case ACTIVE -> {}
case STALE -> {}
case CANCELLED -> {}
case REJECTED -> {}
}
}
}
UserEntitlementsUpdateEvent

The UserEntitlementsUpdateEvent is sent when the data entitlements for a user have changed. It contains the following fields:

FieldTypeDescription
userNameStringThe identifier of the user account within the Genesis application.
emrsIdStringThe identifier of the user as stored on the Bloomberg entitlement system (EMRS).
eidIntThe entitlement ID (EID) that has either been granted or denied to the user.
entitledBooleanWhether the user is entitled for this EID or not.

These events must be used to drive data visibility rules in the application.

Code Examples
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.UserEntitlementsUpdateEvent;

import javax.inject.Inject;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onUserEntitlementsUpdate(UserEntitlementsUpdateEvent event) {
String user = event.getUserName();

String emrsId = event.getEmrsId();

int eid = event.getEid();

boolean entitled = event.getEntitled();
}
}
UserEntitlementsRevokedEvent

The UserEntitlementsRevokedEvent is sent when all data entitlements for a user have been revoked. It contains the following fields:

FieldTypeDescription
userNameStringThe identifier of the user account within the Genesis application.
emrsIdStringThe identifier of the user as stored on the Bloomberg entitlement system (EMRS).

This event should be interpreted as a simultaneous receipt of a UserEntitlementsUpdateEvent for every known EID in the system, with 'entitled' set to false.

Code Examples
import global.genesis.bloomberg.api.EventListener;
import global.genesis.bloomberg.api.UserEntitlementsRevokedEvent;

import javax.inject.Inject;

public class ExampleSubscriber implements EventListener {
private BloombergClient client;

@Inject
public ExampleSubscriber(BloombergClient client) {
this.client = client;
client.addEventListener(this);
}

@Override
public void onUserEntitlementsRevoked(UserEntitlementsRevokedEvent event) {
String user = event.getUserName();
String emrsId = event.getEmrsId();
}
}

Examples

For a real-world example of how to build an application that consumes Bloomberg Market Data, see our how-to guide.