munger-engine / scripts /munger-test.ts
dromero-nttd's picture
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();