세계 최고의 투자자 워렌 버핏의 투자 철학과 원칙을 코드로 구현한 이 에이전트는 어떻게 가치 투자의 정수를 실현하는지 살펴보겠습니다.
워렌 버핏은 벤저민 그레이엄의 가치 투자 원칙을 기반으로 자신만의 투자 철학을 발전시켰습니다. 그의 핵심 원칙은 다음과 같습니다:
이러한 원칙들이 어떻게 코드로 구현되는지 살펴보겠습니다.
워렌 버핏 에이전트는 크게 세 가지 분석 영역을 통해 투자 결정을 내립니다:
각 영역에서 얻은 점수와 안전마진을 종합하여 최종 투자 신호(bullish/bearish/neutral)를 생성합니다.
warren_buffett_agent
def warren_buffett_agent(state: AgentState):
"""Analyzes stocks using Buffett's principles and LLM reasoning."""
# 데이터 초기화
data = state["data"]
end_date = data["end_date"]
tickers = data["tickers"]
analysis_data = {}
buffett_analysis = {}
for ticker in tickers:
# 재무 데이터 수집
metrics = get_financial_metrics(ticker, end_date, period="ttm", limit=5)
financial_line_items = search_line_items(
ticker,
["capital_expenditure", "depreciation_and_amortization", "net_income",
"outstanding_shares", "total_assets", "total_liabilities"],
end_date, period="ttm", limit=5,
)
market_cap = get_market_cap(ticker, end_date)
# 세 가지 핵심 분석 수행
fundamental_analysis = analyze_fundamentals(metrics)
consistency_analysis = analyze_consistency(financial_line_items)
intrinsic_value_analysis = calculate_intrinsic_value(financial_line_items)
# 총점 계산
total_score = fundamental_analysis["score"] + consistency_analysis["score"]
max_possible_score = 10
# 안전마진 분석 추가
margin_of_safety = None
intrinsic_value = intrinsic_value_analysis["intrinsic_value"]
if intrinsic_value and market_cap:
margin_of_safety = (intrinsic_value - market_cap) / market_cap
# 30% 이상의 안전마진이 있다면 점수 추가
if margin_of_safety > 0.3:
total_score += 2
max_possible_score += 2
# 투자 신호 생성
if total_score >= 0.7 * max_possible_score:
signal = "bullish"
elif total_score <= 0.3 * max_possible_score:
signal = "bearish"
else:
signal = "neutral"
# 분석 결과 저장
analysis_data[ticker] = {
"signal": signal,
"score": total_score,
"max_score": max_possible_score,
"fundamental_analysis": fundamental_analysis,
"consistency_analysis": consistency_analysis,
"intrinsic_value_analysis": intrinsic_value_analysis,
"market_cap": market_cap,
"margin_of_safety": margin_of_safety,
}
# LLM을 통한 워렌 버핏 스타일 출력 생성
buffett_output = generate_buffett_output(
ticker=ticker,
analysis_data=analysis_data,
model_name=state["metadata"]["model_name"],
model_provider=state["metadata"]["model_provider"],
)
# 분석 결과 저장
buffett_analysis[ticker] = {
"signal": buffett_output.signal,
"confidence": buffett_output.confidence,
"reasoning": buffett_output.reasoning,
}
이 함수는 각 종목에 대한 분석을 수행하고, 버핏의 투자 원칙에 따라 점수를 계산한 후 최종 투자 신호를 생성합니다. 이제 각 분석 영역을 자세히 살펴보겠습니다.
def analyze_fundamentals(metrics: list) -> dict[str, any]:
"""Analyze company fundamentals based on Buffett's criteria."""
if not metrics:
return {"score": 0, "details": "Insufficient fundamental data"}
# 최신 지표 가져오기
latest_metrics = metrics[0]
score = 0
reasoning = []
# 자기자본수익률(ROE) 확인
if latest_metrics.return_on_equity and latest_metrics.return_on_equity > 0.15: # 15% ROE 기준
score += 2
reasoning.append(f"Strong ROE of {latest_metrics.return_on_equity:.1%}")
elif latest_metrics.return_on_equity:
reasoning.append(f"Weak ROE of {latest_metrics.return_on_equity:.1%}")
# 부채비율 확인
if latest_metrics.debt_to_equity and latest_metrics.debt_to_equity < 0.5:
score += 2
reasoning.append("Conservative debt levels")
elif latest_metrics.debt_to_equity:
reasoning.append(f"High debt to equity ratio of {latest_metrics.debt_to_equity:.1f}")
# 영업이익률 확인
if latest_metrics.operating_margin and latest_metrics.operating_margin > 0.15:
score += 2
reasoning.append("Strong operating margins")
elif latest_metrics.operating_margin:
reasoning.append(f"Weak operating margin of {latest_metrics.operating_margin:.1%}")
# 유동비율 확인
if latest_metrics.current_ratio and latest_metrics.current_ratio > 1.5:
score += 1
reasoning.append("Good liquidity position")
elif latest_metrics.current_ratio:
reasoning.append(f"Weak liquidity with current ratio of {latest_metrics.current_ratio:.1f}")
이 함수는 버핏이 강조하는 핵심 재무 지표를 분석합니다:
def analyze_consistency(financial_line_items: list) -> dict[str, any]:
"""Analyze earnings consistency and growth."""
if len(financial_line_items) < 4: # 추세 분석을 위해 최소 4개 기간 필요
return {"score": 0, "details": "Insufficient historical data"}
score = 0
reasoning = []
# 이익 성장 추세 확인
earnings_values = [item.net_income for item in financial_line_items if item.net_income]
if len(earnings_values) >= 4:
earnings_growth = all(earnings_values[i] > earnings_values[i + 1] for i in range(len(earnings_values) - 1))
if earnings_growth:
score += 3
reasoning.append("Consistent earnings growth over past periods")
else:
reasoning.append("Inconsistent earnings growth pattern")
# 성장률 계산
if len(earnings_values) >= 2:
growth_rate = (earnings_values[0] - earnings_values[-1]) / abs(earnings_values[-1])
reasoning.append(f"Total earnings growth of {growth_rate:.1%} over past {len(earnings_values)} periods")
버핏은 예측 가능하고 일관된 수익 성장을 보이는 기업을 선호합니다. 이 함수는:
버핏은 기업의 본질적 가치를 계산하기 위해 "오너 이익(Owner Earnings)"이라는 개념을 사용합니다. 이는 기업이 실제로 창출하는 경제적 가치를 더 정확하게 반영합니다.
def calculate_owner_earnings(financial_line_items: list) -> dict[str, any]:
"""Calculate owner earnings (Buffett's preferred measure of true earnings power).
Owner Earnings = Net Income + Depreciation - Maintenance CapEx"""
if not financial_line_items or len(financial_line_items) < 1:
return {"owner_earnings": None, "details": ["Insufficient data for owner earnings calculation"]}
latest = financial_line_items[0]
# 필요한 구성 요소 가져오기
net_income = latest.net_income
depreciation = latest.depreciation_and_amortization
capex = latest.capital_expenditure
if not all([net_income, depreciation, capex]):
return {"owner_earnings": None, "details": ["Missing components for owner earnings calculation"]}
# 유지보수 자본지출 추정 (일반적으로 총 자본지출의 70-80%)
maintenance_capex = capex * 0.75
owner_earnings = net_income + depreciation - maintenance_capex
오너 이익의 계산식:
이 공식은 기업이 실제로 창출하는 현금 흐름의 경제적 현실을 더 잘 반영합니다.
def calculate_intrinsic_value(financial_line_items: list) -> dict[str, any]:
"""Calculate intrinsic value using DCF with owner earnings."""
# 오너 이익 계산
earnings_data = calculate_owner_earnings(financial_line_items)
if not earnings_data["owner_earnings"]:
return {"value": None, "details": earnings_data["details"]}
owner_earnings = earnings_data["owner_earnings"]
# 현재 시장 데이터 가져오기
latest_financial_line_items = financial_line_items[0]
shares_outstanding = latest_financial_line_items.outstanding_shares
# 버핏의 DCF 가정
growth_rate = 0.05 # 보수적인 5% 성장률
discount_rate = 0.09 # 일반적인 9% 할인율
terminal_multiple = 12 # 보수적인 출구 멀티플
projection_years = 10
# 미래 가치 계산
future_value = 0
for year in range(1, projection_years + 1):
future_earnings = owner_earnings * (1 + growth_rate) ** year
present_value = future_earnings / (1 + discount_rate) ** year
future_value += present_value
# 영구 가치 추가
terminal_value = (owner_earnings * (1 + growth_rate) ** projection_years * terminal_multiple) /
(1 + discount_rate) ** projection_years
intrinsic_value = future_value + terminal_value
이 함수는 오너 이익을 기반으로 기업의 내재 가치를 계산합니다:
이러한 보수적인 가정은 버핏의 "안전마진" 원칙과 일치합니다.
버핏의 핵심 원칙 중 하나는 "안전마진(Margin of Safety)"입니다. 에이전트는 다음과 같이 안전마진을 계산합니다:
# 안전마진 분석 추가
margin_of_safety = None
intrinsic_value = intrinsic_value_analysis["intrinsic_value"]
if intrinsic_value and market_cap:
margin_of_safety = (intrinsic_value - market_cap) / market_cap
# 30% 이상의 안전마진이 있다면 점수 추가
if margin_of_safety > 0.3:
total_score += 2
max_possible_score += 2
이 코드는:
1. 계산된 내재 가치와 현재 시장 가치(시가총액)를 비교합니다.
2. 내재 가치가 시장 가치보다 30% 이상 높으면 추가 점수를 부여합니다.
3. 이는 버핏이 강조하는 "안전마진" 원칙을 직접적으로 구현한 것입니다.
모든 정량적 분석이 완료된 후, 에이전트는 대규모 언어 모델(LLM)을 활용하여 워렌 버핏 스타일의 최종 투자 분석을 생성합니다:
def generate_buffett_output(
ticker: str,
analysis_data: dict[str, any],
model_name: str,
model_provider: str,
) -> WarrenBuffettSignal:
"""Get investment decision from LLM with Buffett's principles"""
template = ChatPromptTemplate.from_messages(
[
(
"system",
"""You are a Warren Buffett AI agent. Decide on investment signals based on Warren Buffett's principles:
Circle of Competence: Only invest in businesses you understand
Margin of Safety: Buy well below intrinsic value
Economic Moat: Prefer companies with lasting advantages
Quality Management: Look for conservative, shareholder-oriented teams
Financial Strength: Low debt, strong returns on equity
Long-term Perspective: Invest in businesses, not just stocks
Rules:
- Buy only if margin of safety > 30%
- Focus on owner earnings and intrinsic value
- Prefer consistent earnings growth
- Avoid high debt or poor management
- Hold good businesses long term
- Sell when fundamentals deteriorate or the valuation is too high
""",
),
(
"human",
"""Based on the following data, create the investment signal as Warren Buffett would.
Analysis Data for {ticker}:
{analysis_data}
Return the trading signal in the following JSON format:
{{
"signal": "bullish/bearish/neutral",
"confidence": float (0-100),
"reasoning": "string"
}}
""",
),
]
)
이 함수는:
1. 버핏의 투자 원칙을 시스템 프롬프트로 제공합니다.
2. 모든 정량적 분석 데이터를 LLM에 전달합니다.
3. LLM이 버핏의 관점에서 투자 신호, 신뢰도, 그리고 투자 논리를 생성하도록 요청합니다.
이는 순수한 정량적 분석과 버핏의 정성적 투자 철학을 결합하는 방법입니다.
워렌 버핏의 몇 가지 유명한 투자 명언은 이 에이전트의 설계 원칙을 잘 반영합니다:
"가격은 당신이 지불하는 것이고, 가치는 당신이 얻는 것이다."
이 에이전트는 시장 가격과 내재 가치를 명확히 구분하고, 둘 사이의 차이에서 투자 기회를 찾습니다.
"다른 사람들이 탐욕스러울 때 두려워하고, 다른 사람들이 두려워할 때 탐욕스러워라."
비록 현재 버전에서는 시장 심리를 직접 분석하지 않지만, 내재 가치에 집중함으로써 시장의 과도한 낙관주의나 비관주의에 영향받지 않습니다.
"당신이 이해하지 못하는 사업에 투자하지 마라."
LLM 통합을 통해 비즈니스 모델의 이해도를 평가하려고 시도하지만, 이 부분은 향후 더 개선될 수 있습니다.
워렌 버핏 에이전트는 세계 최고의 투자자의 원칙과 방법론을 코드로 구현한 강력한 도구입니다. 이 에이전트는 기업의 재무적 강점, 수익 일관성, 그리고 본질적 가치를 종합적으로 분석하여 버핏 스타일의 투자 신호를 생성합니다.
비록 정성적 요소의 평가에 한계가 있지만, 대규모 언어 모델(LLM)과의 통합을 통해 이러한 한계를 보완하고 있습니다. 데이터 중심의 분석과 버핏의 투자 철학을 결합함으로써, 이 에이전트는 장기적인 가치 투자를 지원하는 강력한 도구를 제공합니다.
워렌 버핏이 말했듯이, "시장은 단기적으로는 투표 기계이지만, 장기적으로는 저울입니다." 이 에이전트는 단기적인 시장 감성을 넘어 기업의 진정한 가치를 찾아내는 '저울'의 역할을 수행합니다.