Asynchrone Post-Anfragen mithilfe des Wörterbuchs der Elemente
Ich habe einen Handelsbot gebaut, der Aktien kauft / verkauft, sobald sich der Markt öffnet, und ich versuche, meine Handelsanfragen (Postanfragen) zu beschleunigen.
Ich betrachte nur etwa 350 Bestände, aber ich habe festgestellt, dass an Tagen, an denen ich eine große Anzahl von Bestellungen (200-300) abschicke, meine Anfragen bei Verwendung der requestsBibliothek ziemlich lange dauern können (~ 1,5 Minuten) . Ich wollte versuchen, die Anfragen zu verwenden asynciound aiohttpum sie schneller einzusenden, aber ich bekomme einen Fehler, den ich nicht herausfinden kann. Ich bin mit asynchronen Methoden nicht besonders vertraut, daher komme ich zu SO, um eine kleine Hilfe zu erhalten.
Nachfolgend finden Sie die asynchronen Funktionen zum Ausführen der Handels- / Post-Anfragen. Ich habe es lose auf dieser SO-Antwort basiert (Python-Async-Post-Anfragen). Der Fehler, den ich bekomme, istTypeError: 'coroutine' object is not iterable
Ich bin mir ziemlich sicher, dass dies mit dem Versuch zu tun hat, das Wörterbuch zu durchlaufen, aber ich bin mir nicht sicher, wie ich das erreichen soll, was ich will. Vielleicht muss ich die Kauf- und Verkaufsaufträge trennen, damit ich nur zwei separate Listen anstelle eines Wörterbuchs durchlaufe?
Anregungen wären hilfreich.
Anmerkungen :
- Wenn es überhaupt darauf ankommt, wird der Code über die GCP Cloud-Funktion ausgeführt.
- Das Übergeben von zwei Listen an die Funktion ist beabsichtigt. Ich muss Kauf- / Verkaufsstatistiken berechnen, bevor ich die Trades mache, und dachte, es sei am einfachsten / saubersten, sie in der
make_trades_asyncFunktion zu kombinieren .
# Example buy/sell lists:
buySymbolsList = ['MMM', 'CLX']
sellSymbolsList = ['A' 'MS']
async def make_trades_async(buySymbolsList, sellSymbolsList, token):
buyDict = dict.fromkeys(buySymbolsList, "BUY")
sellDict = dict.fromkeys(sellSymbolsList, "SELL")
trades_dict = {**sellDict, **buyDict}
url = 'https://api.tdameritrade.com/v1/accounts/{}/orders'.format(config.MARGIN_ACCOUNT)
async with aiohttp.ClientSession() as session:
post_tasks = []
# prepare the coroutines that post
async for ticker, trade_action in trades_dict.items():
post_tasks.append(do_post(session, url, ticker, trade_action, token))
# now execute them all at once
await asyncio.gather(*post_tasks)
async def do_post(session, url, ticker, trade_action, token):
async with session.post(url,
json ={"orderType": "MARKET",
"session": "NORMAL",
"duration": "DAY",
"orderStrategyType": "SINGLE",
"orderLegCollection": [{
"instruction": trade_action,
"quantity": 1,
"instrument": {
"symbol": ticker,
"assetType": "EQUITY"
}
}]
},
headers= {'Authorization': 'Bearer '+ token}
) as response:
if response.status != 201:
print("Failed to make trade for {}".format(ticker))
Die make_trades_asyncFunktion wird ausgeführt, indem Folgendes ausgeführt wird:
asyncio.run(make_trades_async(buySymbolsList=buySymbolsList,
sellSymbolsList=sellSymbolsList,
token=token))
Bearbeiten : Umgebungs- / Paketinformationen:
Python 3.7
asyncio==3.4.3
aiohttp==3.6.2
async-timeout==3.0.1
attrs==19.3.0
chardet==3.0.4
multidict==4.7.6
yarl==1.5.1
Antworten
Sie brauchen nicht asyncin Ihrer for-Schleife, Sie fügen lediglich Aufgaben synchron zu einer Liste hinzu. Wenn Sie verwenden async for, sagen Sie, dass im Generator, der Ihre Iterable erzeugt, asynchroner Code ausgeführt wird. In Ihrem Fall ist Ihre Iterable nur die Liste der Elemente im Wörterbuch, sodass keine asyncerforderlich ist.