ai-hedge-fund 12) Warren Buffett

Tasker_Jang·2025년 3월 18일
0

워렌 버핏

세계 최고의 투자자 워렌 버핏의 투자 철학과 원칙을 코드로 구현한 이 에이전트는 어떻게 가치 투자의 정수를 실현하는지 살펴보겠습니다.

워렌 버핏의 투자 철학

워렌 버핏은 벤저민 그레이엄의 가치 투자 원칙을 기반으로 자신만의 투자 철학을 발전시켰습니다. 그의 핵심 원칙은 다음과 같습니다:

  1. 능력 범위(Circle of Competence): 이해할 수 있는 비즈니스에만 투자
  2. 안전마진(Margin of Safety): 본질적 가치보다 훨씬 낮은 가격에 구매
  3. 경제적 해자(Economic Moat): 지속적인 경쟁 우위를 가진 기업 선호
  4. 우수한 경영진: 보수적이고 주주 중심적인 경영진 선호
  5. 재무적 강점: 낮은 부채, 높은 자기자본수익률(ROE)
  6. 장기적 관점: 단순한 주식이 아닌 비즈니스에 투자

이러한 원칙들이 어떻게 코드로 구현되는지 살펴보겠습니다.

워렌 버핏 에이전트 구조

워렌 버핏 에이전트는 크게 세 가지 분석 영역을 통해 투자 결정을 내립니다:

  1. 펀더멘털 분석: 기업의 재무적 강점과 건전성 평가
  2. 일관성 분석: 수익의 일관성과 성장세 평가
  3. 본질적 가치 계산: 오너 이익(Owner Earnings)을 활용한 DCF 모델로 내재 가치 계산

각 영역에서 얻은 점수와 안전마진을 종합하여 최종 투자 신호(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,
        }

이 함수는 각 종목에 대한 분석을 수행하고, 버핏의 투자 원칙에 따라 점수를 계산한 후 최종 투자 신호를 생성합니다. 이제 각 분석 영역을 자세히 살펴보겠습니다.

1. 펀더멘털 분석

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}")

이 함수는 버핏이 강조하는 핵심 재무 지표를 분석합니다:

  1. ROE(Return on Equity): 버핏은 15% 이상의 높은 ROE를 선호합니다. 이는 기업이 주주 자본을 효율적으로 활용하는지를 보여줍니다.
  2. 부채비율(Debt to Equity): 버핏은 낮은 부채를 가진 기업을 선호합니다. 부채비율이 0.5 미만이면 보수적인 재무 구조로 평가합니다.
  3. 영업이익률(Operating Margin): 15% 이상의 높은 영업이익률은 기업이 강력한 가격 결정력과 효율성을 가지고 있음을 나타냅니다.
  4. 유동비율(Current Ratio): 1.5 이상의 유동비율은 양호한 단기 유동성을 의미합니다.

2. 일관성 분석

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")

버핏은 예측 가능하고 일관된 수익 성장을 보이는 기업을 선호합니다. 이 함수는:

  1. 과거 순이익(Net Income)의 일관된 성장 패턴을 확인합니다.
  2. 모든 기간에서 순이익이 증가했다면 높은 점수를 부여합니다.
  3. 전체 기간 동안의 성장률을 계산하여 세부 정보로 제공합니다.

3. 본질적 가치 계산

버핏은 기업의 본질적 가치를 계산하기 위해 "오너 이익(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

오너 이익의 계산식:

  • 순이익(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

이 함수는 오너 이익을 기반으로 기업의 내재 가치를 계산합니다:

  1. 오너 이익을 시작점으로 사용합니다.
  2. 보수적인 성장률(5%)과 할인율(9%)을 적용합니다.
  3. 10년간의 미래 현금 흐름을 예측하고 현재 가치로 할인합니다.
  4. 보수적인 출구 멀티플(12x)을 사용하여 영구 가치를 계산합니다.

이러한 보수적인 가정은 버핏의 "안전마진" 원칙과 일치합니다.

안전마진과 투자 신호

버핏의 핵심 원칙 중 하나는 "안전마진(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 기반 최종 분석

모든 정량적 분석이 완료된 후, 에이전트는 대규모 언어 모델(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이 버핏의 관점에서 투자 신호, 신뢰도, 그리고 투자 논리를 생성하도록 요청합니다.

이는 순수한 정량적 분석과 버핏의 정성적 투자 철학을 결합하는 방법입니다.

워렌 버핏 에이전트의 장단점

장점

  1. 종합적 분석: 재무적 강점, 수익 일관성, 내재 가치를 모두 고려합니다.
  2. 오너 이익 활용: 단순한 회계 수치를 넘어 기업의 실제 경제적 가치를 평가합니다.
  3. 안전마진 적용: 오판의 위험을 줄이기 위한 버핏의 핵심 원칙을 구현합니다.
  4. 보수적 가정: 성장률, 할인율, 출구 멀티플에 보수적인 가정을 적용합니다.
  5. LLM 통합: 정량적 분석과 버핏의 정성적 원칙을 결합합니다.

단점

  1. 재무 데이터 의존: 재무제표의 품질과 완전성에 크게 의존합니다.
  2. 질적 요소 제한: 경영진 품질, 경쟁 우위, 사업 모델의 이해도와 같은 질적 요소를 완벽하게 평가하기 어렵습니다.
  3. 미래 예측 한계: 모든 밸류에이션 모델과 마찬가지로 미래 성장과 현금 흐름 예측에 한계가 있습니다.
  4. 산업별 맞춤화 부족: 다양한 산업의 특성을 고려한 맞춤형 분석이 부족합니다.

워렌 버핏의 투자 지혜

워렌 버핏의 몇 가지 유명한 투자 명언은 이 에이전트의 설계 원칙을 잘 반영합니다:

"가격은 당신이 지불하는 것이고, 가치는 당신이 얻는 것이다."

이 에이전트는 시장 가격과 내재 가치를 명확히 구분하고, 둘 사이의 차이에서 투자 기회를 찾습니다.

"다른 사람들이 탐욕스러울 때 두려워하고, 다른 사람들이 두려워할 때 탐욕스러워라."

비록 현재 버전에서는 시장 심리를 직접 분석하지 않지만, 내재 가치에 집중함으로써 시장의 과도한 낙관주의나 비관주의에 영향받지 않습니다.

"당신이 이해하지 못하는 사업에 투자하지 마라."

LLM 통합을 통해 비즈니스 모델의 이해도를 평가하려고 시도하지만, 이 부분은 향후 더 개선될 수 있습니다.

마무리

워렌 버핏 에이전트는 세계 최고의 투자자의 원칙과 방법론을 코드로 구현한 강력한 도구입니다. 이 에이전트는 기업의 재무적 강점, 수익 일관성, 그리고 본질적 가치를 종합적으로 분석하여 버핏 스타일의 투자 신호를 생성합니다.

비록 정성적 요소의 평가에 한계가 있지만, 대규모 언어 모델(LLM)과의 통합을 통해 이러한 한계를 보완하고 있습니다. 데이터 중심의 분석과 버핏의 투자 철학을 결합함으로써, 이 에이전트는 장기적인 가치 투자를 지원하는 강력한 도구를 제공합니다.

워렌 버핏이 말했듯이, "시장은 단기적으로는 투표 기계이지만, 장기적으로는 저울입니다." 이 에이전트는 단기적인 시장 감성을 넘어 기업의 진정한 가치를 찾아내는 '저울'의 역할을 수행합니다.

profile
터널을 지나고 있을 뿐, 길은 여전히 열려 있다.

0개의 댓글

관련 채용 정보