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 Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\threading.py", line 932, in _bootstrap_inner
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\threading.py", line 870, in run
self.run()
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\threading.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
CodePudding user response:
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()