2

Using xbbg, i try to retrieve the bloomberg swap curve (s23 also known as YCSW0023 Index).

To do so I do :

from xbbg import blp
import asyncio

async def main():
    async for d in blp.live('s23', max_cnt = 1):
        print(d)
    await main()
    
    
main()

But it does only returns :

V:\ABCD.py:16: RuntimeWarning: coroutine 'main' was never awaited
  main()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Does this mean that I use the wrong ticker ? Does this mean that I use wrong syntax or anything else ?

On excel to retrieve live curve we do :

=BCURVE("S23")
TourEiffel
  • 4,034
  • 2
  • 16
  • 45
  • For your error check this https://stackoverflow.com/questions/54441424/learning-asyncio-coroutine-was-never-awaited-warning-error – ghost21blade Aug 10 '22 at 10:43
  • Take a look at what `=BCurve("S23")` is actually doing in Excel. It basically returns a static definition of the instruments in the curve with tickers. Then there is a live subscription for each of those tickers (`=BDP()`). So you don't subscribe `live` to the curve: you subscribe to each of the individual elements. – DS_London Aug 11 '22 at 09:15
  • @DS_London So how would you do ? Many thanks – TourEiffel Aug 11 '22 at 09:26

1 Answers1

2

In Excel the BCurve() function is doing a lot of things:

  • resolving the S23 curve id to the YCSW0023 Index curve ticker (probably using the low-level //blp/instruments Bloomberg api service)
  • getting the curve members using one of the bulk data fields (possibly PAR_CURVE)
  • Listing the curve instruments, tenor and type on the spreadsheet
  • Creating individual bdp function calls in the cells which depend on the instrument type: some will be 'live' streaming prices, but others (eg fixings) will not; some will convert futures price to rate, some will not.

How you handle this will depend on what end-use you have for the curve. Do you want a one-off snapshot of the latest rates, or do you want live rates to keep ticking away in the background, constantly updating the curve?

Since I can't guess your exact requirement, here is a possible example (I have left out the curve id / curve ticker conversion). This should at least give you a starting point for the various functions.

from xbbg import blp
import asyncio
import re

async def getTicks(result, tkrs):
    remaining = len(tkrs)
    async for tick in blp.live(tkrs,flds=['BID'],max_cnt=0):       
        tkr = tick['TICKER']
        res = result[tkr]

        if res['Rate'] is None:
            remaining -= 1

        #Change futures prices to rates
        if res['Type'] == 'FUTURE_RATE':
            res['Rate'] = 100 - tick['BID']
        else:
            res['Rate'] = tick['BID']

        #Break out if have a rate for all tickers
        if remaining <= 0: break

curveTicker = 'YCSW0023 Index'

#Get the bulk data for par curve members
members = blp.bds(curveTicker,'PAR_CURVE')

tickers = [re.sub(' +', ' ',tkr) for tkr in members.ticker] #Get rid of extra spaces in ticker
tenors = [tnr for tnr in members.tenor]
types = [typ for typ in members.point_type]

results = { tickers[n]:{'Tenor':tenors[n],'Type': types[n],'Rate':None} for n in range(len(tickers))}

live_tickers = []
#Use bdp() for non-live rates (eg fixings)
for tkr in results:
    res = results[tkr]
    if res['Type'] == 'CASH':
        res['Rate'] = blp.bdp(tkr,'PX_LAST').iloc[0][0]
    else:
        live_tickers.append(tkr)

#Kick off the capture of the live subscriptions
asyncio.run(getTicks(results,live_tickers))

for inst in results:
    print(inst,results[inst])

With the output:

US0003M Index {'Tenor': '3 MO', 'Type': 'CASH', 'Rate': 2.9210000000000003}
EDU2 Comdty {'Tenor': '128 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.3299999999999983}
EDZ2 Comdty {'Tenor': '212 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.8400000000000034}
EDH3 Comdty {'Tenor': '310 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.7900000000000063}
EDM3 Comdty {'Tenor': '401 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.6500000000000057}
EDU3 Comdty {'Tenor': '492 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.424999999999997}
EDZ3 Comdty {'Tenor': '583 DY', 'Type': 'FUTURE_RATE', 'Rate': 3.219999999999999}
USSWAP2 Curncy {'Tenor': '2 YR', 'Type': 'SWAP', 'Rate': 3.4258}
USSWAP3 Curncy {'Tenor': '3 YR', 'Type': 'SWAP', 'Rate': 3.1821}
USSWAP4 Curncy {'Tenor': '4 YR', 'Type': 'SWAP', 'Rate': 3.0191}
USSWAP5 Curncy {'Tenor': '5 YR', 'Type': 'SWAP', 'Rate': 2.9225}
USSW6 Curncy {'Tenor': '6 YR', 'Type': 'SWAP', 'Rate': 2.8721}
USSWAP7 Curncy {'Tenor': '7 YR', 'Type': 'SWAP', 'Rate': 2.8436}
USSW8 Curncy {'Tenor': '8 YR', 'Type': 'SWAP', 'Rate': 2.8264}
USSW9 Curncy {'Tenor': '9 YR', 'Type': 'SWAP', 'Rate': 2.8231}
USSWAP10 Curncy {'Tenor': '10 YR', 'Type': 'SWAP', 'Rate': 2.8309}
USSWAP11 Curncy {'Tenor': '11 YR', 'Type': 'SWAP', 'Rate': 2.852}
USSWAP12 Curncy {'Tenor': '12 YR', 'Type': 'SWAP', 'Rate': 2.8632}
USSWAP15 Curncy {'Tenor': '15 YR', 'Type': 'SWAP', 'Rate': 2.9057}
USSWAP20 Curncy {'Tenor': '20 YR', 'Type': 'SWAP', 'Rate': 2.9057}
USSWAP25 Curncy {'Tenor': '25 YR', 'Type': 'SWAP', 'Rate': 2.8384}
USSWAP30 Curncy {'Tenor': '30 YR', 'Type': 'SWAP', 'Rate': 2.7625}
USSWAP40 Curncy {'Tenor': '40 YR', 'Type': 'SWAP', 'Rate': 2.5562}
USSWAP50 Curncy {'Tenor': '50 YR', 'Type': 'SWAP', 'Rate': 2.3034}
DS_London
  • 3,644
  • 1
  • 7
  • 24
  • Many thanks for this amzing answer which is working fine with `bdp`. If i try to use live datas I still have the following error : RuntimeError: asyncio.run() cannot be called from a running event loop – TourEiffel Aug 11 '22 at 14:11
  • @TourEiffel I’m afraid async Python is not really my speciality. Maybe study the link given in the comments. Unfortunately the ’xbbg` documentation is quite sparse, but you have the Python code so you can look through that. – DS_London Aug 11 '22 at 18:31