Spaces:
Running
Running
feat: Establish initial Munger Engine framework with functional requirements, S&P 500 data fetching, and core stock analysis scripts.
f89d1ea
| import YahooFinance from 'yahoo-finance2'; | |
| import Alpaca from '@alpacahq/alpaca-trade-api'; | |
| import dotenv from 'dotenv'; | |
| import path from 'path'; | |
| // Load environment variables from .env file | |
| dotenv.config({ path: path.resolve(__dirname, '../.env') }); | |
| // Fix for yahoo-finance2 v3+ where default export is the class | |
| const yahooFinance = new (YahooFinance as any)(); | |
| // @ts-ignore | |
| const alpaca = new Alpaca({ | |
| keyId: process.env.ALPACA_KEY, | |
| secretKey: process.env.ALPACA_SECRET, | |
| paper: true, | |
| }); | |
| interface StockMetrics { | |
| symbol: string; | |
| price: number; | |
| wma200: number; | |
| roe: number; | |
| isQuality: boolean; | |
| } | |
| async function getMungerMetrics(symbol: string): Promise<StockMetrics> { | |
| // 1. Obtener Histórico para WMA | |
| const queryOptions = { period1: '2021-01-01', interval: '1wk' as const }; | |
| const history = await yahooFinance.chart(symbol, queryOptions); | |
| const closes = history.quotes.map((q: any) => q.close).filter((c: any): c is number => !!c); | |
| // Calcular 200-WMA (Simple Moving Average de 200 periodos semanales) | |
| const slice = closes.slice(-200); | |
| const wma200 = slice.reduce((a: number, b: number) => a + b, 0) / slice.length; | |
| // 2. Obtener Fundamentales | |
| const summary = await yahooFinance.quoteSummary(symbol, { modules: ['financialData', 'defaultKeyStatistics'] }); | |
| const roe = summary.financialData?.returnOnEquity || 0; | |
| const debtToEquity = summary.financialData?.debtToEquity || 0; | |
| return { | |
| symbol, | |
| price: closes[closes.length - 1], | |
| wma200, | |
| roe, | |
| isQuality: roe > 0.15 && debtToEquity < 50 | |
| }; | |
| } | |
| async function checkAlpacaConnection() { | |
| console.log("Checking Alpaca Connection..."); | |
| try { | |
| const account = await alpaca.getAccount(); | |
| console.log("Alpaca Connection Successful!"); | |
| console.log(`Account Status: ${account.status}`); | |
| console.log(`Buying Power: ${account.buying_power}`); | |
| return true; | |
| } catch (error: any) { | |
| console.error("Alpaca Connection Failed:", error.message); | |
| return false; | |
| } | |
| } | |
| async function main() { | |
| // Check Alpaca first | |
| const alpacaOk = await checkAlpacaConnection(); | |
| if (!alpacaOk) { | |
| console.log("Skipping Munger metrics due to credential failure (optional)."); | |
| // We can continue or stop. Let's continue for now to show other parts work. | |
| } | |
| console.log("\nStarting Munger Metrics Calculation..."); | |
| const symbol = 'AAPL'; | |
| try { | |
| // Suppress warnings? | |
| // yahooFinance.suppressNotices(['yahooSurvey']); | |
| const metrics = await getMungerMetrics(symbol); | |
| console.log(`Metrics for ${symbol}:`); | |
| console.log(JSON.stringify(metrics, null, 2)); | |
| } catch (error) { | |
| console.error("Error calculating metrics:", error); | |
| } | |
| } | |
| main(); | |