matthewgilbert / pdblp

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

allow kwargs for overrides #48

Closed alpha-xone closed 5 years ago

alpha-xone commented 5 years ago

Able to use **kwargs for overrides.

>>> import pdblp

>>> con = pdblp.BCon(port=8194, timeout=5000)
>>> con.start()
>>> con.bulkref(tickers='JPM US Equity', flds='DVD_Hist_All', DVD_Start_Dt='20181001')
          ticker         field                name         value  position
0  JPM US Equity  DVD_Hist_All       Declared Date    2018-09-18         0
1  JPM US Equity  DVD_Hist_All             Ex-Date    2018-10-04         0
2  JPM US Equity  DVD_Hist_All         Record Date    2018-10-05         0
3  JPM US Equity  DVD_Hist_All        Payable Date    2018-10-31         0
4  JPM US Equity  DVD_Hist_All     Dividend Amount          0.80         0
5  JPM US Equity  DVD_Hist_All  Dividend Frequency       Quarter         0
6  JPM US Equity  DVD_Hist_All       Dividend Type  Regular Cash         0
matthewgilbert commented 5 years ago

Thanks for the contribution. As a matter of practice it's a good idea to first open an issue to discuss the problem the pull request is solving.

I don't see a lot of benefit in allowing people to pass overrides through kwargs. This somewhat complicates the API in my opinion and leads to confusion (in my mind at least) between how ovrds and elms are treated. Is there a particularly compelling reason for why this should be done?

alpha-xone commented 5 years ago

kwargs is more pythonic.

For elms, it's only available in bdh with pre-determined set of choices, think a better way of passing elms is integrated it to kwargs as well - any keys in kwargs belonging elms will be passed to elms, i.e.,

elements = ['days', 'fill', 'period', 'periodicityadjustment']
elms = [(k, v) for k, v in kwargs.items() if k.lower() in elements]
ovrds = [(k, v) for k, v in kwargs.items() if k.lower() not in elements]

Not sure the complete list of elms - code is just for demonstration purpose.

matthewgilbert commented 5 years ago

In my opinion I don't think the convenience for this outweighs the added complexity. If you want this functionality I would suggest just doing this with a decorator in user space

def myfunc(tickers, fields, ovrds=None):
    print(tickers)
    print(fields)
    print(ovrds)

def decorate(func):
    def wrapped(tickers, fields, ovrds=None, **kwargs):
        ovrds = [] if not ovrds else ovrds
        ovrds += [(k, v) for k, v in kwargs.items()]
        return myfunc(tickers, fields, ovrds)
    return wrapped

In [13]: myfunc("IBM Equity", "PX_LAST", [("some_overide", 10)])
IBM Equity
PX_LAST
[('some_overide', 10)]

In [14]: myfunc2 = decorate(myfunc)
In [15]: myfunc2("IBM Equity", "PX_LAST", [("some_overide", 10)], another_override=-5)
IBM Equity
PX_LAST
[('some_overide', 10), ('another_override', -5)]
alpha-xone commented 5 years ago

passing list of tuples around is far from pythonic 🤐