Skip to content

Commit f5ca8f2

Browse files
committed
Added BEQS Request (aka Equity Screener)
1 parent a479605 commit f5ca8f2

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

tia/bbg/v3api.py

+75
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,77 @@ def on_event(self, evt, is_final):
615615
self.on_bar_data(data.getElement('barTickData'))
616616

617617

618+
class EQSResponse(object):
619+
def __init__(self, request):
620+
self.request = request
621+
self.response_map = defaultdict(dict)
622+
623+
def on_security_data(self, sid, fieldmap):
624+
self.response_map[sid].update(fieldmap)
625+
626+
def as_map(self):
627+
return self.response_map
628+
629+
def as_frame(self):
630+
""" :return: Multi-Index DataFrame """
631+
data = {sid: pd.Series(data) for sid, data in self.response_map.iteritems()}
632+
return pd.DataFrame.from_dict(data, orient='index')
633+
634+
635+
class EQSRequest(Request):
636+
def __init__(self, name, type='GLOBAL', group='General', asof=None, language=None):
637+
super(EQSRequest, self).__init__('//blp/refdata')
638+
self.name = name
639+
self.group = group
640+
self.type = type
641+
self.asof = asof and pd.to_datetime(asof) or None
642+
self.language = language
643+
644+
def __repr__(self):
645+
fmtargs = dict(clz=self.__class__.__name__,
646+
name=self.name,
647+
type=self.type,
648+
group=self.group,
649+
asof=self.asof)
650+
return '<{clz}({name}, type={type}, group={group}, asof={asof})'.format(**fmtargs)
651+
652+
def new_response(self):
653+
self.response = EQSResponse(self)
654+
655+
def get_bbg_request(self, svc, session):
656+
# create the bloomberg request object
657+
request = svc.createRequest('BeqsRequest')
658+
request.set('screenName', self.name)
659+
self.type and request.set('screenType', self.type)
660+
self.group and request.set('Group', self.group)
661+
overrides = {}
662+
if self.asof:
663+
overrides['PiTDate'] = self.asof.strftime('%Y%m%d')
664+
if self.language:
665+
overrides['languageId'] = self.language
666+
overrides and self.apply_overrides(request, overrides)
667+
return request
668+
669+
def on_security_node(self, node):
670+
sid = XmlHelper.get_child_value(node, 'security')
671+
farr = node.getElement('fieldData')
672+
fldnames = [str(farr.getElement(_).name()) for _ in range(farr.numElements())]
673+
fdata = XmlHelper.get_child_values(farr, fldnames)
674+
self.response.on_security_data(sid, dict(zip(fldnames, fdata)))
675+
ferrors = XmlHelper.get_field_errors(node)
676+
ferrors and self.field_errors.extend(ferrors)
677+
678+
def on_event(self, evt, is_final):
679+
""" this is invoked from in response to COM PumpWaitingMessages - different thread """
680+
for msg in XmlHelper.message_iter(evt):
681+
data = msg.getElement('data')
682+
for node, error in XmlHelper.security_iter(data.getElement('securityData')):
683+
if error:
684+
self.security_errors.append(error)
685+
else:
686+
self.on_security_node(node)
687+
688+
618689
class Terminal(object):
619690
"""Submits requests to the Bloomberg Terminal and dispatches the events back to the request
620691
object for processing.
@@ -700,6 +771,10 @@ def get_intraday_bar(self, sid, event='TRADE', start=None, end=None, interval=No
700771
adjustment_abnormal=adjustment_abnormal, adjustment_follow_DPDF=adjustment_follow_DPDF)
701772
return self.execute(req)
702773

774+
def get_screener(self, name, group='General', type='GLOBAL', asof=None, language=None):
775+
req = EQSRequest(name, type=type, group=group, asof=asof, language=language)
776+
return self.execute(req)
777+
703778

704779
class SyncSubscription(object):
705780
def __init__(self, tickers, fields, interval=None, host='localhost', port=8194):

0 commit comments

Comments
 (0)