Я написал ниже код, но, похоже, он не дает истинного асинхронного результата.
код:
async def getOHLC(kc, symbol):
print("before .... " + symbol)
ohlc_val = kc.ohlc(symbol)
print(ohlc_val)
print("after .... " + symbol)
async def trackPrice(kc):
stocks_array = []
with open('../config/stocks.txt') as f:
for line in f:
stocks_array.append(line.rstrip('\n'))
await asyncio.gather(*[getOHLC(kc, stock) for stock in stocks_array])
if __name__ == "__main__":
import time
s = time.perf_counter()
asyncio.run(trackPrice(connect()))
elapsed = time.perf_counter() - s
print(f"{__file__} executed in {elapsed:0.2f} seconds.")
Результат:
2020-12-13 21:37:21: Establishing connection ....
before .... NSE:TCS
{'NSE:TCS': {'instrument_token': 2953217, 'last_price': 2783.6, 'ohlc': {'open': 2792.7, 'high': 2807.7, 'low': 2764.55, 'close': 2784.3}}}
after .... NSE:TCS
before .... NSE:INFY
{'NSE:INFY': {'instrument_token': 408065, 'last_price': 1163.2, 'ohlc': {'open': 1159.7, 'high': 1171.95, 'low': 1155.25, 'close': 1167.75}}}
after .... NSE:INFY
before .... NSE:WIPRO
{'NSE:WIPRO': {'instrument_token': 969473, 'last_price': 353.5, 'ohlc': {'open': 357.4, 'high': 360, 'low': 352.65, 'close': 355.9}}}
after .... NSE:WIPRO
before .... NSE:ITC
{'NSE:ITC': {'instrument_token': 424961, 'last_price': 216.3, 'ohlc': {'open': 214.45, 'high': 217.95, 'low': 213.35, 'close': 212.7}}}
after .... NSE:ITC
before .... NSE:TINPLATE
{'NSE:TINPLATE': {'instrument_token': 894209, 'last_price': 145.25, 'ohlc': {'open': 146.3, 'high': 150.4, 'low': 143.6, 'close': 145.35}}}
after .... NSE:TINPLATE
before .... NSE:ALLCARGO
{'NSE:ALLCARGO': {'instrument_token': 3456257, 'last_price': 140.9, 'ohlc': {'open': 154, 'high': 155, 'low': 138, 'close': 139.1}}}
after .... NSE:ALLCARGO
before .... NSE:GDL
{'NSE:GDL': {'instrument_token': 3004161, 'last_price': 115.05, 'ohlc': {'open': 117, 'high': 118.4, 'low': 114.7, 'close': 114.85}}}
after .... NSE:GDL
before .... NSE:RELIANCE
{'NSE:RELIANCE': {'instrument_token': 738561, 'last_price': 2005.8, 'ohlc': {'open': 2013, 'high': 2038, 'low': 1974.25, 'close': 2007}}}
after .... NSE:RELIANCE
before .... NSE:TRF
{'NSE:TRF': {'instrument_token': 4604673, 'last_price': 112.5, 'ohlc': {'open': 112.9, 'high': 116.9, 'low': 110, 'close': 106.3}}}
after .... NSE:TRF
before .... NSE:PNCINFRA
{'NSE:PNCINFRA': {'instrument_token': 2402561, 'last_price': 179.5, 'ohlc': {'open': 189.7, 'high': 189.7, 'low': 177.85, 'close': 175.15}}}
after .... NSE:PNCINFRA
before .... NSE:DMART
{'NSE:DMART': {'instrument_token': 5097729, 'last_price': 2685.1, 'ohlc': {'open': 2647, 'high': 2715, 'low': 2632, 'close': 2622.05}}}
after .... NSE:DMART
before .... NSE:HEROMOTOCO
{'NSE:HEROMOTOCO': {'instrument_token': 345089, 'last_price': 3185.3, 'ohlc': {'open': 3200, 'high': 3239.5, 'low': 3169, 'close': 3194.3}}}
after .... NSE:HEROMOTOCO
before .... NSE:MAHLOG
{'NSE:MAHLOG': {'instrument_token': 98561, 'last_price': 406.1, 'ohlc': {'open': 405, 'high': 427.95, 'low': 402.1, 'close': 390.25}}}
after .... NSE:MAHLOG
before .... NSE:IRCON
{'NSE:IRCON': {'instrument_token': 1276417, 'last_price': 90.85, 'ohlc': {'open': 96, 'high': 96, 'low': 90, 'close': 88}}}
after .... NSE:IRCON
before .... NSE:VOLTAS
{'NSE:VOLTAS': {'instrument_token': 951809, 'last_price': 804.9, 'ohlc': {'open': 814, 'high': 820.9, 'low': 800.55, 'close': 814.25}}}
after .... NSE:VOLTAS
/Users/manjulamkumar/Desktop/myRepo/DEV/autoTrade/batch/access_token.py executed in 19.84 seconds.
не могли бы вы помочь мне определить, если я что-то упустил? Получение данных по 15 акциям занимает почти 20 секунд. Хотя я ожидал, что это займет максимум 5 секунд.
В отличие от многопоточности, вы не можете применить asyncio к существующему коду и ожидать, что он станет параллельным, асинхронный код должен использовать асинхронную функциональность с нуля. Как указывает Томалак, getOHLC ничего не делает await, что является хорошим показателем того, что он «асинхронный» только по названию. Выполнение неожидающей функции не может быть приостановлено, когда функции нужно дождаться результата, и поэтому asyncio.gather() будет выполнять такие функции последовательно. Чтобы решить эту проблему, вам нужно либо переключиться на библиотеку с поддержкой asyncio, либо использовать потоки вместо asyncio.
Чтение файла является дорогостоящей операцией. Я думаю, он должен ждать там.
@user4815162342 user4815162342 Кстати, спасибо за ваши посты на SO, вы отличный учитель асинхронности :)
@madzohan Приятно слышать, спасибо!






Попробуйте открыть и прочитать файл с библиотекой aiofile и удалить второй избыточный цикл for и async-gather, и yes должен переписать все нижние вызовы для асинхронного поведения (await kc.ohlc(symbol) # ... etc)
# ...
async with AIOFile('../config/stocks.txt', 'r') as afp:
async for line in LineReader(afp):
await getOHLC(kc, line.rstrip('\n'))
# ...
Насколько я понимаю, '../config/stocks.txt' используется для списка символов конфигурации во время запуска. Основная проблема заключается в непонимании конструкции отверстий в этом коде. Функция getOHLC должна быть асинхронной по своей природе, а не просто обернутой в async def
getOHLC метод не имеет предела текучести (await something выражение).
Вот почему у asyncio нет возможности переключаться между сопрограммами.
kc.ohlc(symbol) - это вызов API, и он не кажется асинхронной функцией, и, следовательно, если я попытаюсь дождаться его ошибок.
Если это солнечно - вы не можете получить никакой выгоды от asyncio, извините.
Может быть, ваша
getOHLCфункция должна что-тоawait?