how to extract data from binance websockets with ThreadedWebsocketManager? - python

I have this code:
from http import client
from operator import index
import asyncio
from binance.streams import ThreadedWebsocketManager, AsyncClient, BinanceSocketManager
import pandas as pd
import config
from binance.client import Client
indexes=[1.1,2.2,3.3,4.4,5.5]
def streaming_data_process(msg):
"""
Function to process the received messages
param msg: input message
"""
print(f"message type: {msg['e']}")
print(f"close price: {msg['c']}")
print(f"best ask price: {msg['a']}")
print(f"best bid price: {msg['b']}")
print("---------------------------")
return msg
def trade_history(msg):
''' define how to process incoming WebSocket messages '''
if msg['e'] != 'error':
print(msg)
print(msg['c'])
print(msg['E'])
print(msg['o'])
print(msg['h'])
print(msg['l'])
print(msg['v'])
btc_price['last'] = msg['c']
btc_price['bid'] = msg['b']
btc_price['last'] = msg['a']
btc_price['error'] = False
indexes[0]=msg['E']
indexes[1]=msg['o']
indexes[2]=msg['h']
indexes[3]=msg['l']
indexes[4]=msg['v']
#indexes[5]=msg['c']
print(indexes)
return indexes, btc_price['last']
else:
btc_price['error'] = True
# Aqui quieres devolver algo? O que actualice esto pero no devuelva nada?
if __name__ == "__main__":
client = Client(config.API_KEY, config.API_SECRET, tld='com')
symbolo='BTCUSDT'
btc_price = {'error':False}
#tiempo = msg['E']
# init and start the WebSocket
bsm = ThreadedWebsocketManager()
bsm.start()
# subscribe to a stream
# Aquí deberías llamar a trade_history con el debido mensaje
bsm.start_symbol_ticker_socket(callback=trade_history, symbol=symbolo)
I need to extract the data from indexes, I need to use the msg[h],[l],[c],[o],[v] and [E]
to use it in this:
df['Date'] = pd.to_datetime(df['Date'], unit='ms')
df.set_index('Date', inplace=True, drop=True)
#data = data.drop(data.columns[0],axis=1)
o=df['Open'] = df['Open'].astype(float)
h=df['High'] = df['High'].astype(float)
l=df['Low'] = df['Low'].astype(float)
c=df['Close'] = df['Close'].astype(float)
v=df['Volume'] = df['Volume'].astype(float)
what is the correct way to do this, I dont know if its with a json, or how ever the way it needs to be done, but yes, I need to extract the data form msg[E] .... to use it in the df list. how has it to be done?

Related

RuntimeError: Timeout context manager should be used inside a task when using threading and async io in aiogram

i tried to create a telegram bot in aiogram to send messages if a particular share price is reached. im using threading in order to run this in background as the bot takes user inputs. basically it takes a dict and takes the key as ticker for yfinance and gets the current price and compares with the given condition and if its a true condition it will send the alert to a chat. this is the code
#bot info
import yfinance as yf
import logging
logging.basicConfig(level=logging.INFO)
from aiogram import Bot, Dispatcher, executor
import asyncio
import threading
bot = Bot(token='bot api key')
dp = Dispatcher(bot)
sh={}
jk={}
#reads a dict from a text file
with open('shares.txt','r') as f:
a=f.read()
b=a.rstrip('}').lstrip('{').split(',')
for i in b:
try:
c=i.split(':')
com_name=c[0].strip().strip(''' ' ''').strip()
com_price=float(c[1])
sh[com_name]=com_price
except:
sh={}
break
async def send_price(pp: str):
await bot.send_message(chat_id=user chat id, text=str(pp))
#price updater
def pp():
while True:
pl = sh.copy()
index = ''
for keys, values in list(pl.items()):
if keys in jk and pl[keys] == jk[keys]:
del pl[keys]
print(pl)
kj = pl
if len(kj)==0:
break
for i in kj:
if kj[i]==0:
break
s = yf.Ticker(i)
a = (s.info)['currentPrice']
# print(s,a)
if kj[i] == 0:
continue
# print('kj',kj[i])
if kj[i] <= a:
index += (f'{i} is currently up rn up with current price being {str(a)} \n')
jk[i] = kj[i]
#print(index)
if len(index) != 0:
asyncio.run(send_price(index))
threading.Thread(target=pp).start()
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
when i run the code i get this error .
RuntimeError: Timeout context manager should be used inside a task

How to use websocket-client and Thread as a claass?

I need to call my class >> CotarMoedas another python file.
But I need to get return of cons live stream as result.
#https://www.youtube.com/watch?v=pxyaENuoZUM&list=PL9ATnizYJ7f8_opOpLnekEZNsNVUVbCZN&index=47
import websocket
import json
import pandas as pd
from sqlalchemy import create_engine
from threading import Thread
engine = create_engine('sqlite:///COINS.db')
class CotarMoedas:
def __init__(self):
self.endpoint = 'wss://stream.binance.com:9443/ws/!miniTicker#arr'
tr = Thread(target=self.call_ws)
tr.start()
def df_import(self, data):
#Pegar os valores dos pares casados com USDT
df_ = pd.DataFrame(data)
df_ = df_[df_['s'].str.endswith('USDT')]
df_.c = df_.c.astype(float)
final = df_[['s','E','c']]
for i in range(len(final)):
row_ = final[i:i+1]
#print(row_)
row_[['E','c']].to_sql(row_.s.values[0], engine, index=False, if_exists='append')
def best_conin(self):
engine = create_engine('sqlite:///COINS.db')
dfs = pd.read_sql("""SELECT name FROM sqlite_master WHERE type='table'""", engine)
tables = dfs.name.to_list()
reutrns = []
for table in tables:
df__ = pd.read_sql(table,engine)
# ret_ = (df__.tail(20).c.pct_change() + 1).prod() - 1 # Os 20 mais recentes
ret_ = (df__.c.pct_change() + 1).prod() - 1
reutrns.append(ret_)
rst = pd.Series(reutrns).nlargest(10)
rst.sort_values()
bv = rst.to_dict()
ls = []
for k, v in bv.items():
ls.append([tables[k],v])
tt = print(tables[k],v)
return tt
def on_close(self,ws):
print('Conexão encerrada!')
def on_message(self, ws, message):
out = json.loads(message)
#print(out)
df_import(out)
print('============')
best_conin()
def call_ws(self):
ws = websocket.WebSocketApp(self.endpoint, on_message=self.on_message, on_close=self.on_close)
ws.run_forever()
But I traying call it like this
from videos_algovibes.cotacao import CotarMoedas
rst = CotarMoedas()
vai = rst.best_conin()
if __name__ == "__main__":
print(vai)
I'm simplifying the code :
#https://www.youtube.com/watch?v=pxyaENuoZUM&list=PL9ATnizYJ7f8_opOpLnekEZNsNVUVbCZN&index=47
import websocket
import json
import pandas as pd
from sqlalchemy import create_engine
from threading import Thread
import threading
class CotarMoedas:
def __init__(self):
self.endpoint = 'wss://stream.binance.com:9443/ws/!miniTicker#arr'
#tr = Thread(target=self.call_ws)
#tr.start()
self.call_ws()
def best_conin(self):
print("Best coin")
def on_close(self,ws):
print('Conexão encerrada!')
def on_message(self, ws, message):
def run(*args):
print(message)
print("Message received...")
threading.Thread(target=run).start()
def call_ws(self):
def _call_ws():
ws = websocket.WebSocketApp(self.endpoint, on_message=self.on_message, on_close=self.on_close)
ws.run_forever()
threading.Thread(target=_call_ws).start()
https://youtu.be/pDslZbvO7Hs
As you can see in the video.
Threading could be handled this way.
Good luck with SQLAlchemy, Sessions, etc.

RealSense camera: stop() cannot be called before start()

i have a problem on my code.
I need to receive some packages post from antennas and receive the same frame from camera, tryng to tyng up the packgae (json) to the frame.
I have an exception like this:
stop() cannot be called before start()
and the code looks like:
import pyrealsense2 as rs
import cv2
import numpy as np
import datetime
from app import app
from flask import request, jsonify
import io, json
i = 0
resp = None
pipeline = None
#app.route("/file-upload", methods=["POST"])
def upload_file():
global pipeline
#print("Create pipeline")
#pipeline = create_pipeline()
pipeline = rs.pipeline()
cfg = rs.config()
cfg.enable_stream(rs.stream.color, 1280, 720, rs.format.bgr8, 45)
pipeline.start(cfg)
string = request.data
string = string.decode('utf-8')
frames = pipeline.wait_for_frames()
color_frame = frames.get_color_frame()
Current_Time = datetime.datetime.now() # .time() or .date()
timestampStr = Current_Time.strftime("%d-%b-%Y -- %H-%M-%S.%f")
if not color_frame:
print("Color frame non presente")
color_image = np.asanyarray(color_frame.get_data())
if string is not None:
payload = json.loads(string)
else:
resp = jsonify({'message': "Il payload è vuoto"})
resp.status_code = 404
try:
with io.open("./DatasetProva/Json/" + timestampStr+'.json', 'w', encoding='utf8') as outfile:
# Scriviamo leimmagini sul disco nel path
str_ = json.dumps(payload,indent=4, separators=(',', ': '), ensure_ascii=False)
outfile.write(str_)
#i+=1
resp = jsonify({'message': "E' stato salvato il json"})
resp.status_code = 201
cv2.imwrite("./DatasetProva/Immagini/" + timestampStr + ".jpg", color_image)
pipeline.stop()
return resp
except Exception as ex:
print("Errore sulla scrittura sul disco ", ex)
#i-=1
return resp
if __name__ == "__main__":
app.run(debug=True, host ="192.168.1.191", port="8080")
I receive one package from the antenna every 200/300 milliseconds, is it possible that a new pipeline starts before the old one stops? And how could I solve the problem?

How to stream trades for all spot trading pairs on binance using websockets in python

I am trying to stream every single trade for all spot trading pairs on the Binance exchange in real time using web sockets. I have searched for a websocket endpoint to do so and have not found one.
I have tried making a call to the "exchange info" endpoint and getting all trading pairs. Then from there I filtered out the ones that had a trading status of halted and the pairs that didn't allow spot trading. Then I passed these trading pairs which were made lower cased and abbreviated with the proper "#trade" to show I wanted trade info. When I sent this request to the server Binance didn't respond. I have left my code below for you to reproduce my problem:
import ssl
import websocket
import _thread as thread
import re
import ast
import pandas as pd
import requests
import json
def on_message(ws, message):
print(message)
message = json.loads(message)
message = message.get('data')
try:
symbol = message.get("s")
timestamp = message.get("T")
price = message.get("p")
quantity = message.get("q")
is_buyer_maker = message.get("m")
if is_buyer_maker:
taker = "sell"
else:
taker = "buy"
data = {"symbol": symbol,
"timestamp": timestamp,
"price": price,
"quantity": quantity,
"taker": taker}
print(data)
except:
pass
def on_error(ws, error):
print(error)
def on_close(ws):
print("### Binance Closed ###")
def on_open(ws):
def run(*args):
print(logon_msg)
ws.send(logon_msg)
thread.start_new_thread(run, ())
if __name__ == "__main__":
content = requests.get("https://api.binance.com/api/v3/exchangeInfo").json()
content = content.get("symbols")
symbols = []
for thing in content:
if thing.get("status") == "TRADING" and thing.get("isSpotTradingAllowed") == True:
symbols.append(thing.get("symbol"))
symbols = [i.lower() + "#trade" for i in symbols]
logon_msg = {"method": "SUBSCRIBE", "params": symbols,"id": 1}
logon_msg = json.dumps(logon_msg)
websocket.enableTrace(True)
ws = websocket.WebSocketApp("wss://stream.binance.com:9443/stream?streams=trade",
on_message=on_message,
on_error=on_error,
on_close=on_close,
on_open=on_open)
ws.on_open = on_open
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

Pass a Queue to handle_read function async tcp server

I'm using a multiprocess to make 2 tasks. A process 1 is a async tcp server which receives commands and have to pass these commands to process 2 (is a while true loop).
How i'm using multiprocessing, the process don't share global variables, so i have to use a queue. But, a proccess 1 is a simple asynctcp server. I don't know how to pass the queue object to handle_read fuction.
Anyone have an idea? Thanks a lot!
The code i'm trying:
#!usr/bin/env python3
#import dos módulos necessarios
import time
import collections
from datetime import datetime
from datetime import timedelta
from threading import Timer
import os
import sys
from smbus import SMBus
from struct import pack, unpack
import threading
from multiprocessing import Process, Queue
import asyncore
import socket
bstatus = 0
lastdata = {}
#bytechecksum para confirmação
chksum = 15
#funções auxiliares
def millis():
dt = datetime.now()-start_time
ms = (dt.days*24*60*60 + dt.seconds)*1000+dt.microseconds / 1000.0
return ms
def getbit(data,index):
return(data & (1<<index)!=0)
def parseData(data):
mydata = {}
if data[8] == 27:
mydata['Temp1'] = data[0]
mydata['Temp2'] = data[1]
mydata['Temp3'] = data[2]
mydata['Temp4'] = data[3]
mydata['HotFlow'] = data[4]
mydata['ColdFlow'] = data[5]
mydata['PumpSpeed'] = data[6]
mydata['PumpStatus'] = getbit(data[7],0)
mydata['HeaterStatus'] = getbit(data[7],1)
mydata['ArduinoMode'] = getbit(data[7],2)
mydata['TimeStamp'] = timezone.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
#pegar o modo do arduino
arduino_mode = mydata['ArduinoMode']
parseStatus = True
else:
parseStatus = False
return parseStatus, mydata
#classes para implmmentar o servidor assincrono
class dataHandler(asyncore.dispatcher_with_send):
#this function doesn't working
def __init__(self,sock,queue):
self.queue = queue
self.sock = sock
def handle_read(self):
data = self.sock.recv(50)
'''interpretar os comandos:
operação: Ligar/Desligar Bomba, Ligar/Desligar Aquecedor, Alterar velocidade da bomba
Modo: trocar de modo automático para remoto
Armazenamento: ativar ou desativar o armazenamento de dados para o trend
'''
if(data == b'7'):
operation_mode = 1
queue.put(data)
print(data)
elif(data == b'8'):
operation_mode = 0
queue.put(data)
print(data)
try:
bytescommand = pack('=cb',data,chksum)
bus.write_block_data(arduinoAddress,ord(data),list(bytescommand))
except Exception as err:
print(str(err))
finally:
pass
#print(data)
class Server(asyncore.dispatcher):
def __init__(self,host,port,queue):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET,socket.SOCK_STREAM)
self.bind((host,port))
self.listen(1)
self.queue = queue
def handle_accept(self):
pair = self.accept()
if pair is None:
return
else:
sock,addr = pair
handler = dataHandler(sock,self.queue) #doesn't working
#classe para implementar a função principal
def tcpserver(queue):
server = Server('localhost',8080,queue)
asyncore.loop()
def mainloop(stime,ftime,queue):
prevmillis = stime
prevmillis2 = ftime
operation_mode = 1
while True:
try:
currentmillis2 = millis()
if(queue.empty):
pass
else:
print(queue.get())
if(currentmillis2 - prevmillis2 > readinterval):
#do some stuff
#programa principal
if __name__=='__main__':
prevmillis= millis() #contador para solicitação de dados para o arduino
prevmillis2 = prevmillis #contador para envio do banco
#create Queue
queue = Queue()
p1 = Process(target=tcpserver,args=(queue,))
p1.start()
p2 = Process(target=mainloop,args=(prevmillis,prevmillis2,queue,))
p2.start()
strstatus = 'Servidor rodando'
print(strstatus)
In mainloop you don't test the return value of queue.empty, you test the function object itself. That always evaluates True, so it looks like queue is always empty. Change to a function call:
def mainloop(stime,ftime,queue):
prevmillis = stime
prevmillis2 = ftime
operation_mode = 1
while True:
try:
currentmillis2 = millis()
if(queue.empty()): # Added ()
pass
else:
print(queue.get())
if(currentmillis2 - prevmillis2 > readinterval):
#do some stuff

Categories

Resources