Programming for trading

[Python] OpenAPI로 주식 영업일, 휴장일 구하기

quantoasis 2022. 12. 31. 13:46
반응형


이번 포스팅은 주식장의 영업일과 비영업일을 구분하는 방법에 대한 것입니다.

트레이딩캘린더를 데이터베이스로 만들어 놓으면 주식이나 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를 업데이트 하면되니까 직접 해보시기 바랍니다^^


이번 포스팅은 여기까집니다. 감사합니다

반응형