如何使用 python API 的 BQL Bloomberg excel 公式(xbbg 或 blpapi)?
How to use the BQL Bloomberg excel formula for python API (xbbg or blpapi)?
有没有一种方法可以在 BLPAPI 或 XBBG API 中使用 Python 中的 BQL 公式,而不是循环通过一堆代码来检索数据即所有使用 BDP 或 BDS 公式的 S&P500 股票? (这将很快达到当天的数据限制,我怀疑,因为我想检查一堆不同的指标)。
我发现了 2019 年的 post,其中建议使用 BQNT,但我更愿意避免使用 BQNT,link 此处:.
提前致谢!
除了评论之外,我还尝试了一个从 Python 驱动 Excel 的概念验证。这个 quick'n'dirty 脚本在后台打开 Excel,将 BQL 公式放入单元格,轮询 return 值,并填充 DataFrame:
import pandas as pd
import time
import win32com.client as wc
#Get a dispatch interface for the Excel app
_xl = wc.Dispatch("Excel.Application")
#Ensure the Bloomberg addin is loaded
_xl.Workbooks.Open('c:\blp\API\Office Tools\BloombergUI.xla')
#Create a new workbook
wb = _xl.Workbooks.Add()
ws = wb.Sheets(1)
cl = ws.Cells(1,1) #Cell A1 on Sheet 1
#Define BQL query, and set cell formula
qry ='=@BQL.Query("get(YIELD) for(filter(bonds([\'IBM US Equity\']),CPN_TYP==Fixed and CRNCY==USD))")'
cl.Formula=qry
_xl.Calculate()
#Check the cell's value: it will likely be #N/A ...
res = cl.Value
nLoop = 0
nTimeout = 100 #ie 10 seconds
#Loop until either get a non-# return or timeout
while res[0]=='#' and nLoop<=nTimeout:
time.sleep(0.1) #100 ms
res = cl.Value
nLoop += 1
if res[0] == '#':
print('Timed out')
return
print('Results after {0:} secs'.format(nLoop/10.0))
#The Bloomberg addin will have changed the original BQL formula
#and added a 'cols=x,rows=y' parameter at the end
#This tells us the size of the data
#as BQL doesn't seem to have the option to return a dynamic array
f = cl.Formula
rc = f.split(',')[-1].split(';')
cols = int(rc[0].split('=')[1])
s = rc[1].split('=')[1]
rows = int(s[0:len(s)-2])
#Retrieve the values from this new range
data = ws.Range(cl,ws.Cells(rows,cols)).Value
#Convert to DataFrame
df=pd.DataFrame(data[1:],columns=data[0])
print(df)
#Tidy up
_xl.DisplayAlerts = False
wb.Close()
_xl.Quit()
输出:
Results after 1.4 secs
ID YIELD
0 DD103619 Corp 1.012017
1 BJ226366 Corp 1.921489
2 DD103620 Corp 3.695580
3 ZS542668 Corp 2.945504
4 BJ226369 Corp 2.899166
5 ZS542664 Corp 1.109456
6 BJ226365 Corp 1.350594
7 ZS542666 Corp 2.732168
8 ZS542661 Corp 0.147570
9 ZS542663 Corp 0.621825
10 EJ772545 Corp 0.391708
11 EJ222340 Corp 2.846866
12 ZS542665 Corp 1.842695
13 EJ299219 Corp 0.224708
14 DD108917 Corp 3.733077
15 AM269440 Corp 0.189621
16 QJ633474 Corp 0.295588
17 BJ226367 Corp 2.727445
18 EC767655 Corp 2.241108
19 EI062653 Corp 2.728811
20 JK138051 Corp 1.077776
21 DD115180 Corp 1.604258
22 DD112334 Corp 1.527195
23 EK063561 Corp 0.570778
24 AM269866 Corp 1.329918
25 JK138053 Corp 2.915085
26 EH589075 Corp 3.110513
如果我要在生产中执行此操作,我会将整个内容包装在 class 中以避免每次我想执行查询时停止和启动 Excel。另外,我还没有测试用户已经 运行 Excel 发生了什么事情!
有没有一种方法可以在 BLPAPI 或 XBBG API 中使用 Python 中的 BQL 公式,而不是循环通过一堆代码来检索数据即所有使用 BDP 或 BDS 公式的 S&P500 股票? (这将很快达到当天的数据限制,我怀疑,因为我想检查一堆不同的指标)。
我发现了 2019 年的 post,其中建议使用 BQNT,但我更愿意避免使用 BQNT,link 此处:
提前致谢!
除了评论之外,我还尝试了一个从 Python 驱动 Excel 的概念验证。这个 quick'n'dirty 脚本在后台打开 Excel,将 BQL 公式放入单元格,轮询 return 值,并填充 DataFrame:
import pandas as pd
import time
import win32com.client as wc
#Get a dispatch interface for the Excel app
_xl = wc.Dispatch("Excel.Application")
#Ensure the Bloomberg addin is loaded
_xl.Workbooks.Open('c:\blp\API\Office Tools\BloombergUI.xla')
#Create a new workbook
wb = _xl.Workbooks.Add()
ws = wb.Sheets(1)
cl = ws.Cells(1,1) #Cell A1 on Sheet 1
#Define BQL query, and set cell formula
qry ='=@BQL.Query("get(YIELD) for(filter(bonds([\'IBM US Equity\']),CPN_TYP==Fixed and CRNCY==USD))")'
cl.Formula=qry
_xl.Calculate()
#Check the cell's value: it will likely be #N/A ...
res = cl.Value
nLoop = 0
nTimeout = 100 #ie 10 seconds
#Loop until either get a non-# return or timeout
while res[0]=='#' and nLoop<=nTimeout:
time.sleep(0.1) #100 ms
res = cl.Value
nLoop += 1
if res[0] == '#':
print('Timed out')
return
print('Results after {0:} secs'.format(nLoop/10.0))
#The Bloomberg addin will have changed the original BQL formula
#and added a 'cols=x,rows=y' parameter at the end
#This tells us the size of the data
#as BQL doesn't seem to have the option to return a dynamic array
f = cl.Formula
rc = f.split(',')[-1].split(';')
cols = int(rc[0].split('=')[1])
s = rc[1].split('=')[1]
rows = int(s[0:len(s)-2])
#Retrieve the values from this new range
data = ws.Range(cl,ws.Cells(rows,cols)).Value
#Convert to DataFrame
df=pd.DataFrame(data[1:],columns=data[0])
print(df)
#Tidy up
_xl.DisplayAlerts = False
wb.Close()
_xl.Quit()
输出:
Results after 1.4 secs
ID YIELD
0 DD103619 Corp 1.012017
1 BJ226366 Corp 1.921489
2 DD103620 Corp 3.695580
3 ZS542668 Corp 2.945504
4 BJ226369 Corp 2.899166
5 ZS542664 Corp 1.109456
6 BJ226365 Corp 1.350594
7 ZS542666 Corp 2.732168
8 ZS542661 Corp 0.147570
9 ZS542663 Corp 0.621825
10 EJ772545 Corp 0.391708
11 EJ222340 Corp 2.846866
12 ZS542665 Corp 1.842695
13 EJ299219 Corp 0.224708
14 DD108917 Corp 3.733077
15 AM269440 Corp 0.189621
16 QJ633474 Corp 0.295588
17 BJ226367 Corp 2.727445
18 EC767655 Corp 2.241108
19 EI062653 Corp 2.728811
20 JK138051 Corp 1.077776
21 DD115180 Corp 1.604258
22 DD112334 Corp 1.527195
23 EK063561 Corp 0.570778
24 AM269866 Corp 1.329918
25 JK138053 Corp 2.915085
26 EH589075 Corp 3.110513
如果我要在生产中执行此操作,我会将整个内容包装在 class 中以避免每次我想执行查询时停止和启动 Excel。另外,我还没有测试用户已经 运行 Excel 发生了什么事情!