파이썬으로 야후파이낸스에서 주가 데이터를 불러오는 방법을 검색해보니 pandas_datareader 패키지를 이용하는 방법이 주로 검색되었다.
그러나 직접해보니 아래와 같은 에러가 발생하고, 아무리 에러 해결법을 찾아보려고 해도 고쳐지지가 않았다....
>>> import pandas_datareader as pdr
>>> from datetime import datetime
>>> print(pdr.__version__)
0.10.0
>>> start_date = datetime(2022,1,1)
>>> end_date = datetime(2022,12,31)
>>> df1 = pdr.DataReader('AAPL', 'yahoo' , start_date, end_date)
Traceback (most recent call last):
~~~
data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"]
TypeError: string indices must be integers
위의 string indices must be integers라는 에러에 대한 해결법들을 실행해봐도 이상하게 난 고쳐지지가 않았다....
그래서 찾은 방법이 아래와 같다.
1. yahoo_fin 패키지 설치
2. ticker 찾기
위 코드에서 첫번째 인수로 들어가는 '^GSPC' 가 어디서 온 값인지 궁금할 수 있다.
일반적으로 해당 종목별 고유코드라고 할 수 있는 티커(ticker)가 존재하며, 야후파이낸스에서는 아래와 같이 찾을 수 있다.
3. 해당 종목의 주가 데이터 불러오기( yahoo_fin.stock_info.get_data )
야후파이낸스에서 S&P 500 지수의 2006년~2007년 정보 가져온 결과는 아래와 같다.
>>> import yahoo_fin.stock_info as si
>>> df = si.get_data('^GSPC', start_date='01/01/2006', end_date='12/31/2007')
>>> df.head()
open high low close adjclose volume ticker
2006-01-03 1248.290039 1270.219971 1245.739990 1268.800049 1268.800049 2554570000 ^GSPC
2006-01-04 1268.800049 1275.369995 1267.739990 1273.459961 1273.459961 2515330000 ^GSPC
2006-01-05 1273.459961 1276.910034 1270.300049 1273.479980 1273.479980 2433340000 ^GSPC
2006-01-06 1273.479980 1286.089966 1273.479980 1285.449951 1285.449951 2446560000 ^GSPC
2006-01-09 1285.449951 1290.780029 1284.819946 1290.150024 1290.150024 2301490000 ^GSPC
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 501 entries, 2006-01-03 to 2007-12-28
Data columns (total 7 columns):
--- ------ -------------- -----
0 open 501 non-null float64
1 high 501 non-null float64
2 low 501 non-null float64
3 close 501 non-null float64
4 adjclose 501 non-null float64
5 volume 501 non-null int64
6 ticker 501 non-null object
dtypes: float64(5), int64(1), object(1)
memory usage: 29.4+ KB
데이터를 조회할 때, get_data 함수 내 start_date와 end_date 인수 값의 형식은 아래 4가지 모두 가능하다.
① 문자열 : 'MM/DD/YYYY'
② 문자열 : 'YYYYMMDD'
③ 문자열 : 'YYYY-MM-DD'
④ 시간형 : datetime.datetime(YYYY, MM, DD)
실제로 아래 예시들을 봤을 때, 잘 작동하는 것을 볼 수 있다.
>>> df = si.get_data('^GSPC', start_date='20060101', end_date='20071231')
>>> df.head()
open high low close adjclose volume ticker
2006-01-03 1248.290039 1270.219971 1245.739990 1268.800049 1268.800049 2554570000 ^GSPC
2006-01-04 1268.800049 1275.369995 1267.739990 1273.459961 1273.459961 2515330000 ^GSPC
2006-01-05 1273.459961 1276.910034 1270.300049 1273.479980 1273.479980 2433340000 ^GSPC
2006-01-06 1273.479980 1286.089966 1273.479980 1285.449951 1285.449951 2446560000 ^GSPC
2006-01-09 1285.449951 1290.780029 1284.819946 1290.150024 1290.150024 2301490000 ^GSPC
>>> df = si.get_data('^GSPC', start_date='2006-01-01', end_date='2007-12-31')
>>> df.head()
open high low close adjclose volume ticker
2006-01-03 1248.290039 1270.219971 1245.739990 1268.800049 1268.800049 2554570000 ^GSPC
2006-01-04 1268.800049 1275.369995 1267.739990 1273.459961 1273.459961 2515330000 ^GSPC
2006-01-05 1273.459961 1276.910034 1270.300049 1273.479980 1273.479980 2433340000 ^GSPC
2006-01-06 1273.479980 1286.089966 1273.479980 1285.449951 1285.449951 2446560000 ^GSPC
2006-01-09 1285.449951 1290.780029 1284.819946 1290.150024 1290.150024 2301490000 ^GSPC
>>> from datetime import datetime
>>> start = datetime(2006,1,1)
>>> end = datetime(2007,12,31)
>>> df = si.get_data('^GSPC', start_date=start, end_date=end)
>>> df.head()
open high low close adjclose volume ticker
2006-01-03 1248.290039 1270.219971 1245.739990 1268.800049 1268.800049 2554570000 ^GSPC
2006-01-04 1268.800049 1275.369995 1267.739990 1273.459961 1273.459961 2515330000 ^GSPC
2006-01-05 1273.459961 1276.910034 1270.300049 1273.479980 1273.479980 2433340000 ^GSPC
2006-01-06 1273.479980 1286.089966 1273.479980 1285.449951 1285.449951 2446560000 ^GSPC
2006-01-09 1285.449951 1290.780029 1284.819946 1290.150024 1290.150024 2301490000 ^GSPC
4. 전처리 및 엑셀 저장
>>> df.to_excel('S&P.xlsx')
저장 후 엑셀 데이터를 확인해보면 다음과 같다.
인덱스가 시간 데이터이다보니 엑셀 데이터의 A열이 시/분/초까지 기재된 것을 볼 수 있다.
그래서 년월일 까지만 따로 추출해서 저장할 필요가 있으며, 가공 순서는 다음과 같다.
① 인덱스를 별도의 컬럼으로 전환 : reset_index()
② 컬럼명 index 를 date로 변경 : rename(columns = {'index' : 'date'})
③ date 컬럼의 데이터 형식이 datetime이므로 문자열로 변환 : apply(lambda x : x.strftime('%Y-%m-%d'))
④ 엑셀 저장시 index는 제외 : to_excel( 'df.xlsx', index = False )
>>> df = si.get_data('^GSPC', start_date='2006-01-01', end_date='2007-12-31')
>>> df = df.reset_index().rename(columns={'index':'date'})
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 501 entries, 0 to 500
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 501 non-null datetime64[ns]
1 open 501 non-null float64
2 high 501 non-null float64
3 low 501 non-null float64
4 close 501 non-null float64
5 adjclose 501 non-null float64
6 volume 501 non-null int64
7 ticker 501 non-null object
>>> df['date'] = df['date'].apply(lambda x: x.strftime('%Y-%m-%d'))
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 501 entries, 0 to 500
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 501 non-null object
1 open 501 non-null float64
2 high 501 non-null float64
3 low 501 non-null float64
4 close 501 non-null float64
5 adjclose 501 non-null float64
6 volume 501 non-null int64
7 ticker 501 non-null object
dtypes: float64(5), int64(1), object(2)
memory usage: 27.5+ KB
>>> df.to_excel('S&P.xlsx', index = False)
'python > 메모장' 카테고리의 다른 글
[Python] 야후파이낸스 주요 지수 티커(ticker) 리스트 (0) | 2023.01.16 |
---|---|
[python] 딕셔너리 포함여부 및 리스트 추가 (0) | 2023.01.08 |
[Python] 딕셔너리 포함여부 및 계산 (0) | 2023.01.08 |
[Python] 딕셔너리 key와 value 바꾸기 및 value로 key 찾기 (1) | 2023.01.08 |
[Python] 리스트, 딕셔너리 순위 매기기 (0) | 2023.01.08 |
댓글