I’m writing a program that collects cryptocurrency price information and I want to perform technical analysis on two different kline time intervals. I’ve been struggling to achieve this as I’m new to programming and even newer to Python specifically.
Below is the code I’m currently trying to get two different kline streams in at the same time.
import asyncio from datetime import datetime from binance import AsyncClient, BinanceSocketManager from threading import Thread def analyze(res): kline = res['k'] if kline['x']: #candle is completed print('{} start_sleeping {} {}'.format( datetime.now(), kline['s'], datetime.fromtimestamp(kline['t'] / 1000), )) time.sleep(5) print('{} finish_sleeping {}'.format(datetime.now(), kline['s'])) async def open_binance_stream(symbol,interval): client = AsyncClient(config.API_KEY, config.API_SECRET) bm = BinanceSocketManager(client) ts = bm.kline_socket(symbol,interval) async with ts as stream: while True: res = await stream.recv() Thread(target=analyze, args=(res)).start() await client.close_connection() async def main(): func = False if not func: await on_open() func = await asyncio.gather( open_binance_stream(TRADE_SYMBOL,interval=KLINE_INTERVAL_1MINUTE), open_binance_stream(TRADE_SYMBOL,interval=KLINE_INTERVAL_15MINUTE) ) if __name__ == "__main__": try: loop = asyncio.get_event_loop() loop.run_until_complete(main())
Unfortunately I’m getting these errors:
++connection opened with Binance++ Exception in thread Thread-1: Traceback (most recent call last): Exception in thread Thread-2: File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0libthreading.py", line 932, in _bootstrap_inner Traceback (most recent call last): File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0libthreading.py", line 932, in _bootstrap_inner self.run() File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0libthreading.py", line 870, in run self.run() File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0libthreading.py", line 870, in run self._target(*self._args, **self._kwargs) TypeError: analyze() takes 1 positional argument but 4 were given self._target(*self._args, **self._kwargs) TypeError: analyze() takes 1 positional argument but 4 were given
I don’t feel like I’m passing 4 arguments, but apperently I am. What am I doing wrong here? Any help would be greatly appreciated!
Skurring
Advertisement
Answer
Using double asterisks will make res a dictionary of all the four arguments:
def analyze(**res): print(res) kline = res['k'] if kline['x']: # candle is completed print('{} start_sleeping {} {}'.format( datetime.now(), kline['s'], datetime.fromtimestamp(kline['t'] / 1000), )) time.sleep(5) print('{} finish_sleeping {}'.format(datetime.now(), kline['s']))
Thread arguments should be sent with kwargs instead of args (this will pack arguments into a dictionary):
async def open_binance_stream(symbol, interval): client = AsyncClient(config.API_KEY, config.API_SECRET) bm = BinanceSocketManager(client) ts = bm.kline_socket(symbol, interval) async with ts as stream: while True: res = await stream.recv() Thread(target=analyze, kwargs=res).start()