matthewgilbert / pdblp

pandas wrapper for Bloomberg Open API
MIT License
241 stars 67 forks source link

Get dividend fields #19

Closed anastazie closed 7 years ago

anastazie commented 7 years ago

Dear Matthew, thank you for your package. I am trying to use it to get dividend data for the stock. When I run following code I get an error

con.bdh('CEZ CP Equity', 'DVD_SH_LAST', '20170101', '20170925')

ValueError: Length mismatch: Expected axis has 0 elements, new values have 4 elements

Can you please help me to structure request right?

Thanks, Anastazie

MarekOzana commented 7 years ago

Hi Anastazie, This field is available historically for Index only. image

You can get the current value: con.ref("CEZ CP Equity", "DVD_SH_LAST") which returns

ticker field value
CEZ CP Equity DVD_SH_LAST 33.0

/Marek

NoahKauffman commented 7 years ago

Use BDH() field "EQY_DPS" to pull historical DPS:

this doesn't appear filled out for CEZ CP Equity - BBG appears to be missing data for this ticker

con = pdblp.BCon(debug=True, port=8194)
con.start()

sd = datetime.datetime(2011, 1, 1, 0,0,0,0).strftime('%Y%m%d')
ed = str(datetime.datetime.today().strftime('%Y%m%d'))
tickers = ['IBM US Equity']
cols = ['EQY_DPS']
dps_historical = con.bdh(tickers, cols,sd,ed) 
dps_historical.head()

Also, a BDS() bulk field "DVD_HIST_ALL" is avail to pull more information about dividend history. To my knowledge there doesn't appear to be a straightforward way to pull BDS info in this API. The equivalent call of this excel call :

=BDS("cez cp equity","dvd_hist_all")

Can be achieved via the following pdblp call:

con = pdblp.BCon(debug=True, port=8194)
con.start()
div_history = con.ref_hist("CEZ CP Equity", "DVD_HIST_ALL", dates=['20170108'])
div_history.head()

However, note the sorting mechanism by which bloomberg returns this in the API may make it difficult to parse/use.

NoahKauffman commented 7 years ago

Mattew --

Not to confuse things by adding in a new issue to this thread, but there does seem to be some issue if you wanted to override the bdh() and convert into a different currency.

For example:

con = pdblp.BCon(debug=True, port=8194)
con.start()

sd = datetime.datetime(2011, 1, 1, 0,0,0,0).strftime('%Y%m%d')
ed = str(datetime.datetime.today().strftime('%Y%m%d'))
tickers = ['VOD LN Equity']
cols = ['EQY_DPS']
dps_historical = con.ref_hist(tickers, cols,sd,ed,[('EQY_FUND_CRNCY','USD')]) 

returns the following:

dps_historical = con.ref_hist(tickers, cols,sd,ed,[('EQY_FUND_CRNCY','USD')])
DEBUG:root:Sending Request:
 ReferenceDataRequest = {
    securities[] = {
        "VOD LN Equity"
    }
    fields[] = {
        "EQY_DPS"
    }
    overrides[] = {
        overrides = {
            fieldId = "EQY_FUND_CRNCY"
            value = "USD"
        }
        overrides = {
            fieldId = "REFERENCE_DATE"
            value = "2"
        }
    }
}

DEBUG:root:Sending Request:
 ReferenceDataRequest = {
    securities[] = {
        "VOD LN Equity"
    }
    fields[] = {
        "EQY_DPS"
    }
    overrides[] = {
        overrides = {
            fieldId = "EQY_FUND_CRNCY"
            value = "USD"
        }
        overrides = {
            fieldId = "REFERENCE_DATE"
            value = "0"
        }
    }
}

DEBUG:root:Sending Request:
 ReferenceDataRequest = {
    securities[] = {
        "VOD LN Equity"
    }
    fields[] = {
        "EQY_DPS"
    }
    overrides[] = {
        overrides = {
            fieldId = "EQY_FUND_CRNCY"
            value = "USD"
        }
        overrides = {
            fieldId = "REFERENCE_DATE"
            value = "1"
        }
    }
}

DEBUG:root:Sending Request:
 ReferenceDataRequest = {
    securities[] = {
        "VOD LN Equity"
    }
    fields[] = {
        "EQY_DPS"
    }
    overrides[] = {
        overrides = {
            fieldId = "EQY_FUND_CRNCY"
            value = "USD"
        }
        overrides = {
            fieldId = "REFERENCE_DATE"
            value = "1"
        }
    }
}

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\Python35\lib\site-packages\pdblp\pdblp.py", line 367, in ref_hist
    self.session.sendRequest(request, correlationId=cid)
  File "c:\Python35\lib\site-packages\blpapi\session.py", line 388, in sendRequest
    _ExceptionUtil.raiseOnError(res)
  File "c:\Python35\lib\site-packages\blpapi\exception.py", line 145, in raiseOnError
    _ExceptionUtil.raiseException(errorCode, description)
  File "c:\Python35\lib\site-packages\blpapi\exception.py", line 137, in raiseException
    raise errorClass(description, errorCode)
blpapi.exception.DuplicateCorrelationIdException: Duplicate correlation id: [ valueType=POINTER classId=0 value=00000000005024C8 ] (0x00020005)

I'm not sure where this "REFERENCE_DATE" is being defaulted to 1. This type of override should not need a reference_date override. I'm not sure if that is the issue, but that would be my guess.

matthewgilbert commented 7 years ago

Hi @anastazie, as @MarekOzana pointed out you can get this with ref(). If you need history you will have to check in Bloomberg if there is a reference date field which you can override for getting historical date values, such as REFERENCE_DATE (although this may not be the particular field to override for this data field).

matthewgilbert commented 7 years ago

Hi @NoahKauffman, it looks like you are calling hist_ref() improperly. From the docs

    def ref_hist(self, tickers, flds, dates, timeout=2000, ovrds=[],
                 date_field="REFERENCE_DATE"):
        """
        Get tickers and fields, periodically override date_field to create
        a time series. Return pandas dataframe with column MultiIndex
        of tickers and fields if multiple fields given, Index otherwise.
        If single field is given DataFrame is ordered same as tickers,
        otherwise MultiIndex is sorted
        Parameters
        ----------
        tickers: {list, string}
            String or list of strings corresponding to tickers
        flds: {list, string}
            String or list of strings corresponding to FLDS
        dates: list
            list of date strings in the format YYYYmmdd
        timeout: int
            Passed into nextEvent(timeout), number of milliseconds before
            timeout occurs
        ovrds: list of tuples
            List of tuples where each tuple corresponds to the override
            field and value. This should not include the date_field which will
            be iteratively overridden
        date_field: str
            Field to iteratively override for requesting historical data,
            e.g. REFERENCE_DATE, CURVE_DATE, etc.

You need to pass in a list of dates as strings, whereas you are passing in a start date and an end date.

anastazie commented 7 years ago

@MarekOzana, @NoahKauffman and @matthewgilbert Thank you a lot for clarification.