Skip to content
Advertisement

Python Binance multiple kline time intervals

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()
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement