
금융 데이터 분석에 있어서 Python은 강력한 도구입니다. 특히 pandas
와 yfinance
라이브러리를 조합하면 주식 시장 데이터를 손쉽게 가져와서 분석할 수 있습니다. 이번 포스트에서는 이 도구들을 활용하여 삼성전자와 마이크로소프트의 주가 데이터를 가져오고 분석하는 방법에 대해 알아보겠습니다.
필요한 라이브러리 설치하기
시작하기 전에 필요한 라이브러리를 설치해야 합니다:
pip install pandas pandas-datareader yfinance matplotlib
yfinance 라이브러리 소개
yfinance
는 Yahoo Finance에서 금융 데이터를 쉽게 다운로드할 수 있게 해주는 라이브러리입니다. 이전에는 pandas-datareader
가 Yahoo Finance API를 직접 사용했지만, API 변경으로 인해 이제는 yfinance
를 통해 데이터를 가져오는 것이 더 안정적입니다.
yfinance의 주요 기능
- 주식 기본 데이터 조회: 주가, 거래량, 배당금 등
- 기업 재무제표 데이터: 수익, 자산, 부채 등
- 주식 분할 및 배당금 정보
- 옵션 체인 데이터
- 기업 기본 정보
기본 주가 데이터 가져오기
yfinance
와 pandas-datareader
를 사용하여 삼성전자(005930.KS)와 마이크로소프트(MSFT)의 주가 데이터를 가져오는 코드부터 시작해 보겠습니다:
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override()
# 삼성전자(005930) 2018년 5월 4일부터 현재까지의 데이터 가져오기
sec = pdr.get_data_yahoo('005930.KS', start='2018-05-04')
msft = pdr.get_data_yahoo('MSFT', start='2018-05-04')
Upgrade (2025.05.11)
import yfinance as yf
# Get data directly using yf.download
sec = yf.download('005930.KS', start='2018-05-04')
msft = yf.download('MSFT', start='2018-05-04')
실행하면 다음과 같은 진행 상황이 표시됩니다:
[*********************100%***********************] 1 of 1 completed
[*********************100%***********************] 1 of 1 completed
데이터 구조 살펴보기
yfinance로 가져온 데이터의 구조
yfinance
를 통해 가져온 데이터는 pandas DataFrame 형태로 제공됩니다. 이 DataFrame은 다음과 같은 열로 구성됩니다:
- Open: 시가
- High: 고가
- Low: 저가
- Close: 종가
- Adj Close: 수정 종가 (배당금, 주식 분할 등을 반영)
- Volume: 거래량
아래 코드로 삼성전자의 처음 10개 행을 확인해 봅시다:
print(sec.head(10))
출력 결과:
Open High Low Close Adj Close Volume
Date
2018-05-04 53000.0 53900.0 51800.0 51900.0 46191.074219 39565391
2018-05-08 52600.0 53200.0 51900.0 52600.0 46814.070312 23104720
2018-05-09 52600.0 52800.0 50900.0 50900.0 45301.074219 16128305
2018-05-10 51700.0 51700.0 50600.0 51600.0 45924.066406 13905263
2018-05-11 52000.0 52200.0 51200.0 51300.0 45657.078125 10314997
2018-05-14 51000.0 51100.0 49900.0 50100.0 44589.066406 14909272
2018-05-15 50200.0 50400.0 49100.0 49200.0 43788.066406 18709146
2018-05-16 49200.0 50200.0 49150.0 49850.0 44366.574219 15918683
2018-05-17 50300.0 50500.0 49400.0 49400.0 43966.070312 10365440
2018-05-18 49900.0 49900.0 49350.0 49500.0 44055.070312 6706570
마이크로소프트의 마지막 5개 행을 확인해 보겠습니다 (거래량 제외):
tmp_msft = msft.drop(columns='Volume')
print(tmp_msft.tail())
출력 결과:
Open High Low Close Adj Close
Date
2022-02-14 293.769989 296.760010 291.350006 295.000000 294.391296
2022-02-15 300.010010 300.799988 297.019989 300.470001 299.850006
2022-02-16 298.369995 300.869995 293.679993 299.500000 299.500000
2022-02-17 296.359985 296.799988 290.000000 290.730011 290.730011
2022-02-18 293.049988 293.859985 286.309998 287.929993 287.929993
DataFrame의 기본 구조 탐색
DataFrame의 인덱스와 컬럼 정보를 확인해 봅시다:
print(sec.index)
출력 결과:
DatetimeIndex(['2018-05-04', '2018-05-08', '2018-05-09', '2018-05-10',
'2018-05-11', '2018-05-14', '2018-05-15', '2018-05-16',
'2018-05-17', '2018-05-18',
...
'2022-02-09', '2022-02-10', '2022-02-11', '2022-02-14',
'2022-02-15', '2022-02-16', '2022-02-17', '2022-02-18',
'2022-02-21', '2022-02-22'],
dtype='datetime64[ns]', name='Date', length=935, freq=None)
print(sec.columns)
출력 결과:
Index(['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'], dtype='object')
데이터 분석과 가공
yfinance로 가져온 데이터는 표준 pandas DataFrame이므로, pandas의 모든 기능을 활용하여 다양한 분석과 가공이 가능합니다.
기본 통계 정보 확인하기
# 기본 통계 정보
print(sec.describe())
출력 결과:
Open High Low Close Adj Close Volume
count 935.000000 935.000000 935.000000 935.000000 935.000000 9.350000e+02
mean 62272.486631 62991.168984 61518.237433 62257.593583 59424.953440 1.862924e+07
std 14584.926127 14672.183335 14504.968421 14614.022756 15599.916985 1.061837e+07
min 41550.000000 42300.000000 41000.000000 41800.000000 41800.000000 3.157900e+06
25% 51300.000000 51900.000000 50800.000000 51400.000000 48127.427734 1.197267e+07
50% 58000.000000 58600.000000 57400.000000 58000.000000 54653.832031 1.573842e+07
75% 73800.000000 74500.000000 72900.000000 73500.000000 70732.031250 2.211126e+07
max 92000.000000 92800.000000 90100.000000 91000.000000 91000.000000 1.188622e+08
이동평균 계산하기
주가 분석에서 자주 사용되는 이동평균을 계산해 봅시다:
# 20일, 60일 이동평균 계산하기
sec['MA20'] = sec['Close'].rolling(window=20).mean()
sec['MA60'] = sec['Close'].rolling(window=60).mean()
print(sec[['Close', 'MA20', 'MA60']].tail(10))
출력 결과:
Close MA20 MA60
Date
2022-02-09 75200.0 75675.0000 74991.6667
2022-02-10 75300.0 75455.0000 74893.3333
2022-02-11 74800.0 75240.0000 74788.3333
2022-02-14 73900.0 74975.0000 74670.0000
2022-02-15 74500.0 74755.0000 74605.0000
2022-02-16 73500.0 74490.0000 74513.3333
2022-02-17 72300.0 74160.0000 74386.6667
2022-02-18 72300.0 73875.0000 74286.6667
2022-02-21 72300.0 73625.0000 74193.3333
2022-02-22 71700.0 73360.0000 74080.0000
일별 수익률 계산하기
# 일별 수익률 계산하기
sec['Daily Return'] = sec['Close'].pct_change() * 100
print(sec[['Close', 'Daily Return']].tail())
출력 결과:
Close Daily Return
Date
2022-02-16 73500.0 -1.342282
2022-02-17 72300.0 -1.632653
2022-02-18 72300.0 0.000000
2022-02-21 72300.0 0.000000
2022-02-22 71700.0 -0.829876
데이터 시각화하기
matplotlib을 사용하여 주가 데이터를 시각화해 봅시다:
import matplotlib.pyplot as plt
import yfinance as yf
# Get data directly using yf.download
sec = yf.download('005930.KS', start='2018-05-04')
msft = yf.download('MSFT', start='2018-05-04')
plt.figure(figsize=(12, 6))
plt.plot(sec.index, sec.Close, 'b', label='Samsung Electronics')
plt.plot(msft.index, msft.Close, 'r--', label='Microsoft')
plt.title('Stock Price Comparison: Samsung vs Microsoft')
plt.xlabel('Date')
plt.ylabel('Price (Local Currency)')
plt.legend(loc='best')
plt.grid(True)
plt.show()

위 그래프는 2018년 5월부터 현재까지 삼성전자와 마이크로소프트의 종가를 비교한 것입니다. 삼성전자는 원화로, 마이크로소프트는 달러로 표시되어 있어 직접적인 비교는 어렵지만, 각 회사의 가격 추세를 확인할 수 있습니다.
좀 더 의미 있는 비교를 위해 두 회사의 주가를 첫 날 가격 대비 상대적 변화로 정규화해 봅시다:
import matplotlib.pyplot as plt
import yfinance as yf
# Get data directly using yf.download
sec = yf.download('005930.KS', start='2018-05-04')
msft = yf.download('MSFT', start='2018-05-04')
sec_norm = sec.Close / sec.Close.iloc[0] * 100
msft_norm = msft.Close / msft.Close.iloc[0] * 100
plt.figure(figsize=(12, 6))
plt.plot(sec.index, sec_norm, 'b', label='Samsung Electronics')
plt.plot(msft.index, msft_norm, 'r--', label='Microsoft')
plt.title('Normalized Stock Performance (First day = 100)')
plt.xlabel('Date')
plt.ylabel('Normalized Price')
plt.legend(loc='best')
plt.grid(True)
plt.show()

이제 두 회사의 상대적 성과를 더 명확하게 비교할 수 있습니다. 마이크로소프트가 해당 기간 동안 삼성전자보다 더 높은 성장률을 보인 것을 확인할 수 있습니다.
거래량 분석하기
거래량도 중요한 지표입니다. 삼성전자의 거래량을 시각화해 봅시다:
import matplotlib.pyplot as plt
import yfinance as yf
import pandas as pd
# 데이터 다운로드
sec = yf.download('005930.KS', start='2025-04-01')
# 그래프 생성
fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, figsize=(12, 10))
# 종가 그래프
sec['Close'].plot(ax=ax1)
ax1.set_title('Samsung Electronics Stock Price')
ax1.set_ylabel('Price (KRW)')
ax1.grid(True)
# 거래량 그래프 - width 파라미터 추가
sec['Volume'].plot(kind='bar', ax=ax2, color='g', alpha=0.5, width=1.0)
ax2.set_title('Trading Volume')
ax2.set_ylabel('Volume')
ax2.grid(True)
# x축 레이블 조정
ax2.set_xticklabels(sec.index.strftime('%Y-%m-%d'), rotation=45)
# 바 그래프의 x축 범위 조정
ax2.set_xlim(-1, len(sec))
plt.tight_layout()
plt.show()

이 그래프에서 주가 변동과 거래량 사이의 관계를 볼 수 있습니다. 일반적으로 중요한 가격 변동은 높은 거래량과 함께 나타나는 경향이 있습니다.
yfinance를 사용한 추가 정보 수집
yfinance
는 주가 데이터 외에도 회사의 기본 정보, 재무제표 등 다양한 정보를 제공합니다. 삼성전자에 대한 추가 정보를 살펴봅시다:
# Ticker 객체 생성
samsung = yf.Ticker('005930.KS')
# 회사 기본 정보
print(samsung.info['longName']) # 회사명
print(samsung.info['sector']) # 섹터
print(samsung.info['industry']) # 산업
# 최근 뉴스
print(samsung.news)
# 주요 주주 정보
print(samsung.institutional_holders)
# 재무제표 요약
print(samsung.financials)
기술적 분석 지표 계산하기
투자 분석에 자주 사용되는 몇 가지 기술적 분석 지표를 계산해 봅시다:
import matplotlib.pyplot as plt
import yfinance as yf
import pandas as pd
# 데이터 다운로드
sec = yf.download('005930.KS', start='2018-05-04')
msft = yf.download('MSFT', start='2018-05-04')
# RSI(Relative Strength Index) 계산 함수
def compute_rsi(data, window=14):
diff = data.diff()
up = diff.clip(lower=0)
down = -1 * diff.clip(upper=0)
ma_up = up.rolling(window=window).mean()
ma_down = down.rolling(window=window).mean()
rsi = ma_up / (ma_up + ma_down) * 100
return rsi
# 볼린저 밴드 계산
sec['MA20'] = sec['Close'].rolling(window=20).mean() # 20일 이동평균
sec['Std20'] = sec['Close'].rolling(window=20).std() # 20일 표준편차
sec['Upper'] = sec['MA20'] + (sec['Std20'] * 2) # 상단 밴드
sec['Lower'] = sec['MA20'] - (sec['Std20'] * 2) # 하단 밴드
# RSI 계산
sec['RSI'] = compute_rsi(sec['Close'])
# 볼린저 밴드 시각화
plt.figure(figsize=(12, 6))
plt.plot(sec.index, sec.Close, 'b', label='Close')
plt.plot(sec.index, sec.MA20, 'k--', label='MA20')
plt.plot(sec.index, sec.Upper, 'r-', label='Upper Band')
plt.plot(sec.index, sec.Lower, 'g-', label='Lower Band')
plt.fill_between(sec.index, sec.Upper, sec.Lower, color='lightgray', alpha=0.4)
plt.title('Bollinger Bands for Samsung Electronics')
plt.legend(loc='best')
plt.grid(True)
plt.show()

여러 회사 한번에 데이터 가져오기
여러 회사의 데이터를 한 번에 가져오려면 다음과 같이 할 수 있습니다:
import matplotlib.pyplot as plt
import yfinance as yf
import pandas as pd
# 여러 회사의 티커 리스트
tickers = ['005930.KS', 'MSFT', 'GOOG', 'AAPL']
# 데이터 가져오기
data = yf.download(tickers, start='2020-01-01')
# 종가 데이터만 선택
close_data = data['Close']
# 시각화
plt.figure(figsize=(14, 7))
for ticker in tickers:
plt.plot(close_data.index, close_data[ticker]/close_data[ticker].iloc[0]*100, label=ticker)
plt.title('Stock Performance Comparison (2020-01-01 = 100)')
plt.xlabel('Date')
plt.ylabel('Normalized Price (%)')
plt.legend()
plt.grid(True)
plt.show()

결론
이 포스트에서는 pandas
와 yfinance
를 사용하여 주식 데이터를 가져오고 분석하는 기본적인 방법을 살펴보았습니다. 이러한 도구들을 통해 주가 데이터를 다양한 방식으로 시각화하고 분석할 수 있습니다.
Python의 강력한 데이터 분석 라이브러리를 활용하면, 복잡한 금융 분석도 몇 줄의 코드로 쉽게 수행할 수 있습니다. 더 나아가 머신러닝 기법을 접목하여 주가 예측 모델을 만들거나, 포트폴리오 최적화 알고리즘을 구현할 수도 있습니다.