From 19b098393a9446de70cd090be62d61b7de142828 Mon Sep 17 00:00:00 2001 From: Henry Winkel Date: Sat, 16 May 2026 12:39:27 +0200 Subject: [PATCH] feat: add most-actives API proxy route --- app/routes/api/stocks/most-actives.ts | 38 +++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 app/routes/api/stocks/most-actives.ts diff --git a/app/routes/api/stocks/most-actives.ts b/app/routes/api/stocks/most-actives.ts new file mode 100644 index 0000000..74d8b49 --- /dev/null +++ b/app/routes/api/stocks/most-actives.ts @@ -0,0 +1,38 @@ +import type { MostActiveStock } from "../../../types"; + +const ALPACA_API_KEY = process.env.ALPACA_API_KEY!; +const ALPACA_SECRET_KEY = process.env.ALPACA_SECRET_KEY!; +const ALPACA_DATA_URL = process.env.ALPACA_DATA_URL || "https://data.alpaca.markets"; + +export async function loader() { + try { + const response = await fetch(`${ALPACA_DATA_URL}/v1beta1/screener/stocks/most-actives`, { + headers: { + "APCA-API-KEY-ID": ALPACA_API_KEY, + "APCA-API-SECRET-KEY": ALPACA_SECRET_KEY, + }, + }); + + if (!response.ok) { + throw new Error(`Alpaca API error: ${response.status}`); + } + + const data = await response.json(); + const stocks: MostActiveStock[] = (data.most_actives || []).map((item: any) => ({ + symbol: item.symbol, + name: item.name || item.symbol, + price: parseFloat(item.price) || 0, + changePercent: parseFloat(item.change_percent) || 0, + volume: parseInt(item.volume) || 0, + })); + + return Response.json(stocks); + } catch (error) { + console.error("Most active stocks API error:", error); + const message = error instanceof Error ? error.message : "Unknown error"; + return Response.json( + { error: `Failed to fetch most active stocks: ${message}` }, + { status: 500 } + ); + } +}