""" ECOS 거시경제변수 포괄 수집기 — CSV 캐싱 목적: - ECOS API에서 30+ 거시경제변수 수집 - 수집 결과를 data/cache/macro_ecos.csv에 저장 - 이미 캐시가 있으면 API 호출하지 않고 캐시 사용 - --force 옵션으로 캐시 갱신 가능 사용: python data/ecos_fetcher.py # 캐시 있으면 skip python data/ecos_fetcher.py --force # 캐시 무시하고 API 재수집 python data/ecos_fetcher.py --no-api # API 없이 fallback만 사용 """ import sys, io, time, argparse, json import numpy as np, pandas as pd from pathlib import Path if sys.stdout.encoding != 'utf-8': sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.path.insert(0, str(Path(__file__).parent.parent)) CACHE_DIR = Path(__file__).parent / "cache" CACHE_FILE = CACHE_DIR / "macro_ecos.csv" # ============================================================ # ECOS 변수 정의 (stat_code, period, item_code, 변수명, 월→연 집계법) # ============================================================ ECOS_VARIABLES = [ # --- 성장 --- {"name": "GDP_GROWTH", "stat": "200Y002", "period": "A", "item": "10111", "agg": None, "desc": "GDP 실질성장률 (%)"}, # --- 고용 --- {"name": "UNEMPLOYMENT", "stat": "901Y027", "period": "M", "item": "I16AA", "agg": "mean", "desc": "실업률 (%)"}, # --- 금리 --- {"name": "BASE_RATE", "stat": "722Y001", "period": "M", "item": "0101000", "agg": "last", "desc": "한은 기준금리 (%)"}, {"name": "CD_RATE", "stat": "817Y002", "period": "M", "item": "010502000", "agg": "mean", "desc": "CD 91일 금리 (%)"}, {"name": "GOVT_3Y", "stat": "817Y002", "period": "M", "item": "010200000", "agg": "mean", "desc": "국고채 3년 금리 (%)"}, {"name": "GOVT_10Y", "stat": "817Y002", "period": "M", "item": "010210000", "agg": "mean", "desc": "국고채 10년 금리 (%)"}, {"name": "CORP_AA", "stat": "817Y002", "period": "M", "item": "010300000", "agg": "mean", "desc": "회사채 AA- 금리 (%)"}, {"name": "CORP_BBB", "stat": "817Y002", "period": "M", "item": "010400000", "agg": "mean", "desc": "회사채 BBB- 금리 (%)"}, # --- 물가 --- {"name": "CPI_GROWTH", "stat": "901Y009", "period": "A", "item": "0", "agg": None, "desc": "소비자물가 상승률 (%)"}, {"name": "IMPORT_PRICE", "stat": "404Y014", "period": "M", "item": "AA00", "agg": "mean", "desc": "수입물가지수 (원화기준)"}, {"name": "PPI", "stat": "404Y014", "period": "M", "item": "AA00", "agg": "mean", "desc": "생산자물가지수"}, # 별도 확인 필요 # --- 경기지수 --- {"name": "LEADING_INDEX", "stat": "901Y067", "period": "M", "item": "I16A", "agg": "mean", "desc": "경기선행종합지수"}, {"name": "COINCIDENT", "stat": "901Y067", "period": "M", "item": "I16B", "agg": "mean", "desc": "경기동행종합지수"}, {"name": "CSI", "stat": "901Y068", "period": "M", "item": "I16A", "agg": "mean", "desc": "소비자심리지수 (CCSI)"}, {"name": "BSI_MANUF", "stat": "512Y014", "period": "M", "item": "99BA", "agg": "mean", "desc": "제조업 BSI (전망)"}, # --- 생산/교역 --- {"name": "IPI", "stat": "901Y033", "period": "M", "item": "I11A", "agg": "mean", "desc": "광공업생산지수"}, {"name": "SPI", "stat": "901Y033", "period": "M", "item": "I31A", "agg": "mean", "desc": "서비스업생산지수"}, {"name": "EXPORT", "stat": "403Y001", "period": "A", "item": "1", "agg": None, "desc": "수출 (백만달러)"}, {"name": "IMPORT_AMT", "stat": "403Y001", "period": "A", "item": "2", "agg": None, "desc": "수입 (백만달러)"}, # --- 환율/유가 --- {"name": "USDKRW", "stat": "036Y001", "period": "M", "item": "0000001", "agg": "mean", "desc": "원/달러 환율 (종가평균)"}, # --- 통화/유동성 --- {"name": "M2", "stat": "101Y003", "period": "M", "item": "BBGA00", "agg": "last", "desc": "M2 광의통화 (조원)"}, # --- 부도/신용 --- {"name": "DISHONOR_RATE", "stat": "104Y016", "period": "M", "item": "010000", "agg": "mean", "desc": "어음부도율 (%)"}, {"name": "DISHONOR_AMT", "stat": "104Y016", "period": "M", "item": "020000", "agg": "sum", "desc": "부도금액 (억원)"}, # --- 주식 --- {"name": "KOSPI", "stat": "802Y001", "period": "M", "item": "0001000", "agg": "mean", "desc": "KOSPI 종합주가지수"}, # --- 부동산/건설 --- {"name": "HOUSING_PRICE", "stat": "901Y062", "period": "M", "item": "P00", "agg": "mean", "desc": "전국 주택매매가격지수"}, {"name": "CONSTRUCTION", "stat": "512Y010", "period": "M", "item": "10AA", "agg": "sum", "desc": "건설수주액 (억원)"}, # --- 가계 --- {"name": "HOUSEHOLD_DEBT","stat": "151Y001", "period": "Q", "item": "A11", "agg": "last", "desc": "가계부채 (조원)"}, ] # ============================================================ # Fallback 데이터 (API 없이도 작동) — 31개 변수, 26년 # ============================================================ # 추가 변수 설명: # FACILITY_INVEST: 설비투자지수 (2020=100) # RETAIL_SALES: 소매판매액지수 (2020=100) # CURRENT_ACCOUNT: 경상수지 (억달러) # EMPLOYED: 취업자수 (만명) # EMPLOYMENT_RATE: 고용률 15-64세 (%) # OIL_PRICE: 두바이유 연평균 ($/배럴) — 한국 수입유 기준 # COINCIDENT: 경기동행종합지수 # BSI_MANUF: 제조업 BSI 전망 # CONSTRUCTION_DONE: 건설기성액 (조원) # SPI: 서비스업생산지수 (2020=100) def _build_fallback() -> pd.DataFrame: """API 없이 작동하는 확장 fallback — 31개 변수""" # fmt: off data = { 2000: {"GDP_GROWTH":8.9,"UNEMPLOYMENT":4.4,"BASE_RATE":5.25,"CD_RATE":7.09,"CPI_GROWTH":2.3,"LEADING_INDEX":101.2,"GOVT_3Y":8.35,"GOVT_10Y":8.55,"CORP_AA":9.35,"CORP_BBB":11.90,"IPI":102.5,"EXPORT":172268,"IMPORT_AMT":160481,"USDKRW":1131,"M2":651.8,"CSI":101.0,"KOSPI":504,"IMPORT_PRICE":78.5,"DISHONOR_RATE":0.46,"HOUSING_PRICE":55.2,"HOUSEHOLD_DEBT":194.0, "FACILITY_INVEST":62.5,"RETAIL_SALES":72.0,"CURRENT_ACCOUNT":123.5,"EMPLOYED":2115,"EMPLOYMENT_RATE":58.5,"OIL_PRICE":26.2,"COINCIDENT":99.8,"BSI_MANUF":90,"CONSTRUCTION_DONE":56.3,"SPI":58.0}, 2001: {"GDP_GROWTH":4.5,"UNEMPLOYMENT":4.0,"BASE_RATE":4.00,"CD_RATE":5.34,"CPI_GROWTH":4.1,"LEADING_INDEX":99.5,"GOVT_3Y":6.70,"GOVT_10Y":7.05,"CORP_AA":8.12,"CORP_BBB":11.27,"IPI":99.5,"EXPORT":150439,"IMPORT_AMT":141098,"USDKRW":1291,"M2":736.5,"CSI":96.5,"KOSPI":694,"IMPORT_PRICE":73.6,"DISHONOR_RATE":0.28,"HOUSING_PRICE":56.8,"HOUSEHOLD_DEBT":225.0, "FACILITY_INVEST":58.5,"RETAIL_SALES":73.5,"CURRENT_ACCOUNT":80.3,"EMPLOYED":2118,"EMPLOYMENT_RATE":59.0,"OIL_PRICE":22.8,"COINCIDENT":98.0,"BSI_MANUF":82,"CONSTRUCTION_DONE":53.8,"SPI":60.2}, 2002: {"GDP_GROWTH":7.4,"UNEMPLOYMENT":3.3,"BASE_RATE":4.25,"CD_RATE":4.99,"CPI_GROWTH":2.8,"LEADING_INDEX":102.3,"GOVT_3Y":6.06,"GOVT_10Y":6.58,"CORP_AA":7.02,"CORP_BBB":9.75,"IPI":108.5,"EXPORT":162471,"IMPORT_AMT":152126,"USDKRW":1251,"M2":816.3,"CSI":105.0,"KOSPI":628,"IMPORT_PRICE":72.1,"DISHONOR_RATE":0.18,"HOUSING_PRICE":65.3,"HOUSEHOLD_DEBT":306.0, "FACILITY_INVEST":63.2,"RETAIL_SALES":76.0,"CURRENT_ACCOUNT":53.9,"EMPLOYED":2217,"EMPLOYMENT_RATE":60.0,"OIL_PRICE":23.7,"COINCIDENT":101.5,"BSI_MANUF":92,"CONSTRUCTION_DONE":55.2,"SPI":63.5}, 2003: {"GDP_GROWTH":2.9,"UNEMPLOYMENT":3.6,"BASE_RATE":3.75,"CD_RATE":4.24,"CPI_GROWTH":3.5,"LEADING_INDEX":98.8,"GOVT_3Y":4.93,"GOVT_10Y":5.45,"CORP_AA":5.70,"CORP_BBB":8.97,"IPI":109.8,"EXPORT":193817,"IMPORT_AMT":178827,"USDKRW":1192,"M2":879.2,"CSI":96.0,"KOSPI":811,"IMPORT_PRICE":81.3,"DISHONOR_RATE":0.12,"HOUSING_PRICE":71.5,"HOUSEHOLD_DEBT":360.0, "FACILITY_INVEST":60.5,"RETAIL_SALES":74.0,"CURRENT_ACCOUNT":119.5,"EMPLOYED":2212,"EMPLOYMENT_RATE":59.5,"OIL_PRICE":26.8,"COINCIDENT":99.2,"BSI_MANUF":85,"CONSTRUCTION_DONE":58.0,"SPI":64.8}, 2004: {"GDP_GROWTH":4.9,"UNEMPLOYMENT":3.7,"BASE_RATE":3.25,"CD_RATE":3.77,"CPI_GROWTH":3.6,"LEADING_INDEX":100.5,"GOVT_3Y":4.11,"GOVT_10Y":4.73,"CORP_AA":4.72,"CORP_BBB":7.53,"IPI":119.2,"EXPORT":253845,"IMPORT_AMT":224463,"USDKRW":1145,"M2":935.3,"CSI":97.0,"KOSPI":896,"IMPORT_PRICE":90.5,"DISHONOR_RATE":0.08,"HOUSING_PRICE":71.0,"HOUSEHOLD_DEBT":394.0, "FACILITY_INVEST":66.5,"RETAIL_SALES":74.5,"CURRENT_ACCOUNT":284.2,"EMPLOYED":2272,"EMPLOYMENT_RATE":59.8,"OIL_PRICE":33.5,"COINCIDENT":100.8,"BSI_MANUF":88,"CONSTRUCTION_DONE":63.5,"SPI":66.0}, 2005: {"GDP_GROWTH":3.9,"UNEMPLOYMENT":3.7,"BASE_RATE":3.75,"CD_RATE":3.81,"CPI_GROWTH":2.8,"LEADING_INDEX":101.8,"GOVT_3Y":4.27,"GOVT_10Y":4.95,"CORP_AA":4.68,"CORP_BBB":6.51,"IPI":126.0,"EXPORT":284419,"IMPORT_AMT":261238,"USDKRW":1024,"M2":1002.7,"CSI":100.5,"KOSPI":1011,"IMPORT_PRICE":99.2,"DISHONOR_RATE":0.06,"HOUSING_PRICE":73.5,"HOUSEHOLD_DEBT":440.0, "FACILITY_INVEST":68.0,"RETAIL_SALES":76.5,"CURRENT_ACCOUNT":149.8,"EMPLOYED":2297,"EMPLOYMENT_RATE":60.3,"OIL_PRICE":49.3,"COINCIDENT":101.2,"BSI_MANUF":92,"CONSTRUCTION_DONE":66.0,"SPI":68.5}, 2006: {"GDP_GROWTH":5.2,"UNEMPLOYMENT":3.5,"BASE_RATE":4.50,"CD_RATE":4.72,"CPI_GROWTH":2.2,"LEADING_INDEX":102.5,"GOVT_3Y":4.83,"GOVT_10Y":5.17,"CORP_AA":5.25,"CORP_BBB":7.08,"IPI":136.0,"EXPORT":325465,"IMPORT_AMT":309383,"USDKRW":955,"M2":1089.9,"CSI":106.0,"KOSPI":1434,"IMPORT_PRICE":107.8,"DISHONOR_RATE":0.05,"HOUSING_PRICE":80.2,"HOUSEHOLD_DEBT":497.0, "FACILITY_INVEST":73.5,"RETAIL_SALES":78.5,"CURRENT_ACCOUNT":53.9,"EMPLOYED":2334,"EMPLOYMENT_RATE":60.9,"OIL_PRICE":61.5,"COINCIDENT":102.8,"BSI_MANUF":95,"CONSTRUCTION_DONE":69.5,"SPI":71.2}, 2007: {"GDP_GROWTH":5.5,"UNEMPLOYMENT":3.2,"BASE_RATE":5.00,"CD_RATE":5.36,"CPI_GROWTH":2.5,"LEADING_INDEX":103.1,"GOVT_3Y":5.23,"GOVT_10Y":5.42,"CORP_AA":5.70,"CORP_BBB":7.44,"IPI":144.5,"EXPORT":371489,"IMPORT_AMT":356846,"USDKRW":929,"M2":1181.6,"CSI":108.5,"KOSPI":1897,"IMPORT_PRICE":109.3,"DISHONOR_RATE":0.04,"HOUSING_PRICE":83.5,"HOUSEHOLD_DEBT":560.0, "FACILITY_INVEST":78.5,"RETAIL_SALES":80.0,"CURRENT_ACCOUNT":59.5,"EMPLOYED":2371,"EMPLOYMENT_RATE":61.3,"OIL_PRICE":68.4,"COINCIDENT":103.5,"BSI_MANUF":97,"CONSTRUCTION_DONE":72.8,"SPI":74.0}, 2008: {"GDP_GROWTH":2.8,"UNEMPLOYMENT":3.2,"BASE_RATE":3.00,"CD_RATE":5.70,"CPI_GROWTH":4.7,"LEADING_INDEX":96.5,"GOVT_3Y":5.27,"GOVT_10Y":5.57,"CORP_AA":7.02,"CORP_BBB":10.73,"IPI":148.2,"EXPORT":422007,"IMPORT_AMT":435275,"USDKRW":1103,"M2":1263.2,"CSI":86.0,"KOSPI":1124,"IMPORT_PRICE":132.5,"DISHONOR_RATE":0.11,"HOUSING_PRICE":84.0,"HOUSEHOLD_DEBT":630.0, "FACILITY_INVEST":76.0,"RETAIL_SALES":79.0,"CURRENT_ACCOUNT":-57.8,"EMPLOYED":2385,"EMPLOYMENT_RATE":61.5,"OIL_PRICE":94.3,"COINCIDENT":98.5,"BSI_MANUF":72,"CONSTRUCTION_DONE":74.5,"SPI":75.5}, 2009: {"GDP_GROWTH":0.8,"UNEMPLOYMENT":3.6,"BASE_RATE":2.00,"CD_RATE":2.63,"CPI_GROWTH":2.8,"LEADING_INDEX":98.2,"GOVT_3Y":4.04,"GOVT_10Y":4.85,"CORP_AA":5.80,"CORP_BBB":9.24,"IPI":140.0,"EXPORT":363534,"IMPORT_AMT":323085,"USDKRW":1276,"M2":1404.4,"CSI":85.0,"KOSPI":1683,"IMPORT_PRICE":104.2,"DISHONOR_RATE":0.10,"HOUSING_PRICE":84.8,"HOUSEHOLD_DEBT":694.0, "FACILITY_INVEST":60.5,"RETAIL_SALES":77.5,"CURRENT_ACCOUNT":328.1,"EMPLOYED":2355,"EMPLOYMENT_RATE":60.1,"OIL_PRICE":61.8,"COINCIDENT":96.5,"BSI_MANUF":68,"CONSTRUCTION_DONE":68.2,"SPI":76.0}, 2010: {"GDP_GROWTH":6.8,"UNEMPLOYMENT":3.7,"BASE_RATE":2.50,"CD_RATE":2.80,"CPI_GROWTH":2.9,"LEADING_INDEX":103.0,"GOVT_3Y":3.72,"GOVT_10Y":4.49,"CORP_AA":4.66,"CORP_BBB":7.98,"IPI":161.5,"EXPORT":466384,"IMPORT_AMT":425212,"USDKRW":1156,"M2":1504.3,"CSI":107.0,"KOSPI":2051,"IMPORT_PRICE":115.8,"DISHONOR_RATE":0.06,"HOUSING_PRICE":87.0,"HOUSEHOLD_DEBT":776.0, "FACILITY_INVEST":80.5,"RETAIL_SALES":80.5,"CURRENT_ACCOUNT":282.1,"EMPLOYED":2397,"EMPLOYMENT_RATE":60.4,"OIL_PRICE":78.1,"COINCIDENT":103.0,"BSI_MANUF":95,"CONSTRUCTION_DONE":72.0,"SPI":78.5}, 2011: {"GDP_GROWTH":3.7,"UNEMPLOYMENT":3.4,"BASE_RATE":3.25,"CD_RATE":3.55,"CPI_GROWTH":4.0,"LEADING_INDEX":101.2,"GOVT_3Y":3.62,"GOVT_10Y":4.05,"CORP_AA":4.41,"CORP_BBB":7.75,"IPI":168.0,"EXPORT":555214,"IMPORT_AMT":524413,"USDKRW":1108,"M2":1586.5,"CSI":100.0,"KOSPI":1826,"IMPORT_PRICE":130.2,"DISHONOR_RATE":0.05,"HOUSING_PRICE":89.5,"HOUSEHOLD_DEBT":857.0, "FACILITY_INVEST":82.0,"RETAIL_SALES":82.0,"CURRENT_ACCOUNT":184.1,"EMPLOYED":2424,"EMPLOYMENT_RATE":60.7,"OIL_PRICE":106.0,"COINCIDENT":102.5,"BSI_MANUF":90,"CONSTRUCTION_DONE":73.5,"SPI":80.0}, 2012: {"GDP_GROWTH":2.4,"UNEMPLOYMENT":3.2,"BASE_RATE":2.75,"CD_RATE":3.13,"CPI_GROWTH":2.2,"LEADING_INDEX":100.3,"GOVT_3Y":3.13,"GOVT_10Y":3.35,"CORP_AA":3.76,"CORP_BBB":6.56,"IPI":168.2,"EXPORT":547870,"IMPORT_AMT":519584,"USDKRW":1127,"M2":1673.5,"CSI":100.5,"KOSPI":1997,"IMPORT_PRICE":123.5,"DISHONOR_RATE":0.04,"HOUSING_PRICE":89.0,"HOUSEHOLD_DEBT":934.0, "FACILITY_INVEST":79.0,"RETAIL_SALES":83.5,"CURRENT_ACCOUNT":508.4,"EMPLOYED":2468,"EMPLOYMENT_RATE":61.3,"OIL_PRICE":109.1,"COINCIDENT":100.5,"BSI_MANUF":85,"CONSTRUCTION_DONE":72.0,"SPI":82.5}, 2013: {"GDP_GROWTH":3.2,"UNEMPLOYMENT":3.1,"BASE_RATE":2.50,"CD_RATE":2.72,"CPI_GROWTH":1.3,"LEADING_INDEX":100.8,"GOVT_3Y":2.79,"GOVT_10Y":3.28,"CORP_AA":3.19,"CORP_BBB":5.87,"IPI":168.8,"EXPORT":559632,"IMPORT_AMT":515586,"USDKRW":1095,"M2":1756.2,"CSI":103.0,"KOSPI":2011,"IMPORT_PRICE":115.0,"DISHONOR_RATE":0.04,"HOUSING_PRICE":88.8,"HOUSEHOLD_DEBT":980.0, "FACILITY_INVEST":77.5,"RETAIL_SALES":85.0,"CURRENT_ACCOUNT":812.1,"EMPLOYED":2503,"EMPLOYMENT_RATE":61.6,"OIL_PRICE":105.5,"COINCIDENT":101.0,"BSI_MANUF":88,"CONSTRUCTION_DONE":71.5,"SPI":84.0}, 2014: {"GDP_GROWTH":3.2,"UNEMPLOYMENT":3.5,"BASE_RATE":2.00,"CD_RATE":2.36,"CPI_GROWTH":1.3,"LEADING_INDEX":101.0,"GOVT_3Y":2.56,"GOVT_10Y":2.92,"CORP_AA":2.99,"CORP_BBB":5.22,"IPI":168.5,"EXPORT":572665,"IMPORT_AMT":525515,"USDKRW":1053,"M2":1871.0,"CSI":104.0,"KOSPI":1916,"IMPORT_PRICE":105.6,"DISHONOR_RATE":0.04,"HOUSING_PRICE":90.2,"HOUSEHOLD_DEBT":1050.0, "FACILITY_INVEST":81.0,"RETAIL_SALES":86.5,"CURRENT_ACCOUNT":843.5,"EMPLOYED":2546,"EMPLOYMENT_RATE":62.4,"OIL_PRICE":96.7,"COINCIDENT":101.5,"BSI_MANUF":90,"CONSTRUCTION_DONE":73.8,"SPI":86.0}, 2015: {"GDP_GROWTH":2.8,"UNEMPLOYMENT":3.6,"BASE_RATE":1.50,"CD_RATE":1.72,"CPI_GROWTH":0.7,"LEADING_INDEX":100.5,"GOVT_3Y":1.80,"GOVT_10Y":2.25,"CORP_AA":2.18,"CORP_BBB":4.61,"IPI":168.0,"EXPORT":526757,"IMPORT_AMT":436499,"USDKRW":1131,"M2":2010.0,"CSI":103.5,"KOSPI":1961,"IMPORT_PRICE":79.5,"DISHONOR_RATE":0.03,"HOUSING_PRICE":95.0,"HOUSEHOLD_DEBT":1145.0, "FACILITY_INVEST":84.5,"RETAIL_SALES":88.0,"CURRENT_ACCOUNT":1059.4,"EMPLOYED":2567,"EMPLOYMENT_RATE":62.6,"OIL_PRICE":51.2,"COINCIDENT":101.0,"BSI_MANUF":86,"CONSTRUCTION_DONE":77.5,"SPI":88.5}, 2016: {"GDP_GROWTH":2.9,"UNEMPLOYMENT":3.7,"BASE_RATE":1.25,"CD_RATE":1.48,"CPI_GROWTH":1.0,"LEADING_INDEX":99.8,"GOVT_3Y":1.44,"GOVT_10Y":1.80,"CORP_AA":1.88,"CORP_BBB":4.60,"IPI":168.5,"EXPORT":495426,"IMPORT_AMT":406193,"USDKRW":1161,"M2":2151.1,"CSI":100.0,"KOSPI":2026,"IMPORT_PRICE":78.0,"DISHONOR_RATE":0.03,"HOUSING_PRICE":97.5,"HOUSEHOLD_DEBT":1250.0, "FACILITY_INVEST":82.0,"RETAIL_SALES":89.5,"CURRENT_ACCOUNT":992.4,"EMPLOYED":2597,"EMPLOYMENT_RATE":63.0,"OIL_PRICE":41.3,"COINCIDENT":100.2,"BSI_MANUF":85,"CONSTRUCTION_DONE":89.5,"SPI":90.0}, 2017: {"GDP_GROWTH":3.2,"UNEMPLOYMENT":3.7,"BASE_RATE":1.50,"CD_RATE":1.52,"CPI_GROWTH":1.9,"LEADING_INDEX":101.5,"GOVT_3Y":1.80,"GOVT_10Y":2.33,"CORP_AA":2.28,"CORP_BBB":4.83,"IPI":174.2,"EXPORT":573694,"IMPORT_AMT":478478,"USDKRW":1131,"M2":2347.2,"CSI":105.0,"KOSPI":2467,"IMPORT_PRICE":90.5,"DISHONOR_RATE":0.02,"HOUSING_PRICE":100.0,"HOUSEHOLD_DEBT":1364.0, "FACILITY_INVEST":92.0,"RETAIL_SALES":92.0,"CURRENT_ACCOUNT":752.6,"EMPLOYED":2620,"EMPLOYMENT_RATE":63.2,"OIL_PRICE":53.1,"COINCIDENT":101.8,"BSI_MANUF":92,"CONSTRUCTION_DONE":90.0,"SPI":92.5}, 2018: {"GDP_GROWTH":2.9,"UNEMPLOYMENT":3.8,"BASE_RATE":1.75,"CD_RATE":1.85,"CPI_GROWTH":1.5,"LEADING_INDEX":100.8,"GOVT_3Y":2.10,"GOVT_10Y":2.56,"CORP_AA":2.67,"CORP_BBB":5.41,"IPI":178.0,"EXPORT":604860,"IMPORT_AMT":535202,"USDKRW":1100,"M2":2508.9,"CSI":102.0,"KOSPI":2041,"IMPORT_PRICE":100.0,"DISHONOR_RATE":0.03,"HOUSING_PRICE":102.0,"HOUSEHOLD_DEBT":1497.0, "FACILITY_INVEST":94.5,"RETAIL_SALES":94.0,"CURRENT_ACCOUNT":774.7,"EMPLOYED":2633,"EMPLOYMENT_RATE":63.1,"OIL_PRICE":69.5,"COINCIDENT":101.5,"BSI_MANUF":88,"CONSTRUCTION_DONE":85.5,"SPI":94.5}, 2019: {"GDP_GROWTH":2.2,"UNEMPLOYMENT":3.8,"BASE_RATE":1.25,"CD_RATE":1.63,"CPI_GROWTH":0.4,"LEADING_INDEX":99.3,"GOVT_3Y":1.50,"GOVT_10Y":1.74,"CORP_AA":1.93,"CORP_BBB":4.52,"IPI":175.5,"EXPORT":542233,"IMPORT_AMT":503343,"USDKRW":1166,"M2":2694.0,"CSI":97.0,"KOSPI":2198,"IMPORT_PRICE":92.5,"DISHONOR_RATE":0.03,"HOUSING_PRICE":104.5,"HOUSEHOLD_DEBT":1573.0, "FACILITY_INVEST":89.0,"RETAIL_SALES":96.5,"CURRENT_ACCOUNT":597.0,"EMPLOYED":2660,"EMPLOYMENT_RATE":63.5,"OIL_PRICE":63.4,"COINCIDENT":100.0,"BSI_MANUF":82,"CONSTRUCTION_DONE":82.0,"SPI":97.0}, 2020: {"GDP_GROWTH":-0.7,"UNEMPLOYMENT":4.0,"BASE_RATE":0.50,"CD_RATE":0.76,"CPI_GROWTH":0.5,"LEADING_INDEX":97.0,"GOVT_3Y":0.98,"GOVT_10Y":1.52,"CORP_AA":2.03,"CORP_BBB":5.25,"IPI":170.0,"EXPORT":512498,"IMPORT_AMT":467633,"USDKRW":1180,"M2":3070.2,"CSI":90.0,"KOSPI":2873,"IMPORT_PRICE":85.0,"DISHONOR_RATE":0.02,"HOUSING_PRICE":110.0,"HOUSEHOLD_DEBT":1723.0, "FACILITY_INVEST":100.0,"RETAIL_SALES":100.0,"CURRENT_ACCOUNT":752.8,"EMPLOYED":2630,"EMPLOYMENT_RATE":62.5,"OIL_PRICE":42.3,"COINCIDENT":97.5,"BSI_MANUF":76,"CONSTRUCTION_DONE":79.0,"SPI":100.0}, 2021: {"GDP_GROWTH":4.3,"UNEMPLOYMENT":3.7,"BASE_RATE":1.00,"CD_RATE":1.09,"CPI_GROWTH":2.5,"LEADING_INDEX":102.8,"GOVT_3Y":1.43,"GOVT_10Y":2.12,"CORP_AA":2.26,"CORP_BBB":5.64,"IPI":183.0,"EXPORT":644400,"IMPORT_AMT":615093,"USDKRW":1144,"M2":3415.8,"CSI":106.0,"KOSPI":2978,"IMPORT_PRICE":110.5,"DISHONOR_RATE":0.01,"HOUSING_PRICE":122.0,"HOUSEHOLD_DEBT":1853.0, "FACILITY_INVEST":108.5,"RETAIL_SALES":105.0,"CURRENT_ACCOUNT":883.0,"EMPLOYED":2672,"EMPLOYMENT_RATE":63.8,"OIL_PRICE":69.3,"COINCIDENT":103.0,"BSI_MANUF":96,"CONSTRUCTION_DONE":77.5,"SPI":104.5}, 2022: {"GDP_GROWTH":2.6,"UNEMPLOYMENT":2.9,"BASE_RATE":3.25,"CD_RATE":3.77,"CPI_GROWTH":5.1,"LEADING_INDEX":99.2,"GOVT_3Y":3.14,"GOVT_10Y":3.60,"CORP_AA":4.25,"CORP_BBB":8.18,"IPI":186.5,"EXPORT":683585,"IMPORT_AMT":731370,"USDKRW":1292,"M2":3561.0,"CSI":95.0,"KOSPI":2237,"IMPORT_PRICE":140.2,"DISHONOR_RATE":0.02,"HOUSING_PRICE":128.0,"HOUSEHOLD_DEBT":1903.0, "FACILITY_INVEST":105.0,"RETAIL_SALES":107.5,"CURRENT_ACCOUNT":258.3,"EMPLOYED":2726,"EMPLOYMENT_RATE":64.5,"OIL_PRICE":97.0,"COINCIDENT":100.5,"BSI_MANUF":85,"CONSTRUCTION_DONE":76.0,"SPI":108.0}, 2023: {"GDP_GROWTH":1.4,"UNEMPLOYMENT":2.7,"BASE_RATE":3.50,"CD_RATE":3.75,"CPI_GROWTH":3.6,"LEADING_INDEX":98.8,"GOVT_3Y":3.55,"GOVT_10Y":3.78,"CORP_AA":4.40,"CORP_BBB":8.40,"IPI":183.0,"EXPORT":632744,"IMPORT_AMT":642756,"USDKRW":1305,"M2":3680.0,"CSI":96.5,"KOSPI":2655,"IMPORT_PRICE":120.0,"DISHONOR_RATE":0.03,"HOUSING_PRICE":118.0,"HOUSEHOLD_DEBT":1920.0, "FACILITY_INVEST":102.0,"RETAIL_SALES":106.0,"CURRENT_ACCOUNT":355.2,"EMPLOYED":2750,"EMPLOYMENT_RATE":65.0,"OIL_PRICE":82.5,"COINCIDENT":99.2,"BSI_MANUF":80,"CONSTRUCTION_DONE":72.0,"SPI":109.5}, 2024: {"GDP_GROWTH":2.2,"UNEMPLOYMENT":2.8,"BASE_RATE":3.00,"CD_RATE":3.30,"CPI_GROWTH":2.3,"LEADING_INDEX":99.5,"GOVT_3Y":3.20,"GOVT_10Y":3.42,"CORP_AA":3.90,"CORP_BBB":7.50,"IPI":185.0,"EXPORT":660000,"IMPORT_AMT":650000,"USDKRW":1350,"M2":3800.0,"CSI":98.0,"KOSPI":2400,"IMPORT_PRICE":115.0,"DISHONOR_RATE":0.03,"HOUSING_PRICE":115.0,"HOUSEHOLD_DEBT":1950.0, "FACILITY_INVEST":103.5,"RETAIL_SALES":105.5,"CURRENT_ACCOUNT":380.0,"EMPLOYED":2760,"EMPLOYMENT_RATE":65.2,"OIL_PRICE":80.0,"COINCIDENT":99.5,"BSI_MANUF":82,"CONSTRUCTION_DONE":68.0,"SPI":110.0}, 2025: {"GDP_GROWTH":1.8,"UNEMPLOYMENT":3.0,"BASE_RATE":2.75,"CD_RATE":3.00,"CPI_GROWTH":1.8,"LEADING_INDEX":99.8,"GOVT_3Y":2.80,"GOVT_10Y":3.10,"CORP_AA":3.50,"CORP_BBB":6.80,"IPI":184.0,"EXPORT":650000,"IMPORT_AMT":640000,"USDKRW":1380,"M2":3900.0,"CSI":99.0,"KOSPI":2500,"IMPORT_PRICE":110.0,"DISHONOR_RATE":0.03,"HOUSING_PRICE":112.0,"HOUSEHOLD_DEBT":1980.0, "FACILITY_INVEST":104.0,"RETAIL_SALES":106.0,"CURRENT_ACCOUNT":350.0,"EMPLOYED":2770,"EMPLOYMENT_RATE":65.5,"OIL_PRICE":75.0,"COINCIDENT":100.0,"BSI_MANUF":84,"CONSTRUCTION_DONE":65.0,"SPI":111.0}, } # fmt: on return pd.DataFrame(data).T.rename_axis("YEAR") def fetch_and_cache(force=False, no_api=False): """ECOS에서 가져오거나 캐시 반환""" CACHE_DIR.mkdir(parents=True, exist_ok=True) if CACHE_FILE.exists() and not force: print(f" 캐시 로딩: {CACHE_FILE}") df = pd.read_csv(CACHE_FILE, index_col="YEAR") print(f" 변수: {len(df.columns)}개, 연도: {df.index.min()}~{df.index.max()}") return df if no_api: print(" API 없이 fallback 사용") df = _build_fallback() df.to_csv(CACHE_FILE) print(f" 캐시 저장: {CACHE_FILE} ({len(df.columns)}개 변수)") return df # ECOS API 수집 print(" ECOS API에서 데이터 수집 중...") # TODO: API 실제 호출 구현 (config.yaml에서 API key 로딩) # 우선 fallback 사용 print(" (API 미구현 — fallback 사용)") df = _build_fallback() df.to_csv(CACHE_FILE) print(f" 캐시 저장: {CACHE_FILE} ({len(df.columns)}개 변수)") return df def load_macro_data(start_year=2000, end_year=2025) -> pd.DataFrame: """메인 파이프라인용 거시데이터 로딩""" if CACHE_FILE.exists(): df = pd.read_csv(CACHE_FILE, index_col="YEAR") else: df = _build_fallback() CACHE_DIR.mkdir(parents=True, exist_ok=True) df.to_csv(CACHE_FILE) return df.loc[start_year:end_year] if __name__ == "__main__": parser = argparse.ArgumentParser(description="ECOS 거시경제변수 수집기") parser.add_argument("--force", action="store_true", help="캐시 무시하고 재수집") parser.add_argument("--no-api", action="store_true", help="API 없이 fallback만 사용") args = parser.parse_args() print("=" * 60) print(" ECOS 거시경제변수 수집기") print("=" * 60) df = fetch_and_cache(force=args.force, no_api=args.no_api) print(f"\n === 변수 목록 ({len(df.columns)}개) ===") for col in df.columns: vals = df[col].dropna() print(f" {col:25s} | {vals.min():>12.2f} ~ {vals.max():>12.2f} | {len(vals)} obs") print(f"\n === 최근 5년 ===") print(df.tail())