recipes.industry.sectorFlowConcentration Recipes Recipe curated

섹터 자금 흐름 집중도 (외인 비중 + 거래대금 share)

종목이 속한 섹터의 외인 보유 비율 + 거래대금 share 의 단순 정량 표기. 섹터 안 종목 거래대금이 한 종목으로 집중되면 *집중*, 분산되면 *분산*. 추론 라벨 없이 절대 수치만. sector + price gather 결합. 트리거 — '섹터 자금 흐름 집중도 (외인 비중 + 거래대금 share)', 'sector flow concentration', 'sectorFlowConcentration'.

이 스킬

섹터 자금 흐름 집중도 (외인 비중 + 거래대금 share)

종목이 속한 섹터의 외인 보유 비율 + 거래대금 share 의 단순 정량 표기. 섹터 안 종목 거래대금이 한 종목으로 집중되면 *집중*, 분산되면 *분산*. 추론 라벨 없이 절대 수치만. sector + price gather 결합. 트리거 — '섹터 자금 흐름 집중도 (외인 비중 + 거래대금 share)', 'sector flow concentration', 'sectorFlowConcentration'.

Recipes curated recipes.industry.sectorFlowConcentration

연계 절차

이 절차의 단계

  1. 1
    동종 peer 가격 수렴 / 발산 (60d ret 분포) recipes.industry.peerPriceConvergence

    peer 분산과 concentration phase 동시 확인.

  2. 2

    외인 보유 + flow 가속도 두 축 비교.

절차

실행 순서

  1. 1

    종목 5 거래일 평균 거래대금 (Company.gather('price') volume × close)

  2. 2

    섹터 총 거래대금 (sector universe 합산)

  3. 3

    외인 보유율 (Company.gather('flow') 또는 분기 ownership)

  4. 4

    섹터 분류 (GICS/KRX) 차이로 peer 정의 달라짐.

  5. 5

    5거래일 평균 짧음 — 일시적 거래량 폭증 (공시 일자) 왜곡.

  6. 6

    외인 보유율 분기 데이터 사용 시 최근 변동 미반영.

  7. 7

    시총 차이 큰 peer (top-heavy 섹터) share 자동 왜곡.

  8. 8

    concentrated phase 지속: `recipes.sentiment.foreignBuyMomentum` 으로 외인 가속도 확인.

  9. 9

    외인 보유율 급변 (분기 ±5%p): `recipes.sentiment.ownershipShiftSignal` 추적.

  10. 10

    diffuse 진입: `recipes.industry.peerPriceConvergence` 로 peer 가격 발산 여부 확인.

  11. 11

    sector / price row 0 → phase=insufficient.

  12. 12

    단일 거래일 표면화 금지 — 5 거래일 평균 사용.

예시

이런 질문이 들어오면 이 skill 을 쓴다

  • 반도체 섹터 거래대금이 005930 한 종목으로 쏠려있나
  • 섹터 안 외인 보유율 상위 종목
  • 섹터 자금 집중도 정량 확인

출력

기대 결과

  • 섹터 종목별 거래대금 share + 외인 보유율 표 (top N)
  • top1 종목 share + top3 합산 share — 집중도 측정값
  • 자기 종목 위치 (share rank + 외인 비중 percentile)

공개 호출 방식

import dartlab
import polars as pl

target = "005930"
c = dartlab.Company(target)


def floatOr(v):
    try:
        return float(v) if v is not None else None
    except Exception:
        return None


# 종목 거래대금 평균
try:
    pdf = c.gather("price").head(10)
    p_rows = pdf.to_dicts() if hasattr(pdf, "to_dicts") else []
except Exception:
    p_rows = []

vals = []
for r in p_rows:
    cl = floatOr(r.get("close") or r.get("closePrice"))
    vol = floatOr(r.get("volume") or r.get("tradeVolume"))
    if cl is not None and vol is not None:
        vals.append(cl * vol)
target_value = sum(vals) / len(vals) if vals else None

# 외인 보유율 (flow gather row 의 마지막)
try:
    fdf = c.gather("flow").head(5)
    f_rows = fdf.to_dicts() if hasattr(fdf, "to_dicts") else []
except Exception:
    f_rows = []

foreign_pct = None
for r in f_rows:
    v = floatOr(r.get("foreignHoldingRatio") or r.get("foreignRatio"))
    if v is not None:
        foreign_pct = v
        break

# sector gather — sector total value 혹은 sector index
try:
    sdf = c.gather("sector").head(5)
    s_rows = sdf.to_dicts() if hasattr(sdf, "to_dicts") else []
except Exception:
    s_rows = []

sector_total_value = None
for r in s_rows:
    v = floatOr(r.get("totalValue") or r.get("sectorValue") or r.get("totalTradeValue"))
    if v is not None:
        sector_total_value = v
        break

share = None
if target_value is not None and sector_total_value and sector_total_value > 0:
    share = target_value / sector_total_value

phase = "insufficient"
if share is not None:
    if share > 0.20:
        phase = "concentrated"
    elif share < 0.05:
        phase = "diffuse"
    else:
        phase = "normal"

table = pl.DataFrame(
    [
        {
            "targetAvgValue": target_value,
            "sectorTotalValue": sector_total_value,
            "valueShare": share,
            "foreignHoldingPct": foreign_pct,
            "phase": phase,
            "priceRowsAvailable": len(p_rows),
            "sectorRowsAvailable": len(s_rows),
        }
    ]
)

emit_result(
    table=table,
    values={
        "valueShare": share,
        "foreignHoldingPct": foreign_pct,
        "phase": phase,
    },
    date="latest",
    sources=["dartlab://gather/price", "dartlab://gather/flow", "dartlab://gather/sector"],
)

호출 동작

1. 결론 도출

섹터 거래대금 share + 외인 보유율 phase 단정 (concentrated > 20% / normal / diffuse < 5%). 예: “종목 share 18.5% (섹터 1위), 외인 49% → concentrated phase 직전 — 단일 종목 자금 집중 우려.”

2. 핵심 근거 수집

  • 종목 5 거래일 평균 거래대금 (Company.gather(‘price’) volume × close)
  • 섹터 총 거래대금 (sector universe 합산)
  • 외인 보유율 (Company.gather(‘flow’) 또는 분기 ownership)

3. 메커니즘 분석

종목 5d 평균 거래대금 / 섹터 N peer 5d 평균 거래대금 합

share = 종목 거래대금 / 섹터 거래대금 합

share > 20%  → concentrated (단일 종목 집중)
5-20%        → normal (정상)
< 5%         → diffuse (분산 거래)
   +
외인 보유율 (분기 또는 일별)
   > 40%     → 외인 강한 영향
   < 10%     → 개인/기관 위주

share + 외인 보유율 동시 본 → concentrated + 외인 ↑ = 외인 자금 단일 종목 집중 (외인 매도 시 가격 충격 큼).

4. 반례·한계

  • 섹터 분류 (GICS/KRX) 차이로 peer 정의 달라짐.
  • 5거래일 평균 짧음 — 일시적 거래량 폭증 (공시 일자) 왜곡.
  • 외인 보유율 분기 데이터 사용 시 최근 변동 미반영.
  • 시총 차이 큰 peer (top-heavy 섹터) share 자동 왜곡.

5. 후속 모니터링

  • concentrated phase 지속: recipes.sentiment.foreignBuyMomentum 으로 외인 가속도 확인.
  • 외인 보유율 급변 (분기 ±5%p): recipes.sentiment.ownershipShiftSignal 추적.
  • diffuse 진입: recipes.industry.peerPriceConvergence 로 peer 가격 발산 여부 확인.

대표 반환 형태

column의미
targetAvgValue종목 5 거래일 평균 거래대금
sectorTotalValue섹터 총 거래대금
valueSharetargetAvgValue / sectorTotalValue
foreignHoldingPct외인 보유율
phaseconcentrated / normal / diffuse / insufficient

연계 절차

  1. recipes.industry.peerPriceConvergence — peer 분산과 concentration phase 동시 확인.
  2. recipes.sentiment.foreignBuyMomentum — 외인 보유 + flow 가속도 두 축 비교.

기본 검증

  • sector / price row 0 → phase=insufficient.
  • 단일 거래일 표면화 금지 — 5 거래일 평균 사용.
  • 외인 보유율 = 보유 비율 ≠ 일별 순매수 (다른 row).

런타임

실행 환경별 호환성

환경상태비고 / 제한
Local Python supported·
Server supported·
MCP supported·
Web AI limited·
Pyodide limited·

실패 회피

흔한 실패 · 절대 금지

흔한 실패
  • sector gather row 0
  • 단일 거래일 변동을 집중도로 오인
  • 외인 보유율 (보유 vs 매매) 정의 혼동
절대 금지
  • 거래대금 집중도 자체로 매수 시그널 단정 금지
  • 외인 보유율 절대값으로 sentiment 라벨 단정 금지