initial commit

This commit is contained in:
2026-08-05 21:35:45 +05:30
commit dbac720ce0
30 changed files with 19832 additions and 0 deletions

144
src/components/Scanner.js Normal file
View File

@@ -0,0 +1,144 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
function Scanner({ onSelectStock, onSignal }) {
const [data, setData] = useState(null);
const [lastBest, setLastBest] = useState(null);
const loadData = async () => {
try {
const res = await axios.get("http://127.0.0.1:8000/scan");
const newData = res.data;
const best = newData.best_5 && newData.best_5.length > 0 ? newData.best_5[0] : null;
if (best && best.symbol !== lastBest) {
if (onSignal) onSignal(`New Best Trade: ${best.symbol}`);
setLastBest(best.symbol);
}
setData(newData);
} catch (err) {
console.error(err);
}
};
useEffect(() => {
loadData();
const interval = setInterval(loadData, 100000);
return () => clearInterval(interval);
}, []);
const openChart = (symbol) => {
window.open(`https://www.tradingview.com/chart/?symbol=NSE:${symbol}`, "_blank");
};
if (!data) return <div className="glass-card" style={{ textAlign: "center" }}>Loading Scanner Data...</div>;
return (
<div>
{/* Top 5 Trades */}
{(data.best_5 || []).length > 0 && (
<div className="glass-card animate-fade-in" style={{ marginBottom: "30px", borderLeft: "4px solid var(--accent-green)" }}>
<h2 className="text-green">🔥 Top 5 Momentum Picks</h2>
<div className="data-table-container">
<table className="data-table">
<thead>
<tr>
<th>Stock</th>
<th>Price</th>
<th>RSI</th>
<th>MACD</th>
<th>Signal</th>
<th>AI Score</th>
<th>Grade</th>
<th>Institutional</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{(data.best_5 || []).filter(s => s).map((s, i) => (
<tr key={i}>
<td style={{ fontWeight: 600 }}>{s?.symbol}</td>
<td>{s?.price}</td>
<td><span className={`badge ${s?.rsi > 60 ? 'badge-success' : 'badge-neutral'}`}>{s?.rsi}</span></td>
<td><span className={`badge ${s?.macd_hist > 0 ? 'badge-success' : 'badge-danger'}`}>{s?.macd_hist}</span></td>
<td>
<span className={`badge ${s?.signal?.includes("BUY") ? 'badge-success' : 'badge-danger'}`}>
{s?.signal}
</span>
</td>
<td>{s.ai_score} / 100</td>
<td>{s.grade}</td>
<td>{s.institutional ? <span className="text-orange">🔥 Yes</span> : <span className="text-muted">No</span>}</td>
<td>
<button className="action-btn" onClick={() => { openChart(s?.symbol); onSelectStock(s?.symbol); }}>
View Chart
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)}
{/* Sector Tables */}
{Object.entries(data.sectors || {}).map(([sector, info]) => {
const best = info.top_stock;
return (
<div key={sector} className="glass-card animate-fade-in" style={{ marginBottom: "20px" }}>
<h2 className="text-blue">{sector} ({info.stocks.length} Stocks)</h2>
{best && (
<p className="text-orange" style={{ marginBottom: "20px" }}>
<strong>Top Pick:</strong> {best.symbol} (Score: {best.score})
</p>
)}
<div className="data-table-container">
<table className="data-table">
<thead>
<tr>
<th>Stock</th>
<th>Price</th>
<th>MACD</th>
<th>Signal</th>
<th>Volume</th>
<th>Target</th>
<th>AI Score</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{(info.stocks || []).map((s, i) => (
<tr key={i}>
<td style={{ fontWeight: 500 }}>{s?.symbol}</td>
<td>{s?.price}</td>
<td><span className={`badge ${s?.macd_hist > 0 ? 'badge-success' : 'badge-danger'}`}>{s?.macd_hist}</span></td>
<td>
<span className={`badge ${s?.signal?.includes("BUY") ? 'badge-success' : 'badge-danger'}`}>
{s?.signal}
</span>
</td>
<td>{s?.volume?.toLocaleString()}</td>
<td className="text-green">{s?.target}</td>
<td>{s?.ai_score}</td>
<td>
<button className="action-btn" onClick={() => { openChart(s?.symbol); onSelectStock(s?.symbol); }}>
Chart
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
})}
</div>
);
}
export default Scanner;