Tutorial on using pdblp

This tutorial provides some simple use cases for pdblp . To start with, import the library and create a BCon() object

In [1]: import pdblp

In [2]: con = pdblp.BCon(debug=True, port=8194, timeout=5000)

Make sure that you are logged in to a Bloomberg terminal, after which you should be able to to start a connection as follows

In [3]: con.start()

To get some historical data, we can call bdh()

In [4]: con.bdh('SPY US Equity', 'PX_LAST',
                '20150629', '20150630')
DEBUG:root:Sending Request:
 HistoricalDataRequest = {
    securities[] = {
        "SPY US Equity"
    }
    fields[] = {
        "PX_LAST"
    }
    periodicityAdjustment = ACTUAL
    periodicitySelection = DAILY
    startDate = "20150629"
    endDate = "20150630"
    overrides[] = {
    }
}
DEBUG:root:Message Received:
 HistoricalDataResponse = {
    securityData = {
        security = "SPY US Equity"
        eidData[] = {
        }
        sequenceNumber = 0
        fieldExceptions[] = {
        }
        fieldData[] = {
            fieldData = {
                date = 2015-06-29
                PX_LAST = 205.420000
            }
            fieldData = {
                date = 2015-06-30
                PX_LAST = 205.850000
            }
        }
    }
}
Out[4]: 
ticker      SPY US Equity
2015-06-29         205.42
2015-06-30         205.85

Notice that when con.debug == True that the Response and Request messages are printed to stdout. This can be quite useful for debugging but gets annoying for normal use, so let’s turn it off and get some more data. This time we request two fields which returns a DataFrame with a MultiIndex by default.

In [5]: con.debug = False

In [6]: con.bdh('SPY US Equity', ['PX_LAST', 'VOLUME'],
   ...:         '20150629', '20150630')
   ...: 
Out[6]: 
ticker     SPY US Equity             
field            PX_LAST       VOLUME
date                                 
2015-06-29        205.42  202621332.0
2015-06-30        205.85  182925106.0

But can also return data in long format

In [7]: con.bdh('SPY US Equity', ['PX_LAST', 'VOLUME'],
   ...:         '20150629', '20150630', longdata=True)
   ...: 
Out[7]: 
        date         ticker    field         value
0 2015-06-29  SPY US Equity  PX_LAST  2.054200e+02
1 2015-06-29  SPY US Equity   VOLUME  2.026213e+08
2 2015-06-30  SPY US Equity  PX_LAST  2.058500e+02
3 2015-06-30  SPY US Equity   VOLUME  1.829251e+08

You can also override different FLDS’s, for example

In [8]: con.bdh('MPMIEZMA Index', 'PX_LAST',
   ...:         '20150101', '20150830')
   ...: 
Out[8]: 
ticker     MPMIEZMA Index
field             PX_LAST
date                     
2015-06-30           52.5
2015-07-31           52.4

In [9]: con.bdh('MPMIEZMA Index', 'PX_LAST',
   ...:         '20150101', '20150830',
   ...:         ovrds=[('RELEASE_STAGE_OVERRIDE', 'P')])
   ...: 
Out[9]: 
ticker     MPMIEZMA Index
field             PX_LAST
date                     
2015-04-30           51.9

The context can also be managage using bopen

In [10]: with pdblp.bopen(port=8194) as bb:
   ....:     df = bb.bdh('SPY US Equity', 'PX_LAST',
   ....:                 '20150629', '20150630')
   ....: 

The libary also contains functions for accessing reference data, a variety of usages are shown below

In [11]: con.ref('AUDUSD Curncy', 'SETTLE_DT')
Out[11]: 
          ticker      field       value
0  AUDUSD Curncy  SETTLE_DT  2018-06-06

In [12]: con.ref(['NZDUSD Curncy', 'AUDUSD Curncy'], 'SETTLE_DT')
Out[12]: 
          ticker      field       value
0  NZDUSD Curncy  SETTLE_DT  2018-06-06
1  AUDUSD Curncy  SETTLE_DT  2018-06-06

In [13]: con.ref('AUDUSD Curncy', ['SETTLE_DT', 'DAYS_TO_MTY'])
Out[13]: 
          ticker        field       value
0  AUDUSD Curncy    SETTLE_DT  2018-06-06
1  AUDUSD Curncy  DAYS_TO_MTY           0

In [14]: con.ref(['NZDUSD Curncy', 'AUDUSD Curncy'],
   ....:         ['SETTLE_DT', 'DAYS_TO_MTY'])
   ....: 
Out[14]: 
          ticker        field       value
0  NZDUSD Curncy    SETTLE_DT  2018-06-06
1  NZDUSD Curncy  DAYS_TO_MTY           0
2  AUDUSD Curncy    SETTLE_DT  2018-06-06
3  AUDUSD Curncy  DAYS_TO_MTY           0

In [15]: con.ref('AUDUSD Curncy', 'SETTLE_DT',
   ....:         [('REFERENCE_DATE', '20150715')])
   ....: 
Out[15]: 
          ticker      field       value
0  AUDUSD Curncy  SETTLE_DT  2015-07-17

In [16]: con.ref(['NZDUSD Curncy', 'AUDUSD Curncy'],
   ....:         ['SETTLE_DT', 'DAYS_TO_MTY'],
   ....:         [('REFERENCE_DATE', '20150715')])
   ....: 
Out[16]: 
          ticker        field       value
0  NZDUSD Curncy    SETTLE_DT  2015-07-17
1  NZDUSD Curncy  DAYS_TO_MTY           0
2  AUDUSD Curncy    SETTLE_DT  2015-07-17
3  AUDUSD Curncy  DAYS_TO_MTY           0

In [17]: con.bulkref('W 1 Comdty', 'FUT_CHAIN',
   ....:             [('INCLUDE_EXPIRED_CONTRACTS', 'Y')]).head()
   ....: 
Out[17]: 
       ticker      field                  name         value  position
0  W 1 Comdty  FUT_CHAIN  Security Description  W N59 Comdty         0
1  W 1 Comdty  FUT_CHAIN  Security Description  W U59 Comdty         1
2  W 1 Comdty  FUT_CHAIN  Security Description  W Z59 Comdty         2
3  W 1 Comdty  FUT_CHAIN  Security Description  W H60 Comdty         3
4  W 1 Comdty  FUT_CHAIN  Security Description  W K60 Comdty         4

There are some types of reference data which cannot be downloaded in batch but support overriding the reference date. For this type of data, ref_hist() is useful to sequentially override the reference date to generate a time series. A word of caution, under the hood this is making a number of ReferenceDataRequest s and thus can throttle your daily data limits if queried over large date ranges.

In [18]: con.ref_hist('AUD1M Curncy', 'DAYS_TO_MTY',
   ....:              dates=['20150625', '20150626'])
   ....: 
Out[18]: 
       date        ticker        field  value
0  20150625  AUD1M Curncy  DAYS_TO_MTY     30
1  20150626  AUD1M Curncy  DAYS_TO_MTY     31

In [19]: con.ref_hist(['AUD1M Curncy', 'NZD1M Curncy'],
   ....:               'DAYS_TO_MTY',
   ....:               dates=['20150625', '20150626'])
   ....: 
Out[19]: 
       date        ticker        field  value
0  20150625  AUD1M Curncy  DAYS_TO_MTY     30
1  20150625  NZD1M Curncy  DAYS_TO_MTY     30
2  20150626  AUD1M Curncy  DAYS_TO_MTY     31
3  20150626  NZD1M Curncy  DAYS_TO_MTY     31

In [20]: con.ref_hist('AUD1M Curncy', ['DAYS_TO_MTY', 'SETTLE_DT'],
   ....:              dates=['20150625', '20150626'])
   ....: 
Out[20]: 
       date        ticker        field       value
0  20150625  AUD1M Curncy  DAYS_TO_MTY          30
1  20150625  AUD1M Curncy    SETTLE_DT  2015-07-29
2  20150626  AUD1M Curncy  DAYS_TO_MTY          31
3  20150626  AUD1M Curncy    SETTLE_DT  2015-07-31

In [21]: con.ref_hist(['AUD1M Curncy', 'NZD1M Curncy'],
   ....:              ['DAYS_TO_MTY', 'SETTLE_DT'],
   ....:              dates=['20150625', '20150626'])
   ....: 
Out[21]: 
       date        ticker        field       value
0  20150625  AUD1M Curncy  DAYS_TO_MTY          30
1  20150625  AUD1M Curncy    SETTLE_DT  2015-07-29
2  20150625  NZD1M Curncy  DAYS_TO_MTY          30
3  20150625  NZD1M Curncy    SETTLE_DT  2015-07-29
4  20150626  AUD1M Curncy  DAYS_TO_MTY          31
5  20150626  AUD1M Curncy    SETTLE_DT  2015-07-31
6  20150626  NZD1M Curncy  DAYS_TO_MTY          31
7  20150626  NZD1M Curncy    SETTLE_DT  2015-07-31

In [22]: con.ref_hist(['AUD1M Curncy', 'NZD1M Curncy'],
   ....:              ['DAYS_TO_MTY', 'SETTLE_DT'],
   ....:              dates=['20150625', '20150626'])
   ....: 
Out[22]: 
       date        ticker        field       value
0  20150625  AUD1M Curncy  DAYS_TO_MTY          30
1  20150625  AUD1M Curncy    SETTLE_DT  2015-07-29
2  20150625  NZD1M Curncy  DAYS_TO_MTY          30
3  20150625  NZD1M Curncy    SETTLE_DT  2015-07-29
4  20150626  AUD1M Curncy  DAYS_TO_MTY          31
5  20150626  AUD1M Curncy    SETTLE_DT  2015-07-31
6  20150626  NZD1M Curncy  DAYS_TO_MTY          31
7  20150626  NZD1M Curncy    SETTLE_DT  2015-07-31

In [23]: con.bulkref_hist("BVIS0587 Index", "CURVE_TENOR_RATES",
   ....:                  dates=['20160625'],
   ....:                 date_field="CURVE_DATE").head()
   ....: 
Out[23]: 
       date          ticker              field          name           value  position
0  20160625  BVIS0587 Index  CURVE_TENOR_RATES         Tenor              3M         0
1  20160625  BVIS0587 Index  CURVE_TENOR_RATES  Tenor Ticker  BV3M0101 Index         0
2  20160625  BVIS0587 Index  CURVE_TENOR_RATES     Ask Yield    -2.42454e-14         0
3  20160625  BVIS0587 Index  CURVE_TENOR_RATES     Mid Yield    -2.42454e-14         0
4  20160625  BVIS0587 Index  CURVE_TENOR_RATES     Bid Yield           0.504         0

A useful trick to avoid throttling your connection when querying large data or to ensure you can reproduce your results without a connection in the future is to make use of the excellent joblib library. For example

In [24]: import joblib

In [25]: import shutil

In [26]: from tempfile import mkdtemp

In [27]: temp_dir = mkdtemp()

In [28]: cacher = joblib.Memory(temp_dir)

In [29]: bdh = cacher.cache(con.bdh, ignore=['self'])

In [30]: bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630')
________________________________________________________________________________
[Memory] Calling pdblp.pdblp.bdh...
bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630')
______________________________________________________________bdh - 0.1s, 0.0min
Out[30]: 
ticker     SPY US Equity
field            PX_LAST
date                    
2015-06-29        205.42
2015-06-30        205.85

In [31]: bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630')
Out[31]: 
ticker     SPY US Equity
field            PX_LAST
date                    
2015-06-29        205.42
2015-06-30        205.85

In [32]: shutil.rmtree(temp_dir)

You can also access Bloomberg SRCH data using bsrch

In [33]: con.bsrch("COMDTY:VESSEL").head()
Out[33]: 
                  0
0  IMO1000019 Index
1         LADY K II
2  IMO1000021 Index
3           MONTKAJ
4  IMO1000033 Index