이번 포스팅은 주식장의 영업일과 비영업일을 구분하는 방법에 대한 것입니다.
트레이딩캘린더를 데이터베이스로 만들어 놓으면 주식이나 etf의 과거 기간성과를 쉽게 뽑아낼 수 있다는 장점이 있습니다.
휴일정보는 공공데이터포털(https://www.data.go.kr/data/15012690/openapi.do)에서 openapi를 이용하여 뽑아낼 거구요
나머지 일자는 pandas와 datetime을 통해 생성해보겠습니다.
개발에 앞서 미리 위 사이트에서 apikey를 신청해놓으시기 바랍니다.
- 휴일정보를 데이터프레임으로 반환하기
import requests
import datetime as dt
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime
import time
#데이터를 요청하는 함수
def get_request_query(url, operation, params, serviceKey):
import urllib.parse as urlparse
params = urlparse.urlencode(params)
request_query = url + '/' + operation + '?' + params + '&' + 'serviceKey' + '=' + serviceKey
return request_query
#휴일정보를 받아 처리하는 함수
def get_holiday(year,mykey):
date = []
for month in range(1, 13): #1월부터 12월까지 for문으로 반복
if month < 10:
month = '0' + str(month)
else:
month = str(month)
url = 'http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService'
operation = 'getRestDeInfo'
params = {'solYear': year, 'solMonth': month}
#데이터 request
request_query = get_request_query(url, operation, params, mykey)
get_data = requests.get(request_query)
if get_data.ok==True:
soup = BeautifulSoup(get_data.content, 'html.parser')
item = soup.findAll('item')
#bs4를 통해 item 파싱
for day in item:
#datetime을 이용하여 weekday 생성, 5:토, 6:일
weekday = datetime.strptime(day.locdate.string, '%Y%m%d').weekday()
dailyinfo = [day.locdate.string, weekday,day.datename.string, day.isholiday.string]
#dailyinfo를 date 리스트에 append
date.append(dailyinfo)
#데이터프레임 만들기
df_holiday = pd.DataFrame(date,columns=['logdate', 'weekday','datename', 'isholiday'])
return df_holiday
데이터를 요청하는 get_request_query 함수와 데이터를 핸들링하는 get_holiday 함수를 만들었습니다.
mykey에는 발급받은 일반인증키(encoding key)를 넣으시면 됩니다.
위 함수를 실행하면 아래와 같이 데이터프레임이 생성됩니다.
- 선택 기간의 날짜 생성하기
openapi를 통해 휴일자를 찾았다면 이제 pandas의 기능으로 영업일자를 처리할 것입니다.
def get_date(year):
firstdate = str(year) +'-01-01'
enddate = str(year) + '-12-31'
start_date = pd.to_datetime(firstdate)
end_date = pd.to_datetime(enddate)
# 시작 날짜와 마지막 날짜 사이에 날짜를 생성
df_fulldate = pd.DataFrame()
df_fulldate['logdate'] = pd.date_range(start_date, end_date, freq='d')
df_fulldate['weekday'] = df_fulldate['logdate'].dt.weekday
#weekday가 5 이상이면 주말, 아니면 주중
df_fulldate['datename'] = ["주말" if s >=5 else "주중" for s in df_fulldate['weekday']]
#weekday가 5 이상이면 Y, 아니면 N
df_fulldate['isholiday'] = ["Y" if s >=5 else "N" for s in df_fulldate['weekday']]
df_fulldate['logdate'] = df_fulldate['logdate'].astype(str).str.replace('-','')
return df_fulldate
pandas의 date_range함수를 이용하면 해당 기간동안의 일자를 생성할 수 있습니다.
약간의 데이터 조작을 통해 ['weekday',datename','isholiday'] 컬럼도 생성해줍니다.
그럼 위에서 생성한 df_holiday와 같은 양식의 df_fulldate가 생성됩니다.
- 휴일과 날짜간의 데이터 조합하여 trading calendar만들기
전체 일자와 휴일자가 있다면 이제 트레이딩캘린더를 만들 수 있습니다.
#concat 함수를 통해 데이터 합치기
df_trading_calendar = pd.concat([df_holiday,df_fulldate],axis=0)
#drop_duplicates로 중복제거(keep=first로 해야 휴일이 살아남음)
df_trading_calendar = df_trading_calendar.drop_duplicates(['logdate'], keep = 'first')
#sort_values()를 통해 오름차순 정렬
df_trading_calendar= df_trading_calendar.sort_values(by=['logdate'], axis=0, ascending=True)
df_trading_calendar
우선 pandas의 concat함수를 통해 두 데이터프레임을 합쳐줍니다.
그 뒤 중복제거를 해야하는데요, df_holiday 데이터프레임이 위쪽, df_fulldate가 아래쪽에 있기 때문에 keep='first' 기능을 넣어주어 df_holiday의 데이터가 살아남도록 해야합니다.
그 후 sort_values()함수로 오름차순정렬 해주면 2023년의 트레이딩캘린더가 완성됩니다.
반복문으로 조금만 더 응용하면 매년 조회를 하면서 트레이딩캘린더를 만들 수 있습니다.
아, 그리고 위 코드에 마지막 영업일 휴장정보를 입력하지 않았는데요 데이터프레임 resample기능으로 12월 월말 자료를 추출 후 isholiday를 업데이트 하면되니까 직접 해보시기 바랍니다^^
이번 포스팅은 여기까집니다. 감사합니다
'Programming for trading' 카테고리의 다른 글
[Python] 업비트API로 비트코인 1분봉 가져오기 (0) | 2023.01.17 |
---|---|
[Python] chatGPT 활용기(데이터프레임 replace) (2) | 2023.01.16 |
[Python] 데이터프레임 차집합 구하기 (0) | 2022.12.30 |
[Python] 삼성전자 PER, PBR 웹크롤링 (0) | 2022.12.20 |
[Python] 정규표현식(regular expression) (0) | 2022.12.17 |