fix: consolidate 3 fetchBars calls into 1 per stock and add 500ms delay between sequential loads to avoid rate limiting

This commit is contained in:
2026-05-16 22:14:21 +02:00
parent 5e865b9c26
commit f8a3b7840f
2 changed files with 36 additions and 50 deletions
+19 -9
View File
@@ -210,20 +210,29 @@ export default function Analyze() {
loadPortfolio();
}, []);
// Auto-load indicators for stocks that don't have them yet
// Auto-load indicators for stocks that don't have them yet (sequential with delay to avoid rate limits)
useEffect(() => {
const unloaded = stocks.filter((s) => !s.indicatorsLoading && s.indicators.rsi == null);
if (unloaded.length === 0) return;
unloaded.forEach(async (stock) => {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: true } : st));
const indicators = await loadIndicators(stock.ticker);
if (indicators) {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicators, indicatorsLoading: false } : st));
} else {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: false } : st));
let cancelled = false;
const loadSequential = async () => {
for (const stock of unloaded) {
if (cancelled) break;
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: true } : st));
const indicators = await loadIndicators(stock.ticker);
if (cancelled) break;
if (indicators) {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicators, indicatorsLoading: false } : st));
} else {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: false } : st));
}
// 500ms delay between each stock to avoid rate limiting
await new Promise((r) => setTimeout(r, 500));
}
});
};
loadSequential();
return () => { cancelled = true; };
}, [stocks]);
useEffect(() => {
@@ -411,6 +420,7 @@ export default function Analyze() {
} else {
setStocks((s) => s.map((st) => st.id === stock.id ? { ...st, indicatorsLoading: false } : st));
}
await new Promise((r) => setTimeout(r, 500));
}
};