← 태버지 목록
_classify_sectors.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
"""finviz_chart_items.json 의 305개 ticker 를 의미 기반 24개 그룹으로 재분류.

기존 finviz JSON 의 12 그룹은 "통화/채권" 안에 NVDA/META 같은 개별 종목이
잡탕으로 들어 있어서 평균 점수가 의미 없었음. 이 모듈은 caption 키워드 기반으로
재분류한 결과를 sector_taxonomy.json 에 저장. 결과는 _intraday_strength_cell 이 사용.

실행: python _classify_sectors.py
출력: sector_taxonomy.json + 분류 통계 stdout
"""
from __future__ import annotations

import json
import re
import sys
from collections import Counter, defaultdict
from pathlib import Path

CFG_PATH = Path(__file__).parent / "finviz_chart_items.json"
OUT_PATH = Path(__file__).parent / "sector_taxonomy.json"

# 우선순위 순서 (위에서부터 매칭, 첫 일치 채택)
RULES: list[tuple[str, str]] = [
    # ── 광역 인덱스 / 시장
    ("미국 광역 인덱스",
     r"S&P 500|러셀 2000|나스닥 100|다우 30|VTI|VOO|IVV|QQQ"),
    ("미국 사이즈/스타일/배당",
     r"배당|VIG|DVY|PEY|IWM|VBR|IWO|IWS|IWP|VTV|VUG|MGK|MGV|소형|중형|"
     r"대형(가치|성장)|대형주|모멘텀|로우볼|퀄리티 ETF|밸류 팩터|"
     r"성장주 ETF|가치주 ETF"),
    ("자산배분 / 팩터",
     r"리스크 패리티|60/40|자산배분"),
    # ── GICS 섹터 ETF
    ("미국 GICS 섹터 ETF",
     r"^XL[A-Z]|GICS|섹터 ETF$|^SPDR.*Sector"),
    # ── 반도체
    ("반도체",
     r"반도체|메모리|파운드리|팹리스|EUV|노광|EDA|HDD|NAND|DRAM|PCB|"
     r"증착|식각|검사·계측|검사장비|패키징|OSAT|후공정|HPC|모바일칩|"
     r"모뎀|스토리지/플래시|광학$|^SMH$|^SOXX$|반도체$|"
     r"테스트\(소켓|^FORM$"),
    # ── 빅테크
    ("빅테크 플랫폼",
     r"애플|마이크로소프트|구글|아마존$|메타|넷플릭스|디즈니|오라클|"
     r"^MSFT$|^GOOGL$|^AAPL$|^AMZN$|^META$|^NFLX$|^DIS$|^ORCL$|어도비|"
     r"세일즈포스|스트리밍|콘텐츠/스트리밍|소셜|메타버스|미디어 실험|"
     r"^VT$|^EZU$|전세계 주식|유로존"),
    # ── 사이버보안
    ("사이버보안",
     r"보안$|보안\(|크라우드|포티넷|지스케일러|팔로알토|클라우드플레어|"
     r"HACK|CIBR|네트워크 보안"),
    # ── AI / SW / 클라우드
    ("AI / 엔터프라이즈 SW",
     r"AI 소프트웨어|데이터·AI|NoSQL|팔란티어|C3\.ai|MSAI|MDB|PLTR|"
     r"스노우플레이크|소프트웨어$|^IGV$|^SKYY$|클라우드 컴퓨팅|"
     r"글로벌 소셜|분자모델링|의료AI|AI 신약|헬스케어 IT"),
    # ── 데이터센터·전력
    ("데이터센터·전력 인프라",
     r"데이터센터|냉각|UPS|스위치기어|전력기기|변압기|아리스타|버티브|"
     r"이튼|Powell Industries|EQIX|DLR|네트워킹|네트워크 장비|서버|"
     r"PC/AI 인프라|송배전|콴타|전력설비|GE Vernova|컨스텔레이션|"
     r"^CEG$|^GEV$|^PWR$|^SILC$|^ADTN$|IoT 플랫폼"),
    # ── 우주·위성
    ("우주 / 위성",
     r"우주|위성|^UFO$|^ROKT$|^LUNR$|^SATL$|달착륙|로켓 ETF"),
    # ── 방산
    ("방산 / 항공우주",
     r"방산|록히드|노스럽|RTX|L3해리스|보잉|^ITA$|^PPA$|^XAR$|^JETS$|"
     r"글로벌 항공|항공우주|항공엔진|에너지 설비"),
    # ── 헬스케어
    ("헬스케어 / 바이오",
     r"바이오|제약|항체|치료|일라이|머크|화이자|존슨|치과|정형외과|"
     r"인슐린|^XBI$|^IBB$|^XLV$|디바이스|의료유통|의료기기|GLP|비만|"
     r"당뇨|수술로봇|혈당|톡신|의료미용|뇌질환|진단|여성건강|건강관리|"
     r"^IXJ$|^ISRG$|^DXCM$|^HOLX$|파이프라인|자가면역|방사성의약품|"
     r"SC 제형|디지털 정신건강|^TALK$|홈케어|^AHCO$|랜티우스|"
     r"테라토|에스티팜|^GERN$|^LNTH$|^SDGR$|^RXRX$|^PHR$|^HALO$"),
    # ── 클린에너지
    ("클린·신재생 에너지",
     r"태양|풍력|수소|연료전지|클린|^ICLN$|^TAN$|^HYDR$|^NEE$|"
     r"블룸에너지|ESS$|배터리|^CHPT$|EV충전"),
    # ── 원자력
    ("원자력 / 우라늄",
     r"원자력|우라늄|SMR|농축|소형원자로|^URA$|^URNM$|^OKLO$|^LEU$|"
     r"센트러스|카메코"),
    # ── 자동차
    ("자동차 / 모빌리티",
     r"전기차|EV$|테슬라|리비안|루시드|니오|샤오펑|BYD|자율주행|전장|"
     r"앱티브|모빌리티|완성차|^F$|^GM$|^CARZ$|글로벌 자동차|자동차 부품"),
    # ── 에너지 / 석유 / 가스
    ("에너지 / 석유·가스",
     r"엑슨모빌|쉐브론|슐럼버져|베이커휴즈|^XLE$|^XOP$|^XOM$|^CVX$|"
     r"^SLB$|^BKR$|에너지/석유|오일서비스|석유|가스 ETF|^LNG$|^EQT$|"
     r"천연가스|LNG 수출|글로벌 에너지|^E$"),
    # ── 해운 / 운송
    ("해운 / 운송",
     r"해운|벌크|탱커|운반선|운반$|LPG 운반|^SBLK$|^STNG$|^LPG$|"
     r"^HAFN$|^IYT$|운송|^UPS$|FedEx|페덱스"),
    # ── 원자재 / 광물
    ("원자재 / 광물 / 금속",
     r"구리|니켈|리튬|희토류|원자재|귀금속|금 ETF|은 ETF|팔라듐|^GLD$|"
     r"^SLV$|^COPX$|^REMX$|^LIT$|^CPER$|광산|^GDX$|금광|알루미늄|^AA$|"
     r"^LPX$|건축 목재|^CAT$|중장비|촉매|화학|^ECVT$"),
    # ── 농업
    ("농업 / 식음료 원자재",
     r"농업|^ALCO$|^ANDE$|^DBA$"),
    # ── 소비재 / 리테일 / 음식
    ("소비재 / 리테일 / 음식",
     r"리테일|이커머스(?!.*AI)|코스트코|애슬레저|매트리스|색조|"
     r"스포츠웨어|렌터카|월마트|타깃|홈디포|로우|^XLY$|^XLP$|소비재|"
     r"^XRT$|미국 소매|^GAP$|의류|^EL$|뷰티|^GIS$|식음료|^DG$|디스카운트|"
     r"^PM$|담배|주방용품|^LCUT$|^TR$|식품|식품 유통|^IMKTA$|^VLGEA$|"
     r"^KODK$|이미지|유통$"),
    # ── 카지노 / 여가 / 리오프닝
    ("카지노 / 여가 / 여행",
     r"카지노|마카오|^WYNN$|^LVS$|극장|리오프닝|^AMC$|공연|^LYV$|여행|"
     r"^PEJ$|^AWAY$|관광|^PRSU$|크루즈"),
    # ── 금융 / 핀테크
    ("금융 / 핀테크",
     r"은행|보험|증권사|핀테크|페이팔|비자|마스터|^BAC$|^JPM$|^GS$|^MS$|"
     r"^XLF$|^KRE$|^KIE$|블록|^HOOD$|로빈훗|^VIRT$|트레이딩|"
     r"^금융$|Range Capital|^RANG$"),
    # ── 부동산
    ("부동산 / REIT",
     r"REIT|^XLRE$|부동산|^VNQ$|^IYR$|^CBL$|리츠"),
    # ── 채권
    ("채권 / 우선주",
     r"국채|TIPS|HY 채권|IG 채권|회사채|^TLT$|^HYG$|^LQD$|^AGG$|^BND$|"
     r"이머징.*채권|^EMB$|장기 국채|단기 국채|채권$|우선주|^XOMAO$|"
     r"^OXLCM$|^XRN-B$|^RCB$|^RANG$"),
    # ── 통화 / FX
    ("통화 / FX",
     r"달러 인덱스|엔 ETF|통화 바스켓|^UUP$|^FXE$|^FXY$|FX$"),
    # ── 해외 / 지역
    ("해외 / 지역 ETF",
     r"한국$|일본$|중국$|독일$|브라질$|인도$|영국$|유럽$|이머징$|^EWY$|"
     r"^EWJ$|^FXI$|^EWG$|^EWZ$|^INDA$|^EWU$|^VGK$|^EFA$|^VEA$|^VWO$|"
     r"^IEUR$|^DFE$|^EFV$|^EFG$|^AAXJ$|아시아|일본 제외|미국 제외|"
     r"^CQQQ$|^CHIQ$|중국 인터넷|중국 소비"),
    # ── 산업재 / 인프라
    ("산업재 / 인프라",
     r"산업재|^XLI$|건설|기계|항공기 부품|인프라|환경|^CLH$|"
     r"EMS$|^JBL$|^SANM$|^TOYO$|^NSYS$|전자$|^산업$"),
    # ── 통신 / 미디어
    ("통신 / 미디어",
     r"통신|^XTL$|^XLC$|버라이즌|AT&T|T-모바일|^TMUS$|^VZ$"),
    # ── 로봇 / 자동화
    ("로봇 / 자동화",
     r"^ROBO$|^ROBT$|^CGNX$|머신비전|로봇 ETF"),
    # ── 암호화폐 / 디지털자산
    ("암호화폐 / 디지털자산",
     r"비트코인|^HODL$|^MSTR$|^COIN$|코인베이스|BTC"),
    # ── 글로벌 테마 (3D/IPO/소셜/우주 외 잡테마)
    ("글로벌 테마",
     r"3D|^PRNT$|^IPOS$|^SOCL$|르네상스 IPO"),
    # ── IT 유통
    ("IT 유통 / 컨설팅",
     r"IT 유통|^SNX$|^FCN$|컨설팅"),
    # ── SPAC / 우선주 등 특수
    ("특수 / SPAC",
     r"SPAC$|^PONOU$|^PAAC$|^TDAC$"),
]


def classify(caption: str) -> str:
    for cat, pat in RULES:
        if re.search(pat, caption, re.IGNORECASE):
            return cat
    return "기타 / 미분류"


def build_taxonomy() -> dict:
    cfg = json.loads(CFG_PATH.read_text(encoding="utf-8"))
    items: dict[str, str] = {}  # ticker → caption
    for group_items in cfg.values():
        for it in group_items:
            items.setdefault(it["ticker"], it["caption"])
    mapping = {t: classify(cap) for t, cap in items.items()}
    return {
        "version": 2,
        "generated_at": __import__("datetime").datetime.now().isoformat(timespec="seconds"),
        "source": "finviz_chart_items.json",
        "ticker_to_group": mapping,
        "captions": items,
    }


def main(argv: list[str] | None = None) -> int:
    tx = build_taxonomy()
    OUT_PATH.write_text(json.dumps(tx, ensure_ascii=False, indent=2), encoding="utf-8")
    counts = Counter(tx["ticker_to_group"].values())
    print(f"=== sector_taxonomy v{tx['version']} 생성 ===")
    print(f"총 ticker: {len(tx['ticker_to_group'])}")
    print(f"카테고리 수: {len(counts)}")
    print("─" * 50)
    for cat, n in sorted(counts.items(), key=lambda x: -x[1]):
        bar = "█" * min(n, 30)
        print(f"  {cat:<28}  {n:>3}  {bar}")
    print(f"\n저장: {OUT_PATH}")
    print(f"미분류: {counts.get('기타 / 미분류', 0)}개")
    return 0


if __name__ == "__main__":
    sys.exit(main())
노트북 실행 중...
_classify_sectors.py
0.0초
Papermill로 모든 셀을 다시 실행하고 있습니다.
수십 초에서 몇 분 걸릴 수 있습니다. 창을 닫지 마세요.