미국주식을 투자하기 전에 파이썬으로 해보고 싶은 게 있다. 그래서 새해부터 제미나이를 잡도리하는 중이다. 작업별로 필요한 라이브러리를 정리해본다.
파이썬은 데이터 수집부터 분석, 모델링까지 금융 공학에 최적화된 생태계를 갖추고 있습니다. 요청하신 기간별(월간/주간 vs 일간) 목적에 맞춰 가장 신뢰할 수 있고 널리 쓰이는 라이브러리들을 정리해 드립니다.
1. 기본 데이터 수집 (공통 필수)
모든 분석의 기초가 되는 주가 데이터(OHLCV)와 재무 데이터를 가져오는 라이브러리입니다.
- yfinance: 야후 파이낸스 데이터를 무료로 가져오는 가장 대중적인 라이브러리입니다. 사용법이 매우 간단하여 빠르게 데이터를 확보하는 데 최적입니다.
- 용도: 일간 주가, 시가총액, 기본 재무제표 데이터 수집.
2. 포트폴리오 모델 구축 (월간/주간 기준)
자산 배분 전략을 수립하고 리밸런싱 비율을 계산하기 위한 라이브러리입니다.
- PyPortfolioOpt: 포트폴리오 최적화를 위한 최고의 라이브러리입니다.
- 기능: 평균-분산 최적화(Mean-Variance Optimization), 샤프 지수 최대화, 블랙-리터만(Black-Litterman) 모델, 리스크 패리티(Risk Parity) 등을 지원합니다.
- 활용: 월간 기준으로 '효율적 투자선(Efficient Frontier)'을 계산하여 종목별 최적 비중을 산출할 때 사용합니다.
- Riskfolio-Lib: PyPortfolioOpt보다 더 시각적이고 다양한 리스크 관리 지표를 제공합니다.
- 기능: CVaR, CDaR 등 꼬리 위험(Tail Risk)을 고려한 포트폴리오 구성에 강점이 있습니다.
3. 기술적 분석 (일간 기준)
매일의 주가 흐름을 분석하여 매매 타이밍을 잡기 위한 지표 계산 라이브러리입니다.
- Pandas-TA: 데이터프레임(Pandas)과 완벽하게 호환되는 기술적 분석 라이브러리입니다.
- 기능: RSI, MACD, 볼린저 밴드 등 수백 개의 지표를
df.ta.rsi()와 같이 한 줄의 코드로 계산할 수 있습니다. - 장점: 사용하기 쉽고 직관적입니다.
- TA-Lib: C언어로 작성되어 연산 속도가 매우 빠르고 업계 표준으로 불립니다.
- 주의: 설치가 다소 까다로울 수 있으나 대량의 데이터를 빠르게 처리해야 한다면 필수적입니다.
4. 뉴스 및 감성 분석 (일간 기준)
뉴스 텍스트를 수집하고 긍정/부정을 판단하는 AI 모델링 라이브러리입니다.
- GoogleNews / Feedparser: 특정 키워드(예: 'Tesla', 'Earnings')에 대한 최신 뉴스를 크롤링합니다.
- Transformers (Hugging Face) + FinBERT: 단순한 단어 매칭이 아닌, 문맥을 이해하는 딥러닝 모델입니다.
- 핵심: 'ProsusAI/finbert'와 같은 금융 특화 사전 학습 모델을 사용하면 뉴스 헤드라인이 주가에 긍정적인지 부정적인지 점수(Sentiment Score)로 산출해 줍니다.
💡 추천 워크플로우 예시
이 라이브러리들을 조합하여 구축할 수 있는 시스템의 구조는 다음과 같습니다.
| 주기 | 단계 | 사용 라이브러리 | 수행 작업 |
|---|---|---|---|
| 일간 (Daily) | 1. 데이터 수집 | yfinance |
장 마감 후 미국 주식 데이터 수집 |
| 2. 기술적 분석 | pandas-ta |
RSI < 30 (과매도) 등 매수 시그널 포착 | |
| 3. 뉴스 분석 | GoogleNews + Transformers |
보유 종목 관련 악재 뉴스 감지 (Risk Alert) | |
| 월간 (Monthly) | 4. 포트폴리오 | PyPortfolioOpt |
지난달 수익률 기반 최적 비중 재산출 (리밸런싱) |
💻 간단한 코드 예시 (기술적 분석 + 포트폴리오)
가장 활용도가 높은 yfinance와 PyPortfolioOpt를 연동하는 간단한 예시입니다.
import yfinance as yf
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models, expected_returns
tickers = ["AAPL", "MSFT", "GOOG", "TSLA"]
# auto_adjust=False를 추가하여 'Adj Close' 칼럼을 강제로 가져옵니다.
data = yf.download(tickers, period="1y", interval="1wk", auto_adjust=False)
# 데이터가 제대로 받아졌는지 확인 (비어있다면 티커 문제나 네트워크 문제)
if data.empty:
print("데이터를 다운로드하지 못했습니다. 티커명을 확인하거나 잠시 후 다시 시도하세요.")
else:
# 이제 'Adj Close'가 확실히 존재합니다.
ohlc = data["Adj Close"]
# 이후 과정 동일
mu = expected_returns.mean_historical_return(ohlc)
S = risk_models.sample_cov(ohlc)
ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe()
cleaned_weights = ef.clean_weights()
print("추천 포트폴리오 비중:", cleaned_weights)yf.download 함수에서 period와 interval매개변수가 있는데, period 매개변수는 "현재(오늘)를 기준으로 과거 얼마 동안의 데이터를 가져올 것인가"를 결정하는 기간 설정 옵션입니다.
쉽게 말해, "지금부터 뒤로 1년 치(1y) 줘" 또는 "상장된 이후 전체(max) 다 줘"라고 명령하는 것입니다.
1. 사용 가능한 옵션 (코드값)
문자열 형태로 입력하며, 자주 쓰이는 값들은 다음과 같습니다.
| 코드값 | 의미 | 설명 |
|---|---|---|
1d, `5d` |
1일, 5일 | 최근 며칠간의 짧은 데이터 |
1mo, 3mo, `6mo` |
1개월, 3개월, 6개월 | 단기~중기 추세 분석용 (mo는 month) |
ytd |
Year To Date | 올해 1월 1일부터 오늘까지 (연초 대비 수익률 계산 시 유용) |
1y, 2y, 5y, `10y` |
1년, 2년, 5년, 10년 | 장기 투자 및 백테스팅용 |
max |
최대 기간 | 해당 종목의 상장일부터 오늘까지 모든 데이터 |
2. 코드 예시
import yfinance as yf
# 1. 최근 1개월 데이터 (단기 분석)
data_short = yf.download("AAPL", period="1mo")
# 2. 최근 10년 데이터 (장기 백테스팅)
data_long = yf.download("AAPL", period="10y")
# 3. 전체 데이터 (상장 이후 모든 역사)
data_all = yf.download("AAPL", period="max")
3. 헷갈리기 쉬운 점: period vs start/end
yf.download 함수는 기간을 설정하는 두 가지 방법이 있는데, 둘 중 하나만 써야 합니다.
period사용 (상대적 기간):- "오늘부터 1년 전까지 줘."
- 매일 실행할 때마다 데이터의 범위가 자동으로 업데이트됩니다. (자동화 봇에 적합)
- 예:
period="1y"
start/end사용 (절대적 기간):- "2020년 1월 1일부터 2020년 12월 31일까지 딱 정해서 줘."
- 특정 과거 시점을 분석할 때 사용합니다.
- 예:
start="2020-01-01", end="2020-12-31"
⚠️ 주의:
period를 설정하면서start나end를 같이 쓰면, 보통period는 무시되거나 에러가 날 수 있으니 둘 중 한 방식만 선택하세요.
💡 팁: interval (데이터 간격)과의 관계
period는 전체 길이를 정하고, interval은 그 안에서 데이터 하나하나의 간격을 정합니다.
period="1d"(하루 치)를 부르면서interval을 설정 안 하면(기본값 1일), 달랑 1줄만 나옵니다.- 하루 치 데이터를 쪼개서 보고 싶다면
interval을 분 단위로 바꿔야 합니다.
# 하루(1d) 동안의 주가 흐름을 5분(5m) 간격으로 쪼개서 가져오기
day_data = yf.download("AAPL", period="1d", interval="5m")
interval 매개변수는 데이터 하나하나의 시간 간격(Bar Size)을 결정합니다.
yfinance에서 사용할 수 있는 코드값은 분(Minute), 시간(Hour), 일(Day), 주(Week), 월(Month) 단위로 나뉩니다.
1. 사용 가능한 코드값 목록
| 단위 | 코드값 | 설명 | 주로 쓰는 용도 |
|---|---|---|---|
| 분 (Minute) | 1m, 2m, 5m, 15m, 30m, `90m` |
1분봉, 5분봉 등 | 데이트레이딩, 스캘핑, 단기 패턴 분석 |
| 시간 (Hour) | 1h |
1시간봉 | 장중 추세 확인 (60m와 동일) |
| 일 (Day) | 1d, `5d` |
일봉 (1d가 기본값) |
스윙 트레이딩, 일반적인 기술적 분석 |
| 주 (Week) | 1wk |
주봉 | 중장기 추세 확인 |
| 월 (Month) | 1mo, `3mo` |
월봉 | 장기 투자, 포트폴리오 리밸런싱 |
⚠️ 주의 (가장 많이 하는 실수):
1m은 1분(Minute)입니다.1mo는 1개월(Month)입니다.m뒤에o를 붙이냐 마느냐로 결과가 완전히 달라지니 주의하세요!
2. 중요 제약 사항 (기간 제한)
야후 파이낸스는 데이터 용량 문제로 간격이 짧을수록 과거 데이터를 가져올 수 있는 기간(period)에 제한을 둡니다.
1m(1분봉): 최근 7일 이내 데이터만 조회 가능- 그 외 분봉 (
2m~90m): 최근 60일 이내 데이터만 조회 가능 1h(1시간봉): 최근 730일(약 2년) 이내 데이터만 조회 가능
예시 (에러 발생하는 경우):
# 에러 발생! (1분봉으로 1년 치를 달라고 하면 안 됨)
data = yf.download("AAPL", period="1y", interval="1m")
# 올바른 예 (1분봉은 최근 5일 정도만 요청)
data = yf.download("AAPL", period="5d", interval="1m")
3. 상황별 추천 조합
사용자님의 목적(포트폴리오 vs 일간 분석)에 맞춘 추천 조합입니다.
A. 포트폴리오 모델링 (월간 기준)
가장 큰 흐름을 봐야 하므로 월봉을 사용합니다.
# 지난 5년간의 월봉 데이터 (매월 말 주가 기준)
pf_data = yf.download("AAPL", period="5y", interval="1mo")
B. 스윙 트레이딩 / 기술적 분석 (일간 기준)
가장 표준적인 일봉 분석입니다.
# 지난 1년간의 일봉 데이터
daily_data = yf.download("AAPL", period="1y", interval="1d")
C. 데이트레이딩 / 봇 개발 (장중 기준)
장중의 디테일한 움직임을 포착합니다.
# 최근 5일간의 15분봉 데이터
intraday_data = yf.download("AAPL", period="5d", interval="15m")