이 스킬
외국인 보유율 vs 배당성향 상관
한국 시장에서 외국인 보유율 변화와 배당성향 변화의 시차 상관을 본다. 외국인이 *배당 정책에 영향* 한 종목 (높은 상관) vs *영향 없는* 종목 (낮은 상관) 분리. 단일 회사 시계열 5~10 년. gather ↔ analysis 격리 메우는 조합. 트리거 — '외국인 배당', 'foreign ownership dividend', '주주환원 외인 영향'.
연계 절차
이 절차의 단계
- 1 recipes.fundamental.dividend.capitalReturn
recipes.fundamental.dividend.capitalReturn환원 thesis 진입.
- 2 recipes.fundamental.dividend.stressTest
recipes.fundamental.dividend.stressTest외인 이탈 시나리오 별 cut 임계.
절차
실행 순서
- 1
Company.gather('ownership') 연도별 외국인 보유율 (foreignPct)
- 2
Company.analysis('capitalAllocation') 연도별 (dividends_paid + net_income) → payoutNi
- 3
year-key 로 join, 표본 ≥ 5 년
- 4
Pearson r0 (동일 연도) + Pearson r1 (외인 1y 선행)
- 5
표본 < 5 년이면 상관 강도 결론 X — 노이즈 영향 큼.
- 6
우선주 분리 발행 시 보통주 보유율만 사용해야 함 (보통주 배당 매칭).
- 7
외국인 보유율 측정 시점 (연말 vs 연평균) 일관성 필요.
- 8
*외인* 단일 카테고리 — 헤지펀드 / 장기 패시브 분리 X.
- 9
r1 ≥ 0.5 → `recipes.fundamental.dividend.capitalReturn` 으로 환원 thesis 진입.
- 10
r0 + r1 둘 다 ≥ 0.5 → `recipes.sentiment.foreignBuyMomentum` 으로 외인 가속도 cross-check.
- 11
둘 다 < 0.5 → `recipes.fundamental.dividend.payoutFcfCoverage` 로 fcf 충당으로 다른 driver 점검.
- 12
표본 < 5 년이면 상관 결론 X, *coverage 한계* 로만.
예시
이런 질문이 들어오면 이 skill 을 쓴다
- 005930 외국인 vs 배당 10년 상관
- 외인 매수 → 1년 뒤 배당 인상 종목
출력
기대 결과
- 연도별 외국인 보유율 + 배당성향 표
- Pearson r (동일 연도) + lag-1 r (외인이 1 년 선행)
- 상관 임계 (|r| ≥ 0.5) 통과 여부
공개 호출 방식
import dartlab
import polars as pl
target = "005930"
c = dartlab.Company(target)
def rows(value, limit=80):
if hasattr(value, "head") and hasattr(value, "to_dicts"):
return value.head(limit).to_dicts()
if isinstance(value, list):
return value[:limit]
return []
own_rows = rows(c.gather("ownership"), limit=40)
try:
cap_rows = c.analysis("capitalAllocation").to_dicts()
except Exception:
cap_rows = []
# year-key 로 join
by_year = {}
for o in own_rows:
y = str(o.get("year") or o.get("asOfYear") or "")[:4]
if not y: continue
by_year.setdefault(y, {})["foreignPct"] = float(o.get("foreignPct") or o.get("foreign_ratio") or 0)
for cap in cap_rows:
y = str(cap.get("year") or cap.get("period") or "")[:4]
if not y: continue
div = abs(float(cap.get("dividends_paid") or cap.get("dividendsPaid") or 0))
ni = float(cap.get("net_income") or cap.get("netIncome") or 0)
by_year.setdefault(y, {})["payoutNi"] = (div / ni) if ni else None
merged = [{"year": y, **v} for y, v in sorted(by_year.items()) if "foreignPct" in v and "payoutNi" in v and v.get("payoutNi") is not None]
table = pl.DataFrame(merged) if merged else pl.DataFrame(
schema={"year": pl.Utf8, "foreignPct": pl.Float64, "payoutNi": pl.Float64}
)
def pearson(a, b):
if len(a) < 3 or len(a) != len(b):
return None
import statistics as st
ma, mb = st.mean(a), st.mean(b)
num = sum((x-ma)*(y-mb) for x, y in zip(a, b))
da = sum((x-ma)**2 for x in a) ** 0.5
db = sum((y-mb)**2 for y in b) ** 0.5
return num / (da*db) if da*db else None
a = table["foreignPct"].to_list()
b = table["payoutNi"].to_list()
r0 = pearson(a, b)
r1 = pearson(a[:-1], b[1:]) if len(a) >= 4 else None
emit_result(
table=table,
values={"pearson": r0, "pearsonLag1": r1, "years": table.height},
date=str(table["year"].max()) if table.height else None,
sources=["dartlab://gather/ownership", "dartlab://analysis/capitalAllocation"],
) 호출 동작
1. 결론 도출
Pearson r0 + r1 임계 단정. 예: “10y 표본 (2016-2025): foreignPct 49% → 54% / payoutNi 0.28 → 0.36 추세. Pearson r0 (동기) = +0.62 / r1 (외인 1y 선행) = +0.71 → 둘 다 |r| ≥ 0.5 통과 — 외인이 1년 선행 가설 지지 (상관 = 인과 아님 명시 필수).”
2. 핵심 근거 수집
- Company.gather(‘ownership’) 연도별 외국인 보유율 (foreignPct)
- Company.analysis(‘capitalAllocation’) 연도별 (dividends_paid + net_income) → payoutNi
- year-key 로 join, 표본 ≥ 5 년
- Pearson r0 (동일 연도) + Pearson r1 (외인 1y 선행)
3. 메커니즘 분석
2 시계열 → year-key join
foreignPct[t]
payoutNi[t] = dividends_paid[t] / net_income[t]
↓
Pearson 상관 2 종:
r0 = corr(foreignPct[t], payoutNi[t]) — 동기 상관
r1 = corr(foreignPct[t-1], payoutNi[t]) — 외인 1y 선행 lag
↓
임계 판정:
|r0| ≥ 0.5 + |r1| ≥ 0.5 → 동기 + 선행 모두 — 외인 영향 강
|r0| < 0.5 + |r1| ≥ 0.5 → 외인 선행 우세 — 외인이 배당 정책 trigger 후보
|r0| ≥ 0.5 + |r1| < 0.5 → 동기만 — 외인이 결정 *이후* 매수 (배당이 외인 attract)
둘 다 < 0.5 → 외인 영향 약 (다른 요인 우세) 상관 ≠ 인과 — 외인이 배당 결정에 영향? 또는 배당 인상이 외인 attract? r1 (선행 lag) 가 r0 보다 강하면 외인 선행 가설 지지.
4. 반례·한계
- 표본 < 5 년이면 상관 강도 결론 X — 노이즈 영향 큼.
- 우선주 분리 발행 시 보통주 보유율만 사용해야 함 (보통주 배당 매칭).
- 외국인 보유율 측정 시점 (연말 vs 연평균) 일관성 필요.
- 외인 단일 카테고리 — 헤지펀드 / 장기 패시브 분리 X.
5. 후속 모니터링
- r1 ≥ 0.5 →
recipes.fundamental.dividend.capitalReturn으로 환원 thesis 진입. - r0 + r1 둘 다 ≥ 0.5 →
recipes.sentiment.foreignBuyMomentum으로 외인 가속도 cross-check. - 둘 다 < 0.5 →
recipes.fundamental.dividend.payoutFcfCoverage로 fcf 충당으로 다른 driver 점검.
대표 반환 형태
| column | 의미 |
|---|---|
year | 결산 연도 |
foreignPct | 외국인 보유율 (%) |
payoutNi | 배당 / NI |
연계 절차
- recipes.fundamental.dividend.capitalReturn - 환원 thesis 진입.
- recipes.fundamental.dividend.stressTest - 외인 이탈 시나리오 별 cut 임계.
기본 검증
- 표본 < 5 년이면 상관 결론 X, coverage 한계 로만.
- 우선주 분리 발행 시 보통주 보유율만 사용한다 — 본 recipe 의 임계는 보통주 기준.
- 상관 = 인과 아님 — 답변 본문에 항상 명시.
런타임
실행 환경별 호환성
| 환경 | 상태 | 비고 / 제한 |
|---|---|---|
| Local Python | supported | · |
| Server | supported | · |
| MCP | supported | · |
| Web AI | limited | · |
| Pyodide | limited | · |
실패 회피
흔한 실패 · 절대 금지
- 5 년 미만 표본으로 상관 강도 단정
- 외국인 보유율 측정 시점 (연말 vs 평균) 불일치
- 우선주 비포함 보유율로 보통주 배당과 매칭
- 상관관계를 인과로 단정 (외인이 배당 정책 결정한다)
- 단일 lag 만 보고 시차 결론