asyncio для загрузки котировок опционов от finance yahoo

#python #python-asyncio #finance #aiohttp #yahoo

Вопрос:

Я работаю над загрузчиком котировок из finance yahoo с использованием Python 3.9 с asyncio, aiohttp:

  • существует необходимость в разработке последовательной последовательности загрузки, поскольку 1-й запрос для каждого тикера опции получает все даты истечения срока действия, а 2-й запрос получает котировки опций для каждого тикера и даты истечения срока действия;
  • при загрузке только 2 тикеров все работает, но при загрузке 300-400 тикеров данные неверны;
  • Я предполагаю, что не все запросы обрабатываются.

Не могли бы вы посоветовать, как найти это узкое место? Вот код:

 def get_tasks(session, tickers):
    tasks = []
    for ticker in tickers:
        print(ticker)
        url_options1 = f"https://query2.finance.yahoo.com/v7/finance/options/{ticker}?"
        tasks.append(asyncio.create_task(session.get(url_options1, headers={'User-Agent': ua}, ssl=True)))
    return tasks


def get_tasks2(session, ticker, expiries):
    tasks2 = []
    for expiry in expiries:
        url_options2 = f"https://query2.finance.yahoo.com/v7/finance/options/{ticker}?amp;date={expiry}"
        tasks2.append(asyncio.create_task(session.get(url_options2, headers={'User-Agent': ua}, ssl=True)))
    return tasks2

async def get_optiondata(tickers):

    results1 = []

    async with aiohttp.ClientSession() as session:
        tasks = get_tasks(session, tickers)
        responses = await asyncio.gather(*tasks)
        for response in responses:
            results1.append(await response.json())

    return results1


async def get_optiondata2(ticker, expiries):

    results2 = []

    async with aiohttp.ClientSession() as session:
        tasks2 = get_tasks2(session, ticker, expiries)
        responses = await asyncio.gather(*tasks2)
        for response in responses:
            results2.append(await response.json())
    return results2

datas = asyncio.run(get_optiondata(usTickers))

results = []
tickers = []
expiries = []

for i in range(len(datas)):
    try:
        symbol = datas[i]['optionChain']['result'][0]['underlyingSymbol']
        tickers.append(symbol)
        if datas[i]['optionChain']['result'][0]['expirationDates']:
            expiries.append(datas[i]['optionChain']['result'][0]['expirationDates'])

    except IndexError as e:
        print(f"{i} {e}")

for i in range(len(tickers)):

    datas2 = asyncio.run(get_optiondata2(tickers[i], expiries[i]), debug=True)
 

Комментарии:

1. Что означает «данные неверны»? Что именно происходит?

2. Привет «данные неверны» — означает, что ответ на запрос не содержит всех дат истечения срока действия. например, тикер «A» — 7 дат истечения срока действия, но только 2 возвращаются ответом

3. Вы не получаете даты истечения срока действия обратно из API или вы удаляете их где-то в своем коде?

Ответ №1:

Вы можете изменить параметры запроса для этой конечной точки, чтобы получить все даты истечения срока действия для тикера:

 url = 'https://query2.finance.yahoo.com/v7/finance/options/{ticker}?getAllData=true'