Closed MarekOzana closed 7 years ago
This is a use case I had not considered. I will take a look and see what is involved to allow this.
I'm wondering what your thoughts on the expected behavior should be in a couple
scenarios. When the field
is truly non existent, not just not applicable
for a given security, I would expect to get an error. e.g.
con.ref(["EJ8189684 Corp"], ["not_a_real_field"])
DEBUG:root:Message Received:
ReferenceDataResponse = {
securityData[] = {
securityData = {
security = "EJ8189684 Corp"
eidData[] = {
}
fieldExceptions[] = {
fieldExceptions = {
fieldId = "not_a_real_field"
errorInfo = {
source = "161::bbdbd18"
code = 9
category = "BAD_FLD"
message = "Field not valid"
subcategory = "INVALID_FIELD"
}
}
}
sequenceNumber = 0
fieldData = {
}
}
}
}
whereas when the field is not applicable I agree returning a NaN is reasonable, e.g.
con.ref(["EI862261 Corp"], ["MATURITY"])
DEBUG:root:Message Received:
ReferenceDataResponse = {
securityData[] = {
securityData = {
security = "EI862261 Corp"
eidData[] = {
}
fieldExceptions[] = {
fieldExceptions = {
fieldId = "MATURITY"
errorInfo = {
source = "161::bbdbd2"
code = 9
category = "BAD_FLD"
message = "Field not applicable to security"
subcategory = "NOT_APPLICABLE_TO_REF_DATA"
}
}
}
sequenceNumber = 0
fieldData = {
}
}
}
}
These behaviours are both consistent with Rblpapi. When given a non existent ticker, my preference would be to throw an error (Currently the behaviour is buggy in the sense that it ignores the error and returns a DataFrame
without the erroneous ticker, unless all tickers are erroneous in which case it fails later when attempting to assign column names to an empty DataFrame
). I can't think of any use cases for wanting to pass in erroneous tickers? @tschm you had suggested a fix for this in #6, I'm wondering if you have any example use cases for this in mind?
con.ref(["EJ8189684 Corp", "not_a_ticker"], ["MATURITY", "NXT_CALL_DT"])
DEBUG:root:Message Received:
ReferenceDataResponse = {
securityData[] = {
securityData = {
security = "EJ8189684 Corp"
eidData[] = {
}
fieldExceptions[] = {
}
sequenceNumber = 0
fieldData = {
MATURITY = 2025-09-18
NXT_CALL_DT = 2020-09-18
}
}
securityData = {
security = "not_a_ticker"
eidData[] = {
}
securityError = {
source = "161::bbdbd10"
code = 15
category = "BAD_SEC"
message = "Unknown/Invalid security [nid:161] "
subcategory = "INVALID_SECURITY"
}
fieldExceptions[] = {
}
sequenceNumber = 1
fieldData = {
}
}
}
}
Out[29]:
ticker field value
0 EJ8189684 Corp MATURITY 2025-09-18
1 EJ8189684 Corp NXT_CALL_DT 2020-09-18
I agree with you Matthew: I would expect ref()
to either pass or return NaN
for NOT_APPLICABLE_TO_REF_DATA and raise exception in case of non existent ticker
or field
.
This is fixed in 659c0d2a8af7f8d24cf53adeb5f3790774160cdc and related to https://github.com/matthewgilbert/pdblp/issues/6
I agree with you Matthew: I would expect
ref()
to either pass or returnNaN
for NOT_APPLICABLE_TO_REF_DATA and raise exception in case of non existentticker
orfield
.
I would have to slightly disagree. While it is good to reference Excel as to what behavior to expect, the batch nature of pdblp's requests encourage some deviations from Excel. For example, you might have a large list of tickers, say 200, and as long as 1 of them is not supported (a bad strike for an option chain, for example) then the request won't resolve. I believe ideal behavior would be to handle bad tickers internally and return everything else. I might be wrong but I think it's worth a quick discussion :)
Just to follow up that i would also would like to see consistent behaviour with excel so if an invalid ticker were to be sent then it would return nan for that one but the rest would be fine. The use case as mentioned is when we have a large array of tickers that are not maintained as well as we would like due to changes, we would still like it to return those that are valid. Maybe an optional parameter such as ignore_invalid_tickers would provide full flexibility?
I am trying to produce chart of z-spread against next call / maturity for a list of all outstanding Contingent Convertible bonds. This requires to get MATURITY and /or NXT_CALL_DT fields for a list of bonds (where I do not know beforehand which bond has missing which field). The problem is that
pdblp.ref()
raises exception whenever a field does not exist for given security (e.g. MATURITY for perpetual bond). Example (3 bonds, the first having both fields, the second missing MATURITY and the last missing NXT_CALL_DT):raises NotFoundException: Attempt to access unavailable sub-element 'MATURITY' of element 'fieldData'. (0x0006000d)
Shouldn't
pdblp.ref
just ignore missing field (or return NaN)? This is exactly what Excel or Rbplapi are doing:For reference. See below the debug printout:
Note that the issue is related to #6 but not the same. The problem is not that we are naming columns of an empty DataFrame like in issue #6 .