Skip to main content
Glama

Korea Stock Analyzer MCP Server

by Mrbaeksang
lynch.ts7.25 kB
/** * 피터 린치 투자 분석 - 완전 개선판 */ import { BaseAnalyzer } from './base-analyzer.js'; import { LynchAnalysis, FinancialData } from '../types/index.js'; export class LynchAnalyzer extends BaseAnalyzer { constructor() { super('피터 린치', 'GARP (Growth at Reasonable Price)'); } async analyze(data: any): Promise<LynchAnalysis> { const { financialData, marketData, growthMetrics } = data; const currentFund = Array.isArray(financialData) ? financialData[0] : financialData; const financialHistory = Array.isArray(financialData) ? financialData : [financialData]; const currentPrice = marketData?.currentPrice || 0; // 1. EPS 성장률 계산 (3-5년 CAGR) const epsGrowthRate = this.calculateEPSGrowthRate(financialHistory, growthMetrics); // 2. 매출 성장률 계산 const salesGrowthRate = this.calculateSalesGrowthRate(financialHistory); // 3. 기본 PEG 비율 계산 const peg = this.calculatePEG(currentFund.per, epsGrowthRate); // 4. 배당 조정 PEG (린치의 개선 공식) const dividendAdjustedPEG = this.calculateDividendAdjustedPEG( currentFund.per, epsGrowthRate, currentFund.div ); // 5. 회사 분류 (6가지 카테고리) const companyType = this.classifyCompany(epsGrowthRate, currentFund); // 6. 적정 PER 산출 (린치 공식: PER = 성장률) const fairPer = this.determineFairPER(epsGrowthRate, companyType); // 7. 적정가 계산 const fairValue = Math.round(currentFund.eps * fairPer); // 8. 재고회전율 (소매업 중요 지표) const inventoryTurnover = this.calculateInventoryTurnover(data); // 9. 부채비율 체크 const debtToEquity = this.calculateDebtToEquity(currentFund); // 10. 린치 종합 점수 const lynchScore = this.calculateLynchScore({ peg, dividendAdjustedPEG, epsGrowthRate, salesGrowthRate, debtToEquity, inventoryTurnover, companyType }); // 11. 상승여력 const margin = this.calculateUpside(fairValue, currentPrice); return { fairValue, method: 'GARP 전략: PEG < 1.0 + 배당조정', margin, recommendation: this.getLynchRecommendation(peg, dividendAdjustedPEG, margin, lynchScore), category: companyType, growthRate: epsGrowthRate, pegRatio: peg, dividendAdjustedPEG, fairPer, salesGrowthRate, debtToEquity, inventoryTurnover, lynchScore }; } private calculateEPSGrowthRate(history: FinancialData[], growthMetrics?: any): number { // 기존 메트릭스가 있으면 사용 if (growthMetrics?.epsGrowth3yCagr) { return growthMetrics.epsGrowth3yCagr; } // 수동 계산 (3년 CAGR) if (history.length >= 3) { const current = history[0].eps; const threeYearsAgo = history[Math.min(2, history.length - 1)].eps; if (threeYearsAgo > 0 && current > 0) { const years = Math.min(3, history.length - 1); return ((Math.pow(current / threeYearsAgo, 1/years) - 1) * 100); } } return 10; // 기본값 10% } private calculateSalesGrowthRate(history: FinancialData[]): number { // 매출 성장률 추정 (EPS 성장률의 80%) const epsGrowth = this.calculateEPSGrowthRate(history); return epsGrowth * 0.8; } private calculatePEG(per: number, growthRate: number): number { if (growthRate <= 0) return 999; return Number((per / growthRate).toFixed(2)); } private calculateDividendAdjustedPEG(per: number, growthRate: number, dividendYield: number): number { // 린치의 배당 조정 PEG = PER / (성장률 + 배당수익률) const adjustedGrowth = growthRate + dividendYield; if (adjustedGrowth <= 0) return 999; return Number((per / adjustedGrowth).toFixed(2)); } private classifyCompany(growthRate: number, fund: FinancialData): string { // 린치의 6가지 분류 if (growthRate > 20) return 'Fast Grower (고성장주)'; if (growthRate > 10) return 'Stalwart (우량주)'; if (growthRate > 5) return 'Slow Grower (저성장주)'; if (fund.per < 10 && fund.pbr < 1) return 'Asset Play (자산주)'; if (growthRate < 0) return 'Turnaround (턴어라운드)'; return 'Cyclical (경기순환주)'; } private determineFairPER(growthRate: number, companyType: string): number { // 린치 원칙: 적정 PER = 성장률 let fairPer = Math.max(growthRate, 5); // 회사 유형별 조정 if (companyType.includes('Fast Grower')) { // 고성장주는 PER 25-40 허용 fairPer = Math.min(fairPer * 1.5, 40); } else if (companyType.includes('Stalwart')) { // 우량주는 PER 10-20 fairPer = Math.min(fairPer, 20); } else if (companyType.includes('Slow Grower')) { // 저성장주는 PER 8-12 fairPer = Math.min(fairPer * 0.8, 12); } else if (companyType.includes('Asset Play')) { // 자산주는 PBR 중심 fairPer = 10; } else if (companyType.includes('Turnaround')) { // 턴어라운드는 보수적 fairPer = 8; } else { // 경기순환주 fairPer = Math.min(fairPer, 15); } return fairPer; } private calculateInventoryTurnover(data: any): number { // 재고회전율 (소매업 중요) // 높을수록 좋음 return 5; // 기본값 } private calculateDebtToEquity(fund: FinancialData): number { // 부채비율 추정 if (fund.pbr > 2) return 1.0; // 높은 PBR = 높은 부채 추정 if (fund.pbr > 1) return 0.5; return 0.3; } private calculateLynchScore(metrics: any): number { let score = 0; // PEG 평가 (40점) if (metrics.peg <= 0.5) score += 40; else if (metrics.peg <= 1.0) score += 30; else if (metrics.peg <= 1.5) score += 20; else if (metrics.peg <= 2.0) score += 10; // 배당조정 PEG (20점) if (metrics.dividendAdjustedPEG <= 1.0) score += 20; else if (metrics.dividendAdjustedPEG <= 1.5) score += 10; // EPS 성장률 (15점) if (metrics.epsGrowthRate >= 20) score += 15; else if (metrics.epsGrowthRate >= 15) score += 10; else if (metrics.epsGrowthRate >= 10) score += 5; // 매출 성장률 (10점) if (metrics.salesGrowthRate >= 15) score += 10; else if (metrics.salesGrowthRate >= 10) score += 5; // 부채비율 (10점) if (metrics.debtToEquity < 0.3) score += 10; else if (metrics.debtToEquity < 0.5) score += 5; // 회사 유형 (5점) if (metrics.companyType.includes('Fast Grower') || metrics.companyType.includes('Stalwart')) { score += 5; } return score; } private getLynchRecommendation( peg: number, dividendPEG: number, margin: number, score: number ): 'Strong Buy' | 'Buy' | 'Hold' | 'Sell' | 'Strong Sell' { // 종합 판단 if (score >= 80 && peg <= 1.0 && margin > 30) return 'Strong Buy'; if (score >= 60 && peg <= 1.5 && margin > 15) return 'Buy'; if (score >= 40 || peg <= 2.0) return 'Hold'; if (score >= 20) return 'Sell'; return 'Strong Sell'; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mrbaeksang/korea-stock-analyzer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server