이어 가기
- Scan
engines.scan - Scan - 스크리닝
engines.scan.screen - Scan - 비율
engines.scan.ratio - Scan - 밸류에이션
engines.scan.valuation - Quality + Value 횡단 스크리닝 (Novy-Marx GP/A 기반)
engines.recipe.qualityValueScreen - Graham deep value 안전마진 스크리닝 (PBR + 유동성 + 저레버리지)
engines.recipe.grahamDeepValue - Analysis - 이익품질
engines.analysis.earningsQuality
절차
실행 순서
- 1
고-점수 (8-9 점) 가치주 연 13.4% vs 저-점수 (0-1 점) 5.9%.
- 2
점수 0 → 1 단위 상승 시 평균 +1.5%p 초과수익.
- 3
가치주 (BM 상위 quintile) 안에서 작동, 성장주에서는 약함.
- 4
`stockCode`, `corpName`
- 5
`p1_roa` ~ `p7_dGm : int8` — 7 항목 통과 여부 (0 또는 1)
- 6
`fScore : int` — 0~7 합계
- 7
`pbr`, `per : float` — 시장 multiple
- 8
`grade : str` — valuation grade
- 9
**원전 9 → 7 변환** — 신주발행 항목과 ΔassetTurnover 제외. 한국 자본금 변동은 무상증자·주식배당 등 노이즈로 학술 신호 약함.
- 10
**freq="Y" 만 의존** — 분기 데이터로 ΔROA 등 더 민감한 신호도 가능하나 본 recipe 는 연간 표준.
- 11
**5 기간 일관성 미점검** — 단일 연도 변화만 봄. 5 년 일관성 (compounderCandidates) 또는 학술적 ΔROA 5 년 평균은 별도 확장.
- 12
**PBR 1.5 임계는 조정 가능** — 한국 chaebol discount 시장에서는 1.0 이하로 더 빡빡하게 가능.
학술 근거
Joseph Piotroski, “Value Investing: The Use of Historical Financial Statement Information to Separate Winners from Losers” (Journal of Accounting Research, 2000): 저-PBR (가치주) 유니버스 안에서 9 가지 fundamental 신호로 점수화. 1976-1996 미국 백테스트:
- 고-점수 (8-9 점) 가치주 연 13.4% vs 저-점수 (0-1 점) 5.9%.
- 점수 0 → 1 단위 상승 시 평균 +1.5%p 초과수익.
- 가치주 (BM 상위 quintile) 안에서 작동, 성장주에서는 약함.
원전 9 항목 중 dartlab ratio 13 종으로 가능한 7 항목만 사용 (lite). 신주발행 (자본금 변동) 과 ΔassetTurnover 는 한국 회계 특이성으로 노이즈 큼 → 제외. 미국 적용 시 둘 추가 가능.
7 항목 (각 1 점, 합계 0~7)
| 번호 | 항목 | dartlab 계산 |
|---|---|---|
| 1 | ROA > 0 | roa > 0 |
| 2 | CFO > 0 | operatingCfMargin > 0 |
| 3 | ΔROA > 0 | 당년 roa − 전년 roa > 0 |
| 4 | CFO > NI | operatingCfMargin > netMargin (accrual quality) |
| 5 | ΔdebtRatio < 0 | 당년 debtRatio − 전년 debtRatio < 0 |
| 6 | ΔcurrentRatio > 0 | 당년 currentRatio − 전년 currentRatio > 0 |
| 7 | ΔgrossMargin > 0 | 당년 grossMargin − 전년 grossMargin > 0 |
원전 9 점 → 7 점 변환 시 임계는 5 점 이상 (≈ 원전 7 점) 을 권장.
공개 호출 방식
import dartlab
import polars as pl
# 1) 7 ratio 모두 freq="Y" 로 fetch (당년 + 전년 컬럼 자동)
def fScore() -> pl.DataFrame:
ratios = ["roa", "operatingCfMargin", "netMargin", "debtRatio", "currentRatio", "grossMargin"]
frames = [dartlab.scanRatio(r, freq="Y").rename({"2025": f"{r}_25", "2024": f"{r}_24"}) for r in ratios]
df = frames[0]
for f in frames[1:]:
df = df.join(f, on="stockCode", how="inner")
return df.with_columns([
(pl.col("roa_25") > 0).cast(pl.Int8).alias("p1_roa"),
(pl.col("operatingCfMargin_25") > 0).cast(pl.Int8).alias("p2_cfo"),
(pl.col("roa_25") > pl.col("roa_24")).cast(pl.Int8).alias("p3_dRoa"),
(pl.col("operatingCfMargin_25") > pl.col("netMargin_25")).cast(pl.Int8).alias("p4_accrual"),
(pl.col("debtRatio_25") < pl.col("debtRatio_24")).cast(pl.Int8).alias("p5_dDebt"),
(pl.col("currentRatio_25") > pl.col("currentRatio_24")).cast(pl.Int8).alias("p6_dCurrent"),
(pl.col("grossMargin_25") > pl.col("grossMargin_24")).cast(pl.Int8).alias("p7_dGm"),
]).with_columns(
pl.sum_horizontal("p1_roa","p2_cfo","p3_dRoa","p4_accrual","p5_dDebt","p6_dCurrent","p7_dGm").alias("fScore")
)
# 2) 가치주 유니버스 (저PBR) 안에서 5 점 이상 추출
value = dartlab.scan("valuation")
result = (
fScore()
.join(value.select(["stockCode", "pbr", "per", "grade"]), on="stockCode")
.filter((pl.col("pbr") <= 1.5) & (pl.col("fScore") >= 5))
.sort("fScore", descending=True)
) 호출 동작
scanRatio(r, freq="Y")6 회 (roa·operatingCfMargin·netMargin·debtRatio·currentRatio·grossMargin) — 컬럼"2025","2024".- polars join 으로 한 wide 테이블.
- 7 항목 binary cast →
fScore합산. scan("valuation")결합 →pbr ≤ 1.5+fScore ≥ 5.fScore내림차순 정렬.
대표 반환 형태
result : pl.DataFrame — 컬럼:
stockCode,corpNamep1_roa~p7_dGm : int8— 7 항목 통과 여부 (0 또는 1)fScore : int— 0~7 합계pbr,per : float— 시장 multiplegrade : str— valuation grade
한계
- 원전 9 → 7 변환 — 신주발행 항목과 ΔassetTurnover 제외. 한국 자본금 변동은 무상증자·주식배당 등 노이즈로 학술 신호 약함.
- freq=“Y” 만 의존 — 분기 데이터로 ΔROA 등 더 민감한 신호도 가능하나 본 recipe 는 연간 표준.
- 5 기간 일관성 미점검 — 단일 연도 변화만 봄. 5 년 일관성 (compounderCandidates) 또는 학술적 ΔROA 5 년 평균은 별도 확장.
- PBR 1.5 임계는 조정 가능 — 한국 chaebol discount 시장에서는 1.0 이하로 더 빡빡하게 가능.
한국 / 미국 시장 차이
- 한국: 저-PBR 가치주 풀이 미국보다 큼 (KOSPI 평균 PBR ≈ 1.0). 본 lite 7 점 모델로 함정 회피 효과 강함. 단 chaebol 계열사 (지주회사·금융 자회사) 회계 특이성 주의.
- 미국: 원전 검증 시장. 신주발행 항목 추가로 9 점 만점 권장. PBR 1.5 → 2.0 까지 완화 가능 (S&P 500 평균 ≈ 4).
연계 절차
- 본 recipe 로 후보 발굴 →
tableRef에 fScore 분포 표. - fScore 6-7 점 종목에 대해
engines.recipe.qualityValueScreen의 GP/A 게이트 추가 통과 여부 확인. engines.recipe.distressFilter로 위험 종목 제외.engines.analysis.earningsQuality— CFO/NI 비율 시계열 정합성 점검.engines.story로 후보별 narrative 생성.
기본 검증
- 점수 분포 — 평균 3-4 점이 정상. 평균 6 점 이상 = 게이트 의심 (PBR 1.5 너무 느슨).
- 5 점 이상 후보 수 — 50~150 개가 정상 범위 (KOSPI 약 2400 종목 중 2~6%).
- ΔROA·ΔdebtRatio 등 변화 항목이 한쪽으로 쏠리면 시장 사이클 영향 — 매크로 환경 함께 해석.
- “F-Score = 7 = 매수” 단정 X — 점수카드는 후보 발굴 도구. 단일 회사 심층 검증 필수.
런타임
실행 환경별 호환성
| 환경 | 상태 | 비고 / 제한 |
|---|---|---|
| Local Python | supported | — |
| Server | supported | — |
| MCP | unknown | — |
| Web AI | unknown | — |
| Pyodide | limited |
|