소스 필드명은 Sharadar SF1/SEP/SF2/SF3 기준.
schema.py 의 정규화 레이어를 거치므로 다른 벤더로 바꿔도 팩터 정의는 불변.
이 문서는 설계 스펙이다. 착수 시점의 계획 135개를 적었고, 실제 레지스트리는 실험 과정에서 늘어 158개다 (§7 참조). 현재 목록의 진실은 코드이며
opt-factor factors [--category quality]로 확인한다.
| 기호 | 의미 |
|---|---|
mcap |
시가총액 (marketcap, 일별 = close × sharesbas × sharefactor) |
⟨x⟩ₜₜₘ |
직전 4개 분기 합 (플로우) |
⟨x⟩ₐᵥg |
기초·기말 평균 (스톡, ROE/ROA 분모용) |
AC |
발생액 = netinc − ncfo |
IC |
투하자본 (invcap) |
IT |
무형자산 (intangibles) |
| [auto] | DSL 트랜스폼으로 자동 생성 (손으로 작성 안 함) |
| [?] | 정의 추정 — 00-overview.md §10 참조 |
주의: 밸류 팩터는 저PER 이 좋으므로 랭킹 시 역수(earnings yield 형태)를 쓴다.
PER을 그대로 오름차순 정렬하면 적자기업(음수 PER)이 최상위로 올라온다. 엔진은mcap/netinc가 아니라netinc/mcap을 내부 스코어로 쓰고, 표시용으로만 역수를 보여준다. (invert=True메타)
| # | 팩터 | 계산식 | 소스 필드 | 비고 |
|---|---|---|---|---|
| 1 | 시가총액 | mcap |
marketcap |
사이즈 팩터 |
| 2 | PER | mcap / netinc |
netinc |
분기 연율화 |
| 3 | PER (TTM) | mcap / ⟨netinc⟩ₜₜₘ |
[auto] | |
| 4 | PBR | mcap / equity |
equity |
스톡 |
| 5 | PSR | mcap / revenue |
revenue |
|
| 6 | PSR (TTM) | mcap / ⟨revenue⟩ₜₜₘ |
[auto] | |
| 7 | POR | mcap / opinc |
opinc |
|
| 8 | POR (TTM) | mcap / ⟨opinc⟩ₜₜₘ |
[auto] | |
| 9 | PCR | mcap / ncfo |
ncfo |
영업활동현금흐름 |
| 10 | PCR (TTM) | mcap / ⟨ncfo⟩ₜₜₘ |
[auto] | |
| 11 | PFCR | mcap / fcf |
fcf = ncfo − capex |
|
| 12 | PRR | mcap / rnd |
rnd |
R&D 0 인 기업 다수 → NaN 처리 [?] |
| 13 | PGPR | mcap / gp |
gp |
|
| 14 | PGPR (TTM) | mcap / ⟨gp⟩ₜₜₘ |
[auto] | |
| 15 | PEG | PER_TTM / EPS성장률 |
epsdil |
아래 참조 |
| 16 | PAR | mcap / assets |
assets |
[?] |
| 17 | PACR | mcap / AC |
netinc,ncfo |
[?] 부호 불안정 |
| 18 | PITR | mcap / intangibles |
intangibles |
[?] 무형자산 0 다수 |
| 19 | NCAV | (assetsc − liabilities) / mcap |
assetsc,liabilities |
그레이엄 순유동자산 |
| 20 | 배당수익률 | dps_ttm / close |
dps, divyield |
|
| 21 | 주주수익률 | (배당 + 자사주매입) / mcap |
−ncfdiv, −ncfcommon |
아래 참조 |
| 22 | 종가 (수정 전) | closeunadj |
SEP closeunadj |
팩터 아님, 필터용 |
PEG_FWD = PER_TTM / (선행 EPS 성장률 × 100) # FMP 추정치 필요
PEG_TTM = PER_TTM / (3년 EPS CAGR × 100) # Sharadar 단독 가능
성장률 ≤ 0 이면 NaN. 두 팩터를 별도 등록하고 소스 없으면 자동 skip.
shareholder_yield = (dividends_paid + net_buyback) / mcap
dividends_paid = −ncfdiv # 현금유출이라 음수로 기록됨
net_buyback = −ncfcommon # 자사주매입 순액 (증자 시 음수 → 희석)
자사주매입을 무시하면 미장에서 치명적이다. 미국 대형주는 배당보다 자사주매입 규모가 크다 (AAPL 등). 한국식 “배당수익률”만 보면 미장 주주환원을 절반도 못 본다.
EV = mcap + 총차입금 + 소수주주지분 − 현금성자산
Sharadar 는 ev 를 직접 제공하나, 정합성을 위해 자체 계산도 지원한다.
EV = marketcap + debtusd − cashnequsd
| # | 팩터 | 계산식 | 소스 필드 |
|---|---|---|---|
| 23 | EV | ev |
ev |
| 24 | EV/Net | ev / netinc |
netinc |
| 25 | EV/Sales | ev / revenue |
revenue |
| 26 | EV/EBITDA | ev / ebitda |
evebitda (사전계산 존재) |
| 27 | EV/EBIT | ev / ebit |
evebit (사전계산 존재) |
| 28 | EV/GP | ev / gp |
gp |
| 29 | EV/R&D | ev / rnd |
rnd |
| 30 | EV/CF | ev / ncfo |
ncfo |
| 31 | EV/AC | ev / AC |
netinc,ncfo |
EV 배수는 자본구조 중립이라 금융주 제외 유니버스에서 PER/PBR 보다 안정적이다. 다만 순현금 기업은 EV 가 음수가 되어 배수 부호가 뒤집힌다 →
EV ≤ 0은 NaN 처리.
| # | 팩터 | 계산식 | 소스 필드 |
|---|---|---|---|
| 32 | ROE | netinc / ⟨equity⟩ₐᵥg |
roe |
| 33 | ROA | netinc / ⟨assets⟩ₐᵥg |
roa |
| 34 | ROE (TTM) | ⟨netinc⟩ₜₜₘ / ⟨equity⟩ₐᵥg |
[auto] |
| 35 | ROA (TTM) | ⟨netinc⟩ₜₜₘ / ⟨assets⟩ₐᵥg |
[auto] |
| 36 | ROIC | NOPAT / ⟨invcap⟩ₐᵥg |
roic |
| 37 | GPIC | gp / ⟨invcap⟩ₐᵥg |
gp,invcapavg [?] |
| 38 | RIC | rnd / ⟨invcap⟩ₐᵥg |
rnd,invcapavg [?] |
| 39 | GP/E | gp / equity |
gp,equity |
| 40 | GP/A | gp / assets |
Novy-Marx 총이익성 |
| 41 | GP/A (TTM) | ⟨gp⟩ₜₜₘ / assets |
[auto] |
| 42 | GP/IT | gp / intangibles |
[?] |
| 43 | OP/IT | opinc / intangibles |
[?] |
| 44 | ROIT | netinc / intangibles |
[?] |
| 45 | ROCE | ebit / (assets − liabilitiesc) |
ebit,assets,liabilitiesc |
GP/A 는 미장에서 가장 잘 검증된 퀄리티 팩터다 (Novy-Marx 2013). 순이익은 회계 재량이 많이 개입되지만 매출총이익은 상대적으로 조작이 어렵다.
| # | 팩터 | 계산식 |
|---|---|---|
| 46 | 무형자산 Turnover | revenue / intangibles |
| 47 | Asset Turnover | revenue / ⟨assets⟩ₐᵥg (assetturnover) |
| 48 | Asset Turnover (TTM) | ⟨revenue⟩ₜₜₘ / ⟨assets⟩ₐᵥg [auto] |
| 49 | GPM | gp / revenue (grossmargin) |
| 50 | OPM | opinc / revenue |
| 51 | NPM | netinc / revenue (netmargin) |
| # | 팩터 | 계산식 |
|---|---|---|
| 52 | R&D / 매출액 | rnd / revenue |
| 53 | R&D / 매출총이익 | rnd / gp |
| 54 | R&D / 영업이익 | rnd / opinc |
| 55 | R&D / 순이익 | rnd / netinc |
R&D 는 섹터 편향이 극심하다 (제약·반도체·소프트웨어에 집중). 반드시
.neutralize(by="sector")를 적용해야 의미 있는 신호가 된다. 미적용 시 이 팩터는 사실상 “기술주 섹터 베팅”이다.
| # | 팩터 | 계산식 | 방향 |
|---|---|---|---|
| 56 | AC/A | (netinc − ncfo) / ⟨assets⟩ₐᵥg |
낮을수록 좋음 |
| 57 | AC/E | (netinc − ncfo) / ⟨equity⟩ₐᵥg |
낮을수록 좋음 |
Sloan(1996) 발생액 이상현상. 이익의 질을 나타내며 부호 방향이 반대다. 레지스트리에
direction=-1로 명시한다.
| # | 팩터 | 계산식 | 소스 |
|---|---|---|---|
| 58 | 변동성 (52주) | std(일간수익률, 252) × √252 |
SEP |
| 59 | 변동성 (60일) | std(일간수익률, 60) × √252 |
SEP |
| 60 | 영업이익 / 차입금 | opinc / debt |
opinc,debt |
| 61 | 차입금비율 | debt / equity (de) |
|
| 62 | 유보율 | retearn / equity |
retearn |
| 63 | 이익변동성 | std(⟨netinc/assets⟩, 최근 20분기) |
낮을수록 좋음 |
| 64 | 유동비율 | assetsc / liabilitiesc (currentratio) |
| # | 팩터 | 구성 |
|---|---|---|
| 65 | F-score | Piotroski 9개 이진 항목 합 (0~9) |
| 66 | Altman Z-score | 5개 항목 가중합, 부실 예측 |
Piotroski F-score (9점) | 범주 | 조건 | |—|—| | 수익성 | ① ROA > 0 ② CFO > 0 ③ ROA 전년 대비 증가 ④ CFO > 순이익 (발생액 품질) | | 레버리지/유동성 | ⑤ 장기차입금비율 감소 ⑥ 유동비율 증가 ⑦ 신주발행 없음 | | 운영효율 | ⑧ 매출총이익률 증가 ⑨ 자산회전율 증가 |
Altman Z-score (제조업)
Z = 1.2·(운전자본/자산) + 1.4·(유보이익/자산) + 3.3·(EBIT/자산)
+ 0.6·(시가총액/총부채) + 1.0·(매출/자산)
| 구간 | 해석 | |—|—| | Z > 2.99 | 안전 | | 1.81 ~ 2.99 | 회색지대 | | Z < 1.81 | 부실 위험 → “관리종목 제외” 필터의 미장 대체재 |
비제조업·금융업은 Z’’ 변형 공식을 써야 한다. 금융주 제외 유니버스가 기본인 이유.
| # | 팩터 | 계산식 | 비고 |
|---|---|---|---|
| 67 | 1개월 모멘텀 | close/close₍₋₂₁₎ − 1 |
단기 반전 → direction=-1 권장 |
| 68 | 3개월 모멘텀 | close/close₍₋₆₃₎ − 1 |
[auto] |
| 69 | 6개월 모멘텀 | close/close₍₋₁₂₆₎ − 1 |
[auto] |
| 70 | 12개월 모멘텀 | close/close₍₋₂₅₂₎ − 1 |
[auto] |
정통 모멘텀은 12-1 (직전 1개월 제외) 을 쓴다. 최근 1개월은 반전 효과가 지배해서 그냥 12개월을 쓰면 두 효과가 상쇄된다.
MOM_12_1을 추가로 등록한다.
| # | 팩터 | 계산식 |
|---|---|---|
| 71 | 종가 (수정 전) | closeunadj — 필터용 |
| # | 팩터 | 계산식 |
|---|---|---|
| 72 | 샤프비율 | mean(r) / std(r) × √252 (252일) |
| 73–76 | 샤프비율 모멘텀 (20/60/120/200일) | 해당 기간 샤프의 변화 [auto] |
| 77 | Sortino 비율 | mean(r) / std(r⁻) × √252 |
| 78–81 | Sortino 모멘텀 (20/60/120/200일) | [auto] |
| # | 팩터 | 계산식 |
|---|---|---|
| 82 | RSI (9일) | Wilder RSI |
| 83 | RSI (14일) | [auto] |
| 84 | RSI (25일) | [auto] |
| # | 팩터 | 계산식 |
|---|---|---|
| 85 | 베타 | cov(rᵢ, r_mkt)/var(r_mkt), 252일 |
| 86 | 베타 (60일) | 60일 [auto] |
| 87 | 절대값 베타 | \|beta\| — 시장중립 종목 선별 |
| 88 | 절대값 베타 (60일) | [auto] |
벤치마크는 SPY 가 아니라 CRSP 시총가중 전체시장 이 이론적으로 맞다. 실무상 SPY 로 근사하되 설정 가능하게 둔다 (
benchmark: SPY).
| # | 원본 | 프록시 팩터 | 계산식 | 소스 |
|---|---|---|---|---|
| 89 | 개인순매수강도 | INSIDER_NET_BUY |
90일 내부자 순매수 주식수 / 유통주식수 | SF2 |
| 90 | 기관순매수강도 | INST_HOLD_CHG |
13F 보유주식수 QoQ 변화율 | SF3 |
| 91 | 외인순매수강도 | SHORT_INT_CHG |
공매도 잔고 변화율 (역방향) | FMP/FINRA |
| 92 | 기관/외인순매수강도 | INST_SHORT_COMBO |
z(INST_HOLD_CHG) − z(SHORT_INT_CHG) |
합성 |
| 93 | 거래대금 회전율 | TURNOVER |
⟨volume × close⟩₂₀ / mcap |
SEP |
13F 지연 처리 필수: 분기말 + 45일 공시.
datekey기준으로만 반영한다. 이 지연 때문에 KRX 일별 수급 대비 신호가 훨씬 약하며, 별도 카테고리로 분리해 다른 팩터와 동일 가중으로 섞이지 않게 한다.
base.qoq() / base.yoy() 로 자동 생성. 손으로 작성하는 코드 0줄.
| base 필드 | QoQ | YoY |
|---|---|---|
netinc (순이익) |
✔ | ✔ |
opinc (영업이익) |
✔ | ✔ |
gp (매출총이익) |
✔ | ✔ |
revenue (매출액) |
✔ | ✔ |
assets (자산) |
✔ | ✔ |
equity (자본) |
✔ | ✔ |
GP_A (GP/A) |
✔ | ✔ |
OPINC_DEBT (영업이익/차입금) |
✔ | ✔ |
ncfo (현금흐름) |
✔ | ✔ |
rnd (연구개발비) |
✔ | ✔ |
cashneq (현금성자산) |
✔ | ✔ |
debt (차입금) |
✔ | ✔ |
divyield (배당수익률) |
✔ | ✔ |
= 13 × 2 = 26개
growth = (x_t - x_{t-4}) / abs(x_{t-4}) # abs() 필수
abs() 없이 계산하면 적자→적자축소 기업의 성장률 부호가 뒤집힌다.
(예: -100 → -50 은 개선인데, (-50 - -100)/-100 = -0.5 로 악화로 잡힘)
추가로 x_{t-4} 가 0 근처면 성장률이 폭발한다 →
분모 절대값이 매출액의 0.1% 미만이면 NaN 처리하는 가드를 둔다.
(a/b/c) = 단기 이평 a개월, 장기 이평 b개월, 관찰 c일 로 해석한다. [?]
| # | 팩터 | 계산식 |
|---|---|---|
| 94 | MA 모멘텀 가속 (3/3/10) | Δ₁₀[ MA₃(close)/MA₃(close)₍₋ₙ₎ ] |
| 95 | MA 모멘텀 가속 (3/12/5) | Δ₅[ MA₃(close)/MA₁₂(close) ] |
| 96 | MA 모멘텀 가속 (10/1/5) | Δ₅[ MA₁₀(close)/MA₁(close) ] |
파라미터 해석이 불확실합니다.
(단기/장기/관찰)로 가정했으며, 실제 정의를 알려주시면 즉시 수정합니다. 구현은 파라미터화해두어ma_accel(short, long, lookback)한 함수로 어떤 조합이든 생성 가능합니다.
base.yoy().accel() = 성장률의 차분 = 2차 미분.
| base | YoY 가속 | QoQ 가속 |
|---|---|---|
netinc (순이익) |
✔ | ✔ |
revenue (매출액) |
✔ | ✔ |
gp (매출총이익) |
✔ | ✔ |
opinc (영업이익) |
✔ | ✔ |
ncfo (영업활동현금흐름) |
✔ | ✔ |
AC (발생액) |
✔ | ✔ |
= 6 × 2 = 12개
가속 팩터는 노이즈가 매우 크다 (2차 차분 = 노이즈 2번 증폭). 단독 사용보다 성장 팩터와의 결합, 또는
.winsor(0.01)후 사용을 권장한다. IC 검증 단계에서 대부분 탈락할 가능성이 높으며, 그걸 확인하는 게 검증 레이어의 역할이다.
| 카테고리 | 개수 | 손으로 작성 | 자동 파생 |
|---|---|---|---|
| 가치 (Price) | 22 | 12 | 10 |
| 가치 (EV) | 9 | 9 | 0 |
| 퀄리티 | 36 | 32 | 4 |
| 가격 | 27 | 15 | 12 |
| 성장 | 26 | 0 | 26 |
| 가속 | 15 | 3 | 12 |
| 합계 | 135 | 71 | 64 |
64개(47%)가 DSL 트랜스폼으로 자동 생성된다.
이 문서는 설계 스펙이며, 위 표는 착수 시점의 계획이다. 이후 실험 과정에서 팩터가 추가돼 레지스트리는 158개다. 차이는 이렇게 생겼다:
| 파일 | 내용 |
|---|---|
library/experimental.py |
직접 조립한 신규 팩터 10종 |
library/oap.py |
Chen & Zimmermann 오픈소스 자산가격 라이브러리 복제 12종 |
library/flow_proxy.py |
13F·내부자 수급 프록시 5종 (§5 는 00-overview.md) |
추가된 22종은 전부 walk-forward 에서 탈락했다 — 문헌에서 t=8.71 이던 팩터가
우리 유니버스에서 −0.70 이 나온 사례를 포함한다 (07-experiment-log.md §3.2).
레지스트리에 있다는 것과 쓸모가 있다는 것은 다르다.
카테고리별 실제 개수는 opt-factor factors 로 확인한다 — 이 표를 손으로
갱신하지 않는 이유는 어긋나기 때문이다.
각 팩터는 아래 메타를 갖는다 — 검증·최적화 단계에서 사용:
@dataclass(frozen=True)
class FactorSpec:
name: str
category: Literal["value_price","value_ev","quality","price",
"growth","acceleration","flow_proxy"]
expr: Expr # 표현식 트리
direction: int = +1 # +1 = 클수록 좋음, -1 = 작을수록 좋음
invert: bool = False # 배수형(PER 등) → 역수로 스코어링
neutralize: tuple = () # ("sector",) / ("sector","size")
winsor: float = 0.01
min_periods: int = 4 # 필요한 최소 분기 수
requires: frozenset = ... # 필요 소스 테이블 {"SF1","SEP","SF3"}
notes: str = ""
requires 로 구독하지 않은 데이터셋에 의존하는 팩터는 자동 비활성화된다.
(예: FMP 미구독 시 PEG_FWD, SHORT_INT_CHG 자동 skip — 에러 대신 경고)