Skip to content

Commit 33f9466

Browse files
Merge pull request #8 from CSA-AI/stats-page-(not-predicted)
live updating accurate stock data with colors! (use statslive.html not stats.html)
2 parents a149b4e + a61645a commit 33f9466

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed

pages/statslive.html

+246
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
---
2+
layout: project
3+
---
4+
5+
<head>
6+
<!-- ApexCharting -->
7+
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
8+
</head>
9+
10+
<style>
11+
#stockInfo {
12+
font-size: 24px;
13+
margin-bottom: 10px;
14+
}
15+
16+
#stockInfo h2 {
17+
font-size: 32px;
18+
margin-bottom: 5px;
19+
}
20+
21+
#stockPrice span {
22+
font-size: 24px;
23+
font-weight: bold;
24+
}
25+
26+
#stockVolume {
27+
font-weight: bold;
28+
}
29+
</style>
30+
31+
<div class="hero 50vh">
32+
33+
</div>
34+
35+
<div class="grid grid-cols-2 gap-4">
36+
<div class="card shadow-xl">
37+
<div class="card-body">
38+
<input id="symbol" type="text" placeholder="ex. AAPL" class="input input-bordered w-full max-w-xs mb-4" />
39+
<button onclick="getStockData()" class="btn">Get Monthly Data</button>
40+
<div id="stockPrice"></div>
41+
<div id="stockChart"></div>
42+
<div id="stockVolume"></div>
43+
<div id="lastRefreshed"></div>
44+
</div>
45+
</div>
46+
47+
<div class="card shadow-xl flex justify-center items-center">
48+
<div class="card-body text-lg">
49+
<div id="stockInfo"></div>
50+
</div>
51+
</div>
52+
</div>
53+
54+
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
55+
<script>
56+
57+
// WebSocket URL
58+
const socket = new WebSocket('wss://ws.finnhub.io?token=cogebo9r01qtg2rmbf9gcogebo9r01qtg2rmbfa0');
59+
60+
let prevPrice = null;
61+
62+
// Connection opened -> Subscribe
63+
socket.addEventListener('open', function (event) {
64+
console.log('WebSocket connection opened');
65+
});
66+
67+
// Listen for messages
68+
socket.addEventListener('message', function (event) {
69+
const data = JSON.parse(event.data);
70+
if (data.data) {
71+
const { s: symbol, p: price, v: volume } = data.data[0]; // Extract symbol, price, and volume
72+
updateStockData(symbol, price, volume);
73+
}
74+
});
75+
76+
// Function to update stock data based on WebSocket message
77+
function updateStockData(symbol, price, volume) {
78+
// Update stock price above graph
79+
document.getElementById("stockPrice").innerHTML = `
80+
<h2>Last Price: <span id="priceValue" class="text-3xl font-bold">${price}</span></h2>
81+
`;
82+
83+
// Update stock volume below graph
84+
document.getElementById("stockVolume").innerHTML = `
85+
<h2>Volume: <span class="font-bold">${volume}</span></h2>
86+
`;
87+
88+
// Compare with previous price and update color
89+
const priceValue = document.getElementById("priceValue");
90+
if (prevPrice !== null && price !== prevPrice) {
91+
priceValue.style.color = price > prevPrice ? 'green' : 'red';
92+
}
93+
94+
// Update previous price
95+
prevPrice = price;
96+
}
97+
98+
// Function to subscribe to a symbol
99+
function subscribe(symbol) {
100+
socket.send(JSON.stringify({'type': 'subscribe', 'symbol': symbol}));
101+
}
102+
103+
// Function to unsubscribe from a symbol
104+
function unsubscribe(symbol) {
105+
socket.send(JSON.stringify({'type': 'unsubscribe', 'symbol': symbol}));
106+
}
107+
108+
// Function to get monthly stock data
109+
async function getStockData() {
110+
const symbol = document.getElementById("symbol").value;
111+
112+
// Fetch real-time quote data from Finnhub API
113+
const apiKey = 'cogebo9r01qtg2rmbf9gcogebo9r01qtg2rmbfa0';
114+
const apiUrl = `https://finnhub.io/api/v1/quote?symbol=${symbol}&token=${apiKey}`;
115+
116+
try {
117+
const response = await axios.get(apiUrl);
118+
const data = response.data;
119+
120+
// Display stock info
121+
const changeColor = data.d > 0 ? 'green' : 'red';
122+
document.getElementById("stockInfo").innerHTML = `
123+
<h2><b>Stock Information</b></h2>
124+
<ul>
125+
<li><b>Symbol:</b> ${symbol}</li>
126+
<li><b>Last Price:</b> ${data.c}</li>
127+
<li style="color: ${changeColor};"><b>Change:</b> ${data.d} (${data.dp}%)</li>
128+
<li><b>High:</b> ${data.h}</li>
129+
<li><b>Low:</b> ${data.l}</li>
130+
<li><b>Open:</b> ${data.o}</li>
131+
<li><b>Previous Close:</b> ${data.pc}</li>
132+
</ul>
133+
`;
134+
} catch (error) {
135+
console.error(error);
136+
}
137+
138+
// Subscribe to symbol for real-time updates
139+
subscribe(symbol);
140+
141+
// Fetch monthly stock data from Alpha Vantage API and render chart
142+
fetchMonthlyStockData(symbol);
143+
}
144+
145+
// Function to fetch monthly stock data from Alpha Vantage API and render chart
146+
async function fetchMonthlyStockData(symbol) {
147+
const rapidApiKey = 'a96f7bb54emshee5a698b2344228p12bd6cjsnbb7e0177bdb6';
148+
const rapidApiHost = 'alpha-vantage.p.rapidapi.com';
149+
const url = `https://${rapidApiHost}/query?function=TIME_SERIES_MONTHLY&symbol=${symbol}&datatype=json&output_size=compact`;
150+
151+
const requestOptions = {
152+
method: 'GET',
153+
headers: {
154+
'X-RapidAPI-Key': rapidApiKey,
155+
'X-RapidAPI-Host': rapidApiHost
156+
}
157+
};
158+
159+
try {
160+
const response = await fetch(url, requestOptions);
161+
const data = await response.json();
162+
163+
// Process stock data for chart
164+
let seriesData = Object.keys(data['Monthly Time Series']).map(key => ({
165+
x: new Date(key),
166+
y: parseFloat(data['Monthly Time Series'][key]['4. close'])
167+
}));
168+
169+
// Render chart using ApexCharts
170+
renderStockChart(seriesData);
171+
} catch (error) {
172+
console.error(error);
173+
}
174+
}
175+
176+
// Function to render stock chart using ApexCharts
177+
function renderStockChart(seriesData) {
178+
var chartOptions = {
179+
series: [{
180+
name: 'Monthly Closed Stock Market Data',
181+
data: seriesData
182+
}],
183+
chart: {
184+
type: 'area',
185+
stacked: false,
186+
height: 350,
187+
zoom: {
188+
type: 'x',
189+
enabled: true,
190+
autoScaleYaxis: true
191+
},
192+
toolbar: {
193+
autoSelected: 'zoom'
194+
}
195+
},
196+
dataLabels: {
197+
enabled: false
198+
},
199+
markers: {
200+
size: 0,
201+
},
202+
title: {
203+
text: 'Stock Closed Price',
204+
align: 'left'
205+
},
206+
fill: {
207+
type: 'gradient',
208+
gradient: {
209+
shadeIntensity: 1,
210+
inverseColors: false,
211+
opacityFrom: 0.5,
212+
opacityTo: 0,
213+
stops: [0, 90, 100]
214+
},
215+
},
216+
yaxis: {
217+
labels: {
218+
formatter: function (val) {
219+
return (val).toFixed(2);
220+
},
221+
},
222+
title: {
223+
text: 'Price'
224+
},
225+
},
226+
xaxis: {
227+
type: 'datetime',
228+
},
229+
tooltip: {
230+
shared: false,
231+
x: {
232+
format: 'dd MMM yyyy'
233+
},
234+
y: {
235+
formatter: function (val) {
236+
return (val).toFixed(2);
237+
}
238+
}
239+
}
240+
};
241+
242+
var chart = new ApexCharts(document.querySelector("#stockChart"), chartOptions);
243+
chart.render();
244+
}
245+
</script>
246+

0 commit comments

Comments
 (0)