[퀀트] 팩터 투자 전략 (Factor Investing)

관리자 Lv.1
02-04 22:42 · 조회 3 · 추천 0

팩터 투자 전략 (Factor Investing)

학술적으로 검증된 요인(팩터)을 활용한 체계적 투자


1. 팩터 투자란?

정의

특정 특성(팩터)을 가진 주식들이 장기적으로 시장 대비 초과 수익을 낸다는 연구 결과를 기반으로 한 투자 전략

핵심 아이디어

수익률 = 시장 수익률 + 팩터 프리미엄 + 알파

2. 주요 팩터 (Fama-French 5 Factor 기반)

2.1 시장 팩터 (Market)

  • 개념: 주식 시장 전체의 리스크 프리미엄
  • 적용: 주식 vs 무위험자산

2.2 가치 팩터 (Value)

  • 개념: 저평가된 주식이 고평가된 주식보다 높은 수익
  • 지표: PER, PBR, PSR, EV/EBITDA
  • 전략: 낮은 밸류에이션 종목 매수
# 가치 점수 계산 예시
value_score = (
    rank(1/PER) * 0.3 +
    rank(1/PBR) * 0.3 +
    rank(1/PSR) * 0.2 +
    rank(1/EV_EBITDA) * 0.2
)

2.3 규모 팩터 (Size)

  • 개념: 소형주가 대형주보다 높은 수익 (소형주 프리미엄)
  • 지표: 시가총액
  • 전략: 시가총액 하위 종목 선호

2.4 수익성 팩터 (Profitability)

  • 개념: 수익성 높은 기업이 높은 수익
  • 지표: ROE, ROA, 영업이익률, GP/A
  • 전략: 고수익성 종목 매수
# 수익성 점수 계산 예시
quality_score = (
    rank(ROE) * 0.3 +
    rank(ROA) * 0.3 +
    rank(영업이익률) * 0.2 +
    rank(GP/A) * 0.2
)

2.5 투자 팩터 (Investment)

  • 개념: 자산 성장이 낮은 기업이 높은 수익
  • 지표: 총자산증가율, CAPEX/자산
  • 전략: 보수적 투자 기업 선호

3. 추가 팩터들

3.1 모멘텀 (Momentum)

  • 개념: 최근 상승한 주식이 계속 상승
  • 지표: 3개월, 6개월, 12개월 수익률
  • 전략: 상위 모멘텀 종목 매수
# 모멘텀 계산 (12-1 모멘텀)
momentum = (price_12m_ago - price_1m_ago) / price_12m_ago
# 최근 1개월 제외하는 이유: 단기 반전 효과

3.2 저변동성 (Low Volatility)

  • 개념: 변동성 낮은 주식이 위험 대비 높은 수익
  • 지표: 표준편차, 베타
  • 전략: 저변동성 종목 매수

3.3 배당 (Dividend)

  • 개념: 고배당 주식의 프리미엄
  • 지표: 배당수익률, 배당성향
  • 전략: 안정적 고배당 종목 매수

4. 한국형 팩터 전략

4.1 밸류 + 퀄리티 조합 (추천)

# 종목 선정 조건
conditions = {
    # 가치 조건
    "PER": lambda x: x < 10,
    "PBR": lambda x: x < 1.0,

    # 퀄리티 조건
    "ROE": lambda x: x > 10,
    "부채비율": lambda x: x < 100,

    # 안전 조건
    "영업이익": lambda x: x > 0,  # 3년 연속
}

4.2 소형 가치주 전략

# 필터링 기준
filters = {
    "시가총액": "하위 30%",
    "PBR": "하위 20%",
    "ROE": "상위 50%",
    "거래량": "일평균 1억 이상",  # 유동성 확보
}

4.3 모멘텀 + 가치 혼합

# 2단계 필터링
step1_value = rank_by_value(stocks)[:100]  # 가치 상위 100개
step2_momentum = rank_by_momentum(step1_value)[:20]  # 모멘텀 상위 20개

5. 팩터 점수 계산 방법

5.1 단일 팩터 순위

import pandas as pd

def single_factor_rank(df, factor, ascending=True):
    """단일 팩터 순위 계산"""
    return df[factor].rank(ascending=ascending, pct=True)

# 사용 예시
df['value_rank'] = single_factor_rank(df, 'PER', ascending=True)
df['quality_rank'] = single_factor_rank(df, 'ROE', ascending=False)

5.2 복합 팩터 점수

def composite_factor_score(df, factors_weights):
    """
    복합 팩터 점수 계산

    factors_weights = {
        ('PER', True): 0.25,    # (팩터명, 오름차순여부): 가중치
        ('PBR', True): 0.25,
        ('ROE', False): 0.25,
        ('모멘텀', False): 0.25,
    }
    """
    score = 0
    for (factor, ascending), weight in factors_weights.items():
        rank = df[factor].rank(ascending=ascending, pct=True)
        score += rank * weight
    return score

# 사용 예시
factors = {
    ('PER', True): 0.25,
    ('PBR', True): 0.25,
    ('ROE', False): 0.30,
    ('12M_Return', False): 0.20,
}
df['composite_score'] = composite_factor_score(df, factors)

6. 백테스팅 프레임워크

6.1 기본 구조

class FactorBacktest:
    def __init__(self, data, start_date, end_date):
        self.data = data
        self.start_date = start_date
        self.end_date = end_date
        self.portfolio = []
        self.returns = []

    def select_stocks(self, date, n_stocks=20):
        """팩터 기반 종목 선정"""
        monthly_data = self.data[self.data['date'] == date]
        scores = self.calculate_factor_scores(monthly_data)
        top_stocks = scores.nlargest(n_stocks, 'score')
        return top_stocks['ticker'].tolist()

    def calculate_factor_scores(self, data):
        """팩터 점수 계산"""
        # 구현
        pass

    def rebalance(self, date):
        """리밸런싱"""
        self.portfolio = self.select_stocks(date)

    def run(self, rebalance_freq='M'):
        """백테스트 실행"""
        # 매월/매분기 리밸런싱
        pass

6.2 성과 측정

def calculate_metrics(returns):
    """성과 지표 계산"""
    import numpy as np

    # 연환산 수익률
    cagr = (1 + returns).prod() ** (252 / len(returns)) - 1

    # 변동성
    volatility = returns.std() * np.sqrt(252)

    # 샤프 비율 (무위험 수익률 3% 가정)
    sharpe = (cagr - 0.03) / volatility

    # 최대 낙폭
    cumulative = (1 + returns).cumprod()
    rolling_max = cumulative.cummax()
    drawdown = (cumulative - rolling_max) / rolling_max
    mdd = drawdown.min()

    return {
        'CAGR': f'{cagr:.2%}',
        'Volatility': f'{volatility:.2%}',
        'Sharpe': f'{sharpe:.2f}',
        'MDD': f'{mdd:.2%}',
    }

7. 실전 적용 가이드

7.1 포트폴리오 구성

추천 구성:
├── 종목 수: 15-30개 (분산 효과)
├── 리밸런싱: 월간 또는 분기별
├── 비중: 동일 비중 or 팩터 점수 비례
└── 섹터 제한: 특정 섹터 30% 이하

7.2 리스크 관리

risk_rules = {
    # 개별 종목 제한
    "max_single_weight": 0.10,  # 개별 종목 최대 10%

    # 섹터 제한
    "max_sector_weight": 0.30,  # 섹터 최대 30%

    # 손절
    "stop_loss": -0.20,  # 개별 종목 -20% 손절

    # 현금 비중
    "min_cash": 0.05,  # 최소 현금 5%
}

7.3 거래 비용 고려

transaction_costs = {
    "commission": 0.00015,  # 매매 수수료 0.015%
    "tax": 0.0023,         # 증권거래세 0.23%
    "slippage": 0.001,     # 슬리피지 0.1%
}

# 왕복 거래 비용
round_trip_cost = (
    transaction_costs["commission"] * 2 +
    transaction_costs["tax"] +
    transaction_costs["slippage"] * 2
)
# 약 0.35% per trade

8. 주의사항

⚠️ 팩터 투자의 한계

  1. 팩터 사이클: 팩터도 시기에 따라 성과 차이

    • 가치주: 2010년대 부진, 2020년대 반등
    • 모멘텀: 급락장에서 큰 손실
  2. 과밀화 (Crowding): 많은 사람이 같은 전략 → 효과 감소

  3. 데이터 스누핑: 과거 데이터에서만 유효한 팩터

  4. 실행 현실: 백테스트 ≠ 실제 거래

✅ 체크리스트

  • [ ] 팩터의 경제적 논리가 있는가?
  • [ ] 여러 시장/기간에서 검증되었는가?
  • [ ] 거래 비용 후에도 유효한가?
  • [ ] 과최적화 되지 않았는가?
  • [ ] 리스크 관리 규칙이 있는가?

9. 참고 자료

논문

  1. Fama & French (1993) - 3 Factor Model
  2. Carhart (1997) - 4 Factor Model (Momentum 추가)
  3. Fama & French (2015) - 5 Factor Model

도서

  1. "Factor Investing and Asset Allocation" - Ang
  2. "Your Complete Guide to Factor-Based Investing" - Berkin & Swedroe

#팩터투자 #가치투자 #모멘텀 #퀄리티 #퀀트전략

💬 0 로그인 후 댓글 작성
첫 댓글을 남겨보세요!