-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: WebSocket Client for Live Data Streaming #2201
base: dev
Are you sure you want to change the base?
Conversation
38ee363
to
55b4a90
Compare
@ValueRaider any opinions on this websocket? Is it suitable for this package? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add a new function in WebSocket
for initialization.
Also I think its worth considering adding an async option
55b4a90
to
43a9a1c
Compare
@ValueRaider Should the websocket be an extra feature like nospam & require or part of base yfinance? |
9415f4d
to
5e14a92
Compare
This PR is completed |
Haven't used yet, was planning to try when markets open. My gut tells me this should be a separate package. It's basically a standalone app stapled onto yfinance, different way of interacting with Yahoo, nothing in common. Also out-of-the-box is broken:
Before you do any more work, check this out: https://github.com/yahoofinancelive/yliveticker #319 #290 |
5e14a92
to
0cc046e
Compare
I would disagree, although it is a different way to access data, it still is just accessing the data like the rest of yfinance. Especially as the main focus of yfinance is simpy to get the data on Yahoo! Finance |
What are your thoughts on https://github.com/yahoofinancelive/yliveticker? |
I always believed yfinance to be a wrapper over Yahoo! Finance API and that the goal was always to make it complete. This package yliveticker hasn't been maintained for four years and lacks async support. As the maintainer, if your gut differs we can close this PR.
I am unable to reproduce this. Can you try again, maybe it was a problem with versions. |
Fair point, looks like owner doesn't care yahoofinancelive/yliveticker#12
Clean fetch, same error. |
Can you help me with this please? |
I had protobuf version 3.20, updating to latest 5.29 fixed error. Can you set a minimum version? Try to get to at least MAJOR.MINOR. |
I think users need some working example codes for actual useful use cases, not printing to screen. Like live Dash visualisation or stream into database. I had a quick go at Dash but even AI struggles. |
I already have this in both requirements.txt and setup.py |
Here is what I was able to come up with. temp.mp4pip install dash dash-bootstrap-components pandas plotly yfinance flask import asyncio
import threading
from datetime import datetime
from dash import dcc, html
import dash_bootstrap_components as dbc
import dash
import pandas as pd
from dash.dependencies import Output, Input
from flask import Flask
import plotly.graph_objs as go
import yfinance as yf
server = Flask(__name__)
app = dash.Dash(__name__, server=server, external_stylesheets=[dbc.themes.CYBORG])
ws = yf.AsyncWebSocket(verbose=False)
STOCK = "MSFT"
df = pd.DataFrame(columns=["time", "price"])
def start_websocket():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
async def stream_data():
await ws.subscribe(STOCK)
def handle_message(msg):
global df
if "id" in msg and "price" in msg:
now = datetime.now().strftime("%H:%M:%S")
new_row = {"time": now, "price": float(msg["price"])}
if df.empty:
df = pd.DataFrame([new_row])
else:
if now in df["time"].values:
df.loc[df["time"] == now, "price"] = float(msg["price"])
else:
df = pd.concat([df, pd.DataFrame([new_row])]).tail(50)
await ws.listen(handle_message)
loop.run_until_complete(stream_data())
threading.Thread(target=start_websocket, daemon=True).start()
app.layout = html.Div([
html.H2("Live Stock Price Stream", style={"textAlign": "center", "color": "white"}),
dcc.Graph(id="live-graph"),
dcc.Interval(id="interval-update", interval=500, n_intervals=0),
])
@app.callback(Output("live-graph", "figure"), Input("interval-update", "n_intervals"))
def update_graph(n):
global df
figure = go.Figure()
if not df.empty:
figure.add_trace(go.Scatter(x=df["time"], y=df["price"], mode="lines+markers", name="Price"))
figure.update_layout(title=f"Live Price of {STOCK}", xaxis_title="Time", yaxis_title="Price")
return figure
if __name__ == "__main__":
app.run_server(debug=True) |
0cc046e
to
43db4cc
Compare
Hello, Any news on this feature? Will it be added to main branch? |
I just need time to try it thoroughly. You don't have to wait for a merge @dhruvan2006 How have you been using it in real world? |
c99fd99
to
257d6e0
Compare
257d6e0
to
51af634
Compare
I rebased onto
I use it on my website to track live prices |
Changes
WebSocket
class to stream live market data.pricing.proto
andpricing_pb2.py
) for data de serialization.requirements.txt
andsetup.py
to include new dependencies.Usage
Pick one from below to test feature: