Skip to main content

주가 데이터 가져오기

Views 377약 7분생성형 AI 활용
Summary

데이터 수집은 퀀트 투자의 출발점이다

퀀트 투자는 거창한 수학 공식에서 시작하지 않는다. 먼저 데이터를 가져와야 한다. 가격이 언제, 얼마에 시작했고, 어디까지 올랐고, 어디까지 떨어졌고, 마지막에 얼마로 끝났는지 확인해야 한다. 그다음 수익률을 계산하고, 변동성을 보고, 전략을 실험한다.

이번 장의 목표는 단순하다.

파이썬으로 해외 주식과 한국 주식 데이터를 가져오고, 저장하고, 다시 불러오는 기본 흐름을 익힌다. 이후 장에서 이동평균선, 모멘텀, 가치 전략, 머신러닝 모델을 만들 때 모두 이 데이터가 출발점이 된다.

주가 데이터 가져오기AI 생성 이미지

OHLCV: 주가 데이터의 기본 언어

주가 데이터를 가져오면 보통 다음과 같은 열을 만난다.

항목의미
Open시가. 그날 처음 거래된 가격
High고가. 그날 가장 높았던 가격
Low저가. 그날 가장 낮았던 가격
Close종가. 그날 마지막에 형성된 가격
Volume거래량. 그날 거래된 주식 수
Adj Close수정종가. 배당, 액면분할 등을 반영해 조정한 가격

이 다섯 가지를 묶어 OHLCV라고 부른다. Open, High, Low, Close, Volume의 첫 글자를 딴 말이다.

처음에는 종가만 봐도 충분해 보인다. 하지만 전략을 만들다 보면 다른 열도 필요해진다. 예를 들어 장중 변동성을 보려면 고가와 저가가 필요하다. 거래대금이나 유동성을 확인하려면 거래량이 필요하다. 시가에 매수하는 전략과 종가에 매수하는 전략은 결과가 달라질 수 있다.

또 하나 중요한 개념이 수정주가다. 주식은 배당, 액면분할, 병합 같은 이벤트를 겪는다. 예를 들어 1주가 2주로 나뉘는 액면분할이 발생하면 주가는 기계적으로 절반 가까이 낮아진다. 이때 단순 종가만 보면 큰 폭락처럼 보일 수 있다. 실제 투자 손실이 아닌데도 데이터상으로는 손실처럼 계산되는 것이다.

그래서 수익률 분석에는 가능하면 수정 가격을 확인해야 한다. 특히 장기 백테스트에서는 수정주가 사용 여부가 결과를 크게 바꾼다. 단, 데이터 제공원마다 수정 방식이 다를 수 있다. 가격은 수정되어 있지만 거래량은 수정되지 않는 경우도 있다. 따라서 백테스트를 시작하기 전에 "어떤 가격 열을 사용했는가"를 반드시 기록해야 한다.

일봉, 주봉, 월봉

주가 데이터는 시간 단위에 따라 다르게 불린다.

일봉은 하루를 한 줄로 정리한 데이터다. 대부분의 초보 퀀트 실험은 일봉으로 충분하다. 주봉은 한 주를 한 줄로, 월봉은 한 달을 한 줄로 정리한 데이터다.

예를 들어 장기 모멘텀 전략은 매일매일의 움직임보다 월간 수익률을 보는 편이 더 자연스러울 수 있다. 반대로 단기 매매 전략은 일봉보다 더 짧은 5분봉, 15분봉 같은 장중 데이터가 필요할 수 있다.

하지만 시간 단위가 짧아질수록 데이터 품질 문제도 커진다. 누락된 봉, 거래 정지, 시간대 차이, 저장 용량 문제가 생긴다. 이 책에서는 먼저 일봉을 기준으로 전략을 만들고, 필요한 경우에만 더 짧은 데이터를 사용한다.

yfinance로 해외 주식 데이터 가져오기

해외 주식과 ETF 데이터를 가져올 때는 yfinance가 간단하다. 야후 파이낸스 데이터를 파이썬에서 쉽게 받을 수 있게 해주는 라이브러리다. 예를 들어 yf.download()를 사용하면 MSFT, AAPL, SPY 같은 미국 주식과 ETF 데이터를 가져올 수 있다.1

먼저 설치한다.

# 처음 한 번만 실행
!pip install yfinance

이제 마이크로소프트 데이터를 가져와 보자.

import yfinance as yf

msft = yf.download(
    'MSFT',
    start='2020-01-01',
    end='2024-12-31',
    auto_adjust=False
)

msft.head()

실행하면 날짜가 인덱스가 되고, 가격 정보가 열로 들어간 데이터프레임이 만들어진다.

msft.info()
msft.columns
msft.index

여기서 가장 먼저 확인할 것은 세 가지다.

첫째, 날짜 인덱스가 제대로 들어왔는가. 둘째, Open, High, Low, Close, Adj Close, Volume 같은 열이 있는가. 셋째, 결측치가 있는가.

msft.isna().sum()

이번에는 최근 1개월의 5분봉 데이터를 가져와 보자.

spy_5m = yf.download(
    'SPY',
    period='1mo',
    interval='5m'
)

spy_5m.tail()

period는 "최근 얼마 동안"을 뜻한다. interval은 데이터 간격이다. 1d는 일봉, 1wk는 주봉, 1mo는 월봉, 5m은 5분봉이다.

반대로 특정 기간을 지정하려면 start와 end를 쓴다.

qqq = yf.download(
    'QQQ',
    start='2021-01-01',
    end='2024-12-31'
)

qqq.tail()

주의할 점이 있다. 데이터 제공 도구에 따라 end 날짜가 포함되지 않는 방식으로 동작할 수 있다. 예를 들어 2024년 12월 31일까지 받고 싶다면 상황에 따라 end='2025-01-01'처럼 다음 날을 넣어야 할 수 있다. 항상 마지막 날짜를 직접 확인하자.

qqq.index.min(), qqq.index.max()

여러 종목의 수정종가를 한 번에 모을 수도 있다.

import pandas as pd

symbols = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'SPY']
prices = pd.DataFrame()

for symbol in symbols:
    data = yf.download(symbol, start='2020-01-01', end='2024-12-31', auto_adjust=False)
    prices[symbol] = data['Adj Close']

prices.head()

이렇게 만든 prices는 여러 종목의 수익률을 비교하거나 상관관계를 계산할 때 유용하다. 다음 장에서 바로 이런 분석을 해볼 것이다.

CSV로 저장하고 다시 불러오기

데이터를 매번 새로 다운로드할 필요는 없다. 같은 데이터를 반복해서 쓰려면 파일로 저장해두는 편이 좋다.

import os

os.makedirs('data/raw', exist_ok=True)

msft.to_csv('data/raw/MSFT_2020_2024.csv', encoding='utf-8-sig')

다시 불러올 때는 날짜 인덱스를 복원해야 한다.

msft_loaded = pd.read_csv(
    'data/raw/MSFT_2020_2024.csv',
    index_col=0,
    parse_dates=True
)

msft_loaded.head()

index_col=0은 첫 번째 열을 인덱스로 쓰겠다는 뜻이다. parse_dates=True는 날짜처럼 생긴 값을 날짜 자료형으로 바꾸겠다는 뜻이다.

저장할 때는 파일 이름에 종목, 기간, 데이터 종류를 넣는 습관이 좋다.

data/raw/MSFT_2020_2024_daily.csv
data/raw/SPY_2024_1mo_5m.csv
data/raw/KRX_005930_2020_2024_daily.csv

나중에 파일이 많아지면 이름만 보고도 어떤 데이터인지 알아야 한다.

FinanceDataReader로 한국 주식 데이터 가져오기

한국 주식은 FinanceDataReader를 쓰면 시작하기 쉽다. StockListing('KRX')로 KOSPI, KOSDAQ, KONEX 상장 종목 목록을 가져올 수 있고, DataReader()로 개별 종목의 OHLCV 데이터를 조회할 수 있다.2

설치한다.

!pip install finance-datareader

종목 목록을 가져온다.

import FinanceDataReader as fdr

krx = fdr.StockListing('KRX')
krx.head()

보통 Code, Name, Market 같은 열을 확인할 수 있다.

krx[['Code', 'Name', 'Market']].head()

이 목록은 매우 중요하다. 종목 코드는 데이터를 가져오는 열쇠이고, 종목명과 시장 구분은 나중에 결과를 해석하는 데 필요하다.

삼성전자 데이터를 가져와 보자.

samsung = fdr.DataReader('005930', '2020-01-01', '2024-12-31')
samsung.head()

한국 주식 코드는 문자열로 다루는 것이 안전하다. 005930을 숫자로 저장하면 앞의 0이 사라져 5930이 될 수 있다. 종목 코드는 계산할 숫자가 아니라 식별자다.

종목 목록도 저장해두자.

os.makedirs('data/universe', exist_ok=True)

krx[['Code', 'Name', 'Market']].to_csv(
    'data/universe/krx_listing.csv',
    index=False,
    encoding='utf-8-sig'
)

여기서 universe는 투자 후보군이라는 뜻이다. 백테스트에서 어떤 종목들을 대상으로 삼았는지 기록하는 폴더라고 생각하면 된다.

pykrx로 한국 시장 데이터 더 세밀하게 다루기

pykrx는 한국 시장에 특화된 데이터 수집 도구다. 특히 특정 날짜 기준 종목 코드 목록을 가져올 수 있다는 점이 중요하다.

설치한다.

!pip install pykrx

기본 사용법은 다음과 같다.

from pykrx import stock

# 최근 영업일 기준 종목 코드 목록
tickers_today = stock.get_market_ticker_list()

# 특정 날짜 기준 종목 코드 목록
tickers_20200102 = stock.get_market_ticker_list('20200102')

# 종목명 확인
stock.get_market_ticker_name('005930')

현재 종목 목록과 과거 특정 날짜의 종목 목록은 다르다. 2020년에 상장되어 있던 종목이 지금은 상장폐지되었을 수 있고, 지금 상장된 종목이 과거에는 없었을 수도 있다. 과거 백테스트에서 현재 상장 종목만 사용하면 살아남은 종목만 보는 문제가 생긴다. 이것이 생존자 편향이다.

개별 종목의 OHLCV 데이터는 다음처럼 가져온다.

samsung_px = stock.get_market_ohlcv_by_date(
    fromdate='20200101',
    todate='20241231',
    ticker='005930'
)

samsung_px.head()

반환되는 열 이름은 보통 한글이다.

시가, 고가, 저가, 종가, 거래량

필요하면 수정 여부를 조정할 수 있다.

samsung_raw = stock.get_market_ohlcv_by_date(
    fromdate='20200101',
    todate='20241231',
    ticker='005930',
    adjusted=False
)

수정주가를 쓸지, 비수정주가를 쓸지는 전략 목적에 따라 달라진다. 일반적인 수익률 백테스트에서는 수정 가격을 확인하는 편이 안전하다. 다만 거래량, 거래대금, 분할 이벤트까지 함께 쓰는 전략이라면 데이터가 어떤 방식으로 조정되었는지 더 꼼꼼히 봐야 한다.

여러 한국 종목을 반복 수집하는 기본 구조

이제 종목 목록을 이용해 여러 종목 데이터를 반복해서 가져와 보자. 모든 종목을 한 번에 수집하는 예제는 시간이 오래 걸릴 수 있으므로, 처음에는 5개만 테스트하는 것이 좋다. 전체 KRX 종목 목록을 돌면서 pykrx로 OHLCV를 수집하고, 종목명과 시장 구분을 붙여 하나의 데이터프레임으로 합치는 방식은 실무적인 수집 구조의 기본형이다.3

from pykrx import stock
import FinanceDataReader as fdr
import pandas as pd
from datetime import datetime
import os

krx = fdr.StockListing('KRX')

sample = krx[['Code', 'Name', 'Market']].head(5)

start_date = '20200101'
end_date = datetime.now().strftime('%Y%m%d')

frames = []

for _, row in sample.iterrows():
    code = row['Code']
    name = row['Name']
    market = row['Market']

    df = stock.get_market_ohlcv_by_date(start_date, end_date, code).reset_index()
    df['종목코드'] = code
    df['종목명'] = name
    df['시장'] = market

    frames.append(df)

price_all = pd.concat(frames, ignore_index=True)
price_all.head()

저장한다.

os.makedirs('data/raw', exist_ok=True)

price_all.to_csv(
    'data/raw/krx_sample_prices.csv',
    index=False,
    encoding='utf-8-sig'
)

이 구조를 확장하면 나만의 가격 데이터베이스를 만들 수 있다. 다만 전체 종목을 자주 반복 수집하면 시간이 오래 걸리고, 제공 서버에 부담을 줄 수 있다. 처음에는 소수 종목으로 테스트하고, 필요한 범위만 수집하자.

데이터 품질을 확인하는 습관

데이터를 가져왔다고 바로 전략을 만들면 안 된다. 먼저 품질을 확인해야 한다.

samsung_px.isna().sum()
samsung_px.index.duplicated().sum()
samsung_px.index.min(), samsung_px.index.max()

확인할 항목은 다음과 같다.

  • 결측치가 있는가

  • 날짜가 중복되어 있지 않은가

  • 시작일과 종료일이 의도한 범위와 맞는가

  • 비거래일이 자연스럽게 빠져 있는가

  • 종목 코드가 문자열로 보존되어 있는가

  • 가격 열이 수정주가인지 비수정주가인지 확인했는가

  • 데이터 제공원이 무엇인지 기록했는가

  • 현재 상장 종목만 사용해 과거를 테스트하고 있지는 않은가

비거래일은 결측치와 다르다. 주말과 공휴일에는 거래가 없으므로 데이터가 없는 것이 정상이다. 반면 거래일인데 특정 종목 데이터가 비어 있다면 확인이 필요하다.

또한 같은 종목이라도 제공원에 따라 가격이 조금 다를 수 있다. 수정주가 계산 방식, 배당 반영 여부, 상장폐지 종목 포함 여부가 다르기 때문이다. 그러므로 백테스트 보고서에는 최소한 다음 내용을 남겨야 한다.

데이터 출처: yfinance / FinanceDataReader / pykrx
수집일: 2026-05-20
대상 종목: KRX 전체 또는 특정 종목 리스트
기간: 2020-01-01 ~ 2024-12-31
가격 기준: 수정종가 / 종가 / adjusted=False 여부
수수료와 세금 반영 여부: 아직 반영 안 함

좋은 퀀트 투자는 멋진 모델보다 깨끗한 데이터에서 시작한다. 데이터가 잘못되면 수익률, 변동성, MDD, 샤프 비율도 모두 잘못된다. AI 모델을 붙여도 마찬가지다. 잘못된 데이터로 학습한 AI는 더 빠르게 틀릴 뿐이다.

이번 장의 핵심 정리

주가 데이터는 보통 OHLCV 구조로 제공된다. 수익률 분석에는 종가뿐 아니라 수정주가 사용 여부를 확인해야 한다. 해외 주식과 ETF는 yfinance로 빠르게 시작할 수 있고, 한국 주식은 FinanceDataReader와 pykrx를 함께 쓰면 편하다.

FinanceDataReader는 현재 상장 종목 목록과 개별 종목 데이터를 가져오기 쉽다. pykrx는 한국 시장에 특화되어 있고, 날짜 기준 종목 목록과 OHLCV 데이터를 다룰 때 유용하다.

마지막으로, 데이터를 저장하고 다시 불러오는 습관을 들이자. 종목 코드, 종목명, 시장 구분, 수집 기간, 데이터 출처를 함께 남겨야 한다. 이 기록이 있어야 나중에 백테스트 결과를 믿을 수 있다.

퀀트 투자의 첫 단계는 예측이 아니다. 데이터를 제대로 가져오는 것이다.

참고

1파이썬 주식 데이터 다운 및 표시

2파이썬을 이용한 한국주식(코스피, 코스닥) 주가 데이터 수집 - FinanceDataReader, pykrx, pandas_datareader, yfinance 비교

3[주식] Python으로 전 주식 종가/시가/거래량 추출

책 목록

처음 만나는 AI 퀀트 투자: 파이썬과 AI로 투자 아이디어를 검증하는 법

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기