[python] 야후 파이낸스 API로 월간 평균 주가 데이터 만들기

Heesu Ahn·2022년 10월 28일
1

python

목록 보기
1/1
post-thumbnail

이미 프로젝트를 끝낸 후 포스팅을 하고 있어서 코드 리뷰는 다른 시리즈에 올리겠습니다. 대충 비상장주식으로 분석하려다가 데이터 부족을 느끼고 상장주식으로 프로젝트를 분석하는 애용입니다.

이번 프로젝트는 야후파이낸스API를 통해 주가 등의 데이터를 불러왔습니다.

(원래 FinanceDataReader(as fdr) API에서 가져왔는데 오류가 나서 대체..)

방법은 두 라이브러리 모두 거의 비슷해서 둘 중 한 API가 고장나면 대체해서 쓰면 되는 듯 합니다.

주식 데이터 불러오기

먼저 라이브러리를 설치합니다.

!pip install pandas_datareader
!pip install yfinance

야후파이낸스 API(yf)가 야후로부터 데이터 획득 방식을 크롤링으로 변경하고 pandas_datareader(pdr)가 데이터를 불러오게 됩니다.

# 라이브러리 불러오기
import yfinance as yf
from pandas_datareader import data as pdr
import pandas as pd

# 야후로부터 데이터 획득 방식을 크롤링으로 변경
yf.pdr_override()

# 해당 종목의 데이터 불러오기(이마트 주식)
df_stock = pdr.get_data_yahoo('139480.KS', start='2000-01-01', end='2022-08-31')
df_stock.head()
  • .pdr_override() 는 데이터 획득 방식을 크롤링으로 변경하는 yfinance의 함수

  • .get_data_yahoo() 는 해당 종목의 주식데이터를 날짜를 정해서 불러오는 함수 입니다.

    종목코드와 찾을 데이터의 시작 날짜, 마지막 날짜를 파라미터로 작성하면 됩니다.
    pdr.get_data_yahoo(’종목’, start=’시작 날’, end=’마지막 날’)

  • 종목의 경우 주식도 가능하지만 ^KS11 식으로 KOSPI지수의 데이터도 가져올 수 있습니다.

  • 이 파라미터에서 end 가 없다면 시작 날부터 오늘까지의 데이터를 가져옵니다.

  • 만약, start를 많이 앞에 설정했는데 상장을 그 이후에 해서 설정일과 상장일 사이에 데이터가 없다면 위에 표처럼 생략하고 나옵니다.(이마트는 2011년 5월 3일에 상장합니다.)

  • 여러 종목의 데이터를 불러올 때는 종목코드 들의 리스트를 파라미터로 넣습니다.

ex )

df_stock = pdr.get_data_yahoo(['AAPL', 'F'], start='2015-01-01', end='2022-08-31')
df_stock.head()

  • Ticker() : 미국 주식은 종목코드가 아닌 식별코드인 티커를 사용하고 있고,그것을 통해 주식 정보를 크롤링하는 함수입니다.

yf.Ticker('139480.KS')
# yfinance.Ticker object <139480.KS> # 데이터 형태, 딕셔너리 형태의 데이터입니다.
yf.Ticker('139480.KS').info # Ticker 안에 담긴 내용을 출력합니다.

# 판다스 데이터프레임 형태로 주요 정보를 불러올 수 있습니다.
yf.Ticker('139480.KS').actions # 배당, 주식 분할 사례를 불러옵니다.
yf.Ticker('139480.KS').dividends # 배당
yf.Ticker('139480.KS').splits # 주식 분할
yf.Ticker('139480.KS').financials # 회사 재무제표
yf.Ticker('139480.KS').major_holder # 주주정보
yf.Ticker('139480.KS').institutional_holders # 기관투자자
yf.Ticker('139480.KS').balance_sheet # 대차 대조표
yf.Ticker('139480.KS').cashflos # 현금흐름표
yf.Ticker('139480.KS').earnings # 기업 실적

주식 데이터 가공

저는 주가와 코스피 지수를 , 코스피 지수 월평균값 변화율보다 주가 월평균값 변화율이 작다면 주가 하락세라는 라벨을 주려고 했습니다.

즉, 주가 기울기가 코스피 기울기보다 작으면 주가 수익률이 코스피 수익률보다 낮다고 가정하는 것입니다. 이를 yfinance를 이용하여 구현해보겠습니다.

import yfinance as yf
from pandas_datareader import data as pdr
import pandas as pd

# 시각화
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib import rc

yf.pdr_override()
# 해당 종목의 주가 데이터, 코스피 데이터 종가 불러오기
df = pdr.get_data_yahoo(['139480.KS','^KS11'], start='2018-01-01', end='2022-08-31')

# index로 지정된 날짜 열을 풀어줍니다. 
df = df_stock.reset_index()

# 필요한 종가 열만을 취하고 열 이름을 재지정 해줍니다. 
# 재지정 안 해주면 multi-index 형태로 되어있습니다.
df = df_stock[['Date','Close']]
df.columns=['date', 'price', 'kospi지수']

# date 열의 데이터 형식을 날짜로 바꿔주고 '년, 월'만 남기도록 dt.striftime()함수 사용
df.date = pd.to_datetime(df.date)
df['date'] = df['date'].dt.strftime('%Y-%m')

# groupby함수로 '년, 월'이 같은 행들 묶어서 각 열 평균값으로 대체
df1 = pd.DataFrame(df_stock.groupby('date')['price'].mean())
df1 = df1.reset_index()
df2 = pd.DataFrame(df_stock.groupby('date')['kospi지수'].mean())
df2 = df2.reset_index() 
df = df1.merge(df2, how='left')
df.head()

from sklearn.preprocessing import MinMaxScaler

# MinMaxScaler로 price, kospi 데이터 정규화
df = df.set_index('date')
scaler = MinMaxScaler()
scaler.fit(df)
scaled = scaler.transform(df)
df_scaled = pd.DataFrame(scaled, columns=['pricemm','kospimm'])
df = df.reset_index('date')
df_scaled.insert(0,'date', df['date'] )

df = df.merge(df_scaled,how='left')
df.head()

print(df.head())

# 주가, 코스피 MinMax 비교 그래프
plt.figure(figsize=(16, 5))
plt.rcParams['font.family'] = 'AppleGothic'
plt.rcParams['font.size'] = 9

sns.lineplot(data=df, x="date", y="pricemm", label='price_minmax')
sns.lineplot(data=df, x="date", y="kospimm", label='kospi_minmax')

plt.ylabel('')
plt.xticks(rotation=45)

plt.show()

여기까지 하면 주가와 코스피의 기울기 비교를 할 사전 전처리는 마쳤습니다.

기울기는 (현재 달의 값)-(지난 달의 값) / 2-1 을 주가, 코스피 각각 계산한 열을 만들어 줍니다.


# 기울기 열을 만드는 for문
for i in range(55):
    df.loc[i+1,'price_slope'] = df.loc[i+1,'pricemm']-df.loc[i,'pricemm']
    df.loc[i+1,'kospi_slope'] = df.loc[i+1,'kospimm']-df.loc[i,'kospimm']

df = df.bfill()

# 주가 하락세 열을 만드는 for문
for i in range(56):
    df.loc[i,'k_s - p_s'] = df.loc[i,'kospi_slope'] - df.loc[i,'price_slope']

    if df.loc[i,'price_slope'] < df.loc[i,'kospi_slope']:
        df.loc[i, 'downturn'] = 1
    else:
        df.loc[i, 'downturn'] = 0

print(df.head())

# 주가 하락세와 하락 정도 그래프
plt.figure(figsize=(16, 5))
plt.rcParams['font.family'] = 'AppleGothic'

sns.scatterplot(data=df, x="date", y="downturn", label='주가 하락세', color="#FF73B8")
sns.lineplot(data=df, x="date", y="pricemm", label='price_minmax')
sns.lineplot(data=df, x="date", y="kospimm", label='kospi_minmax')
sns.lineplot(data=df, x="date", y="k_s - p_s", label='하락정도')

plt.ylabel('')
plt.xticks(rotation=45)

plt.show()

이렇게 직접 내린 정의로 주가하락세를 알아보는 코드를 짜봤습니다.

다음엔 직접 경제관련 feature들을 붙이고 이 주가하락세를 예측해보겠습니다.

profile
AI로 데이터를 말하는 개발자

0개의 댓글