Repository URL to install this package:
|
Version:
0.1.8 ▾
|
import pytest
import pandas as pd
import numpy as np
from pandas.util.testing import assert_frame_equal, assert_index_equal
from pdblp import pdblp
import blpapi
import os
@pytest.fixture(scope="module")
def port(request):
return request.config.getoption("--port")
@pytest.fixture(scope="module")
def host(request):
return request.config.getoption("--host")
@pytest.fixture(scope="module")
def timeout(request):
return request.config.getoption("--timeout")
@pytest.fixture(scope="module")
def con(host, port, timeout):
return pdblp.BCon(host=host, port=port, timeout=timeout).start()
@pytest.fixture(scope="module")
def data_path():
return os.path.join(os.path.dirname(__file__), "data/")
def pivot_and_assert(df, df_exp, with_date=False):
# as shown below, since the raw data returned from bbg is an array
# with unknown ordering, there is no guruantee that the `position` will
# always be the same so pivoting prior to comparison is necessary
#
# fieldData = {
# INDX_MWEIGHT[] = {
# INDX_MWEIGHT = {
# Member Ticker and Exchange Code = "BON8"
# Percentage Weight = 2.410000
# }
# INDX_MWEIGHT = {
# Member Ticker and Exchange Code = "C N8"
# Percentage Weight = 6.560000
# }
# INDX_MWEIGHT = {
# Member Ticker and Exchange Code = "CLN8"
# Percentage Weight = 7.620000
# }
# }
# }
name_cols = list(df_exp.name.unique())
sort_cols = list(df_exp.name.unique())
index_cols = ["name", "position", "field", "ticker"]
if with_date:
sort_cols.append("date")
index_cols.append("date")
df = (df.set_index(index_cols).loc[:, "value"]
.unstack(level=0).reset_index().drop(columns="position")
.sort_values(by=sort_cols, axis=0))
df_exp = (df_exp.set_index(index_cols).loc[:, "value"]
.unstack(level=0).reset_index().drop(columns="position")
.sort_values(by=sort_cols, axis=0))
# deal with mixed types resulting in str from csv read
for name in name_cols:
try:
df_exp.loc[:, name] = df_exp.loc[:, name].astype(float)
except ValueError:
pass
for name in name_cols:
try:
df.loc[:, name] = df.loc[:, name].astype(float)
except ValueError:
pass
if with_date:
df.loc[:, "date"] = pd.to_datetime(df.loc[:, "date"],
format="%Y%m%d")
df_exp.loc[:, "date"] = pd.to_datetime(df_exp.loc[:, "date"],
format="%Y%m%d")
assert_frame_equal(df, df_exp)
ifbbg = pytest.mark.skipif(pytest.config.cache.get('offline', False),
reason="No BBG connection, skipping tests")
@ifbbg
def test_bdh_empty_data_only(con):
df = con.bdh(
tickers=['1437355D US Equity'],
flds=['PX_LAST', 'VOLUME'],
start_date='20180510',
end_date='20180511',
longdata=False
)
df_exp = pd.DataFrame(
[], index=pd.DatetimeIndex([], name='date'),
columns=pd.MultiIndex.from_product([[], []],
names=('ticker', 'field'))
)
assert_frame_equal(df, df_exp)
@ifbbg
def test_bdh_empty_data_with_non_empty_data(con):
df = con.bdh(
tickers=['AAPL US Equity', '1437355D US Equity'],
flds=['PX_LAST', 'VOLUME'],
start_date='20180510',
end_date='20180511',
longdata=False
)
df_exp = pd.DataFrame(
[[190.04, 27989289.0], [188.59, 26212221.0]],
index=pd.DatetimeIndex(["20180510", "20180511"], name="date"),
columns=pd.MultiIndex.from_product([["AAPL US Equity"],
["PX_LAST", "VOLUME"]],
names=["ticker", "field"])
)
assert_frame_equal(df, df_exp)
@ifbbg
def test_bdh_partially_empty_data(con):
df = con.bdh(
tickers=['XIV US Equity', 'AAPL US Equity'],
flds=['PX_LAST'],
start_date='20180215',
end_date='20180216',
longdata=False
)
df_exp = pd.DataFrame(
[[6.04, 172.99], [np.NaN, 172.43]],
index=pd.DatetimeIndex(["20180215", "20180216"], name="date"),
columns=pd.MultiIndex.from_product(
[["XIV US Equity", "AAPL US Equity"], ["PX_LAST"]],
names=["ticker", "field"]
)
)
assert_frame_equal(df, df_exp)
@ifbbg
def test_bdh_one_ticker_one_field_pivoted(con):
df = con.bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630')
midx = pd.MultiIndex(levels=[["SPY US Equity"], ["PX_LAST"]],
labels=[[0], [0]], names=["ticker", "field"])
df_expect = pd.DataFrame(
index=pd.date_range("2015-06-29", "2015-06-30"),
columns=midx,
data=[205.42, 205.85]
)
df_expect.index.names = ["date"]
assert_frame_equal(df, df_expect)
@ifbbg
def test_bdh_one_ticker_one_field_longdata(con):
df = con.bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630',
longdata=True)
idx = pd.Index(["date", "ticker", "field", "value"])
data = [["2015-06-29", "2015-06-30"],
["SPY US Equity", "SPY US Equity"], ["PX_LAST", "PX_LAST"],
[205.42, 205.85]]
df_expect = pd.DataFrame(data=data, index=idx).transpose()
df_expect.loc[:, "date"] = pd.to_datetime(df_expect.loc[:, "date"])
df_expect.loc[:, "value"] = np.float64(df_expect.loc[:, "value"])
assert_frame_equal(df, df_expect)
@ifbbg
def test_bdh_one_ticker_two_field_pivoted(con):
cols = ['PX_LAST', 'VOLUME']
df = con.bdh('SPY US Equity', cols, '20150629', '20150630')
midx = pd.MultiIndex(
levels=[["SPY US Equity"], cols],
labels=[[0, 0], [0, 1]], names=["ticker", "field"]
)
df_expect = pd.DataFrame(
index=pd.date_range("2015-06-29", "2015-06-30"),
columns=midx,
data=[[205.42, 202621332], [205.85, 182925106]]
)
df_expect = df_expect.astype(np.float64)
df_expect.index.names = ["date"]
assert_frame_equal(df, df_expect)
@ifbbg
def test_bdh_one_ticker_two_field_longdata(con):
cols = ['PX_LAST', 'VOLUME']
df = con.bdh('SPY US Equity', cols, '20150629', '20150630',
longdata=True)
idx = pd.Index(["date", "ticker", "field", "value"])
data = [["2015-06-29", "2015-06-29", "2015-06-30", "2015-06-30"],
["SPY US Equity", "SPY US Equity", "SPY US Equity", "SPY US Equity"], # NOQA
["PX_LAST", "VOLUME", "PX_LAST", "VOLUME"],
[205.42, 202621332, 205.85, 182925106]]
df_expect = pd.DataFrame(data=data, index=idx).transpose()
df_expect.loc[:, "date"] = pd.to_datetime(df_expect.loc[:, "date"])
df_expect.loc[:, "value"] = np.float64(df_expect.loc[:, "value"])
assert_frame_equal(df, df_expect)
@ifbbg
def test_bdh_value_errors(con):
bad_col = "not_a_fld"
with pytest.raises(ValueError):
con.bdh("SPY US Equity", bad_col, "20150630", "20150630")
bad_ticker = "not_a_ticker"
with pytest.raises(ValueError):
con.bdh(bad_ticker, "PX_LAST", "20150630", "20150630")
@ifbbg
def test_bdib(con):
# BBG has limited history for the IntradayBarRequest service so request
# recent data
prev_busday = pd.Timestamp(
pd.np.busday_offset(pd.Timestamp.today().date(), -1)
)
ts1 = prev_busday.strftime("%Y-%m-%d") + "T10:00:00"
ts2 = prev_busday.strftime("%Y-%m-%d") + "T10:20:01"
df = con.bdib('SPY US Equity', ts1, ts2, event_type="BID", interval=10)
ts2e = prev_busday.strftime("%Y-%m-%d") + "T10:20:00"
idx_exp = pd.date_range(ts1, ts2e, periods=3, name="time")
col_exp = pd.Index(["open", "high", "low", "close", "volume", "numEvents"])
assert_index_equal(df.index, idx_exp)
assert_index_equal(df.columns, col_exp)
# REF TESTS
@ifbbg
def test_ref_one_ticker_one_field(con):
df = con.ref('AUD Curncy', 'NAME')
df_expect = pd.DataFrame(
columns=["ticker", "field", "value"],
data=[["AUD Curncy", "NAME", "Australian Dollar Spot"]]
)
assert_frame_equal(df, df_expect)
@ifbbg
def test_ref_one_ticker_one_field_override(con):
df = con.ref('AUD Curncy', 'SETTLE_DT',
[("REFERENCE_DATE", "20161010")])
df_expect = pd.DataFrame(
columns=["ticker", "field", "value"],
data=[["AUD Curncy", "SETTLE_DT",
pd.datetime(2016, 10, 12).date()]]
)
assert_frame_equal(df, df_expect)
@ifbbg
def test_ref_invalid_field(con):
with pytest.raises(ValueError):
con.ref("EI862261 Corp", "not_a_field")
@ifbbg
def test_ref_not_applicable_field(con):
# test both cases described in
# https://github.com/matthewgilbert/pdblp/issues/6
df = con.ref("BCOM Index", ["INDX_GWEIGHT"])
df_expect = pd.DataFrame(
[["BCOM Index", "INDX_GWEIGHT", np.NaN]],
columns=['ticker', 'field', 'value']
)
assert_frame_equal(df, df_expect)
df = con.ref("BCOM Index", ["INDX_MWEIGHT_PX2"])
df_expect = pd.DataFrame(
[["BCOM Index", "INDX_MWEIGHT_PX2", np.NaN]],
columns=['ticker', 'field', 'value']
)
assert_frame_equal(df, df_expect)
@ifbbg
def test_ref_invalid_security(con):
with pytest.raises(ValueError):
con.ref("NOT_A_TICKER", "MATURITY")
@ifbbg
def test_ref_applicable_with_not_applicable_field(con):
df = con.ref("BVIS0587 Index", ["MATURITY", "NAME"])
df_exp = pd.DataFrame(
[["BVIS0587 Index", "MATURITY", np.NaN],
["BVIS0587 Index", "NAME", "CAD Canada Govt BVAL Curve"]],
columns=["ticker", "field", "value"])
assert_frame_equal(df, df_exp)
@ifbbg
def test_ref_mixed_data_error(con):
# calling ref which returns singleton and array data throws error
with pytest.raises(ValueError):
con.ref('CL1 Comdty', 'FUT_CHAIN')
# BULKREF TESTS
@ifbbg
def test_bulkref_one_ticker_one_field(con, data_path):
df = con.bulkref('BCOM Index', 'INDX_MWEIGHT',
ovrds=[("END_DATE_OVERRIDE", "20150530")])
df_expected = pd.read_csv(
os.path.join(data_path, "bulkref_20150530.csv")
)
pivot_and_assert(df, df_expected)
@ifbbg
def test_bulkref_two_ticker_one_field(con, data_path):
df = con.bulkref(['BCOM Index', 'OEX Index'], 'INDX_MWEIGHT',
ovrds=[("END_DATE_OVERRIDE", "20150530")])
df_expected = pd.read_csv(
os.path.join(data_path, "bulkref_two_fields_20150530.csv")
)
pivot_and_assert(df, df_expected)
@ifbbg
def test_bulkref_singleton_error(con):
# calling bulkref which returns singleton throws error
with pytest.raises(ValueError):
con.bulkref('CL1 Comdty', 'FUT_CUR_GEN_TICKER')
@ifbbg
def test_bulkref_null_scalar_sub_element(con):
# related to https://github.com/matthewgilbert/pdblp/issues/32#issuecomment-385555289 # NOQA
# smoke test to check parse correctly
ovrds = [("DVD_START_DT", "19860101"), ("DVD_END_DT", "19870101")]
con.bulkref("101 HK EQUITY", "DVD_HIST", ovrds=ovrds)
@ifbbg
def test_bulkref_empty_field(con):
df = con.bulkref(["88428LAA0 Corp"], ["INDEX_LIST"])
df_exp = pd.DataFrame(
[["88428LAA0 Corp", "INDEX_LIST", np.NaN, np.NaN, np.NaN]],
columns=["ticker", "field", "name", "value", "position"]
)
assert_frame_equal(df, df_exp)
@ifbbg
def test_bulkref_empty_with_nonempty_field_smoketest(con):
con.bulkref(['88428LAA0 Corp'], ['INDEX_LIST', 'USE_OF_PROCEEDS'])
@ifbbg
def test_bulkref_not_applicable_field(con):
df = con.bulkref("CL1 Comdty", ["FUT_DLVRBLE_BNDS_ISINS"])
df_exp = pd.DataFrame(
[["CL1 Comdty", "FUT_DLVRBLE_BNDS_ISINS", np.NaN, np.NaN, np.NaN]],
columns=["ticker", "field", "name", "value", "position"]
)
assert_frame_equal(df, df_exp)
@ifbbg
def test_bulkref_not_applicable_with_applicable_field_smoketest(con):
con.bulkref('CL1 Comdty', ['OPT_CHAIN', 'FUT_DLVRBLE_BNDS_ISINS'])
# REF_HIST TESTS
@ifbbg
def test_hist_ref_one_ticker_one_field_numeric(con):
dates = ["20160104", "20160105"]
df = con.ref_hist("AUD1M CMPN Curncy", "DAYS_TO_MTY", dates)
df_expect = pd.DataFrame(
{"date": dates,
"ticker": ["AUD1M CMPN Curncy", "AUD1M CMPN Curncy"],
"field": ["DAYS_TO_MTY", "DAYS_TO_MTY"],
"value": [33, 32]}
)
assert_frame_equal(df, df_expect)
@ifbbg
def test_hist_ref_one_ticker_one_field_non_numeric(con):
dates = ["20160104", "20160105"]
df = con.ref_hist("AUD1M CMPN Curncy", "SETTLE_DT", dates)
df_expect = pd.DataFrame(
{"date": dates,
"ticker": ["AUD1M CMPN Curncy", "AUD1M CMPN Curncy"],
"field": ["SETTLE_DT", "SETTLE_DT"],
"value": 2 * [pd.datetime(2016, 2, 8).date()]}
)
assert_frame_equal(df, df_expect)
# BULKREF_HIST TESTS
@ifbbg
def test_bulkref_hist_one_field(con, data_path):
dates = ["20150530", "20160530"]
df = con.bulkref_hist('BCOM Index', 'INDX_MWEIGHT', dates=dates,
date_field='END_DATE_OVERRIDE')
df_expected = pd.read_csv(
os.path.join(data_path, "bulkref_20150530_20160530.csv")
)
pivot_and_assert(df, df_expected, with_date=True)
@ifbbg
def test_bulkhist_ref_with_alternative_reference_field(con):
# smoke test to check that the response was sent off and correctly
# received
dates = ["20160625"]
con.bulkref_hist("BVIS0587 Index", "CURVE_TENOR_RATES", dates,
date_field="CURVE_DATE")
@ifbbg
def test_context_manager(port, host):
with pdblp.bopen(host=host, port=port) as bb:
df = bb.bdh('SPY US Equity', 'PX_LAST', '20150629', '20150630')
midx = pd.MultiIndex(levels=[["SPY US Equity"], ["PX_LAST"]],
labels=[[0], [0]], names=["ticker", "field"])
df_expect = pd.DataFrame(
index=pd.date_range("2015-06-29", "2015-06-30"),
columns=midx,
data=[205.42, 205.85]
)
df_expect.index.names = ["date"]
assert_frame_equal(df, df_expect)
@ifbbg
def test_context_manager_passed_session(port, host):
sopts = blpapi.SessionOptions()
sopts.setServerHost(host)
sopts.setServerPort(port)
session = blpapi.Session(sopts)
session.start()
session.nextEvent(1000)
session.nextEvent(1000)
with pdblp.bopen(session=session) as bb: # NOQA
pass
@ifbbg
def test_multi_start(port, host, timeout):
con = pdblp.BCon(host=host, port=port, timeout=timeout)
con.start()
con.start()
@ifbbg
def test_non_empty_session_queue(port, host):
sopts = blpapi.SessionOptions()
sopts.setServerHost(host)
sopts.setServerPort(port)
session = blpapi.Session(sopts)
session.start()
with pytest.raises(ValueError):
pdblp.BCon(session=session)
@ifbbg
def test_bsrch(con):
df = con.bsrch("COMDTY:VESSEL").head()
df_expect = pd.DataFrame(["IMO1000019 Index", "LADY K II",
"IMO1000021 Index", "MONTKAJ",
"IMO1000033 Index"])
assert_frame_equal(df, df_expect)
def test_connection_error(port):
con = pdblp.BCon(port=port+1)
with pytest.raises(ConnectionError):
con.start()