8429db504a
- New /stocks route with StockViewer component - New /api/indicators endpoint with SMA, EMA, RSI, MACD - New /api/alpaca/account endpoint - AlpacaAccountInfo component on home page - Indicator calculation utilities - Tests for utilities and components - Vite proxy config for /api
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
export function calculateSMA(prices: number[], period: number = 20): number {
|
|
if (prices.length < period) return 0;
|
|
const sum = prices.slice(0, period).reduce((a, b) => a + b, 0);
|
|
return sum / period;
|
|
}
|
|
|
|
export function calculateEMA(prices: number[], period: number = 20): number {
|
|
if (prices.length < period) return 0;
|
|
const multiplier = 2 / (period + 1);
|
|
let ema = prices[period - 1];
|
|
for (let i = period; i < prices.length; i++) {
|
|
ema = prices[i] * multiplier + ema * (1 - multiplier);
|
|
}
|
|
return ema;
|
|
}
|
|
|
|
export function calculateRSI(prices: number[], period: number = 14): number {
|
|
if (prices.length < period + 1) return 0;
|
|
let gains = 0;
|
|
let losses = 0;
|
|
for (let i = 1; i <= period; i++) {
|
|
const diff = prices[i] - prices[i - 1];
|
|
if (diff > 0) gains += diff;
|
|
else losses -= diff;
|
|
}
|
|
const avgGain = gains / period;
|
|
const avgLoss = losses / period;
|
|
if (avgLoss === 0) return 100;
|
|
const rs = avgGain / avgLoss;
|
|
return 100 - (100 / (1 + rs));
|
|
}
|
|
|
|
export function calculateMACD(
|
|
prices: number[],
|
|
fastPeriod: number = 12,
|
|
slowPeriod: number = 26,
|
|
signalPeriod: number = 9
|
|
): number {
|
|
if (prices.length < slowPeriod) return 0;
|
|
const emaFast = calculateEMA(prices, fastPeriod);
|
|
const emaSlow = calculateEMA(prices, slowPeriod);
|
|
const macdLine = emaFast - emaSlow;
|
|
const signal = calculateEMA([macdLine], signalPeriod);
|
|
return macdLine - signal;
|
|
} |