퀀트투자 - 백테스트 할 날짜 가져오기
본문 바로가기
파이썬으로 만든 것들/퀀트투자

퀀트투자 - 백테스트 할 날짜 가져오기

by Squat Lee 2022. 10. 3.

백테스트를 하기 위해서는 날짜가 필요하다. 내가 투자를 하고나서 일정시점 또는 기간 동안에 수익을 확인해야지 내가 하려는 방법이 옳은지 그른지 판단이 선다.

 

주식시장은 영업일에만 개장한다. 수익을 확인하기 위해서는 해당일의 종가를 알아야 하고, 해당일이 영업일이 아니면 종가를 가져오지 못한다.

 

pykrx에서는 영업일만 가져오는 함수가 있어서 문제가 없었다. 또한, 특정기간 예를들어 한달에 1번 수익률을 구하는 것이 가능했다.

 

하지만, 영업일을 DB로 가져오고 나서 기간별 수익률을 확인하려고 하니 방법을 모르겠다.

 

열심히 고민을 한 끝에 리스트로 만들기로 했다.

con = sqlite3.connect('krx_data.db')
df_dates = pd.read_sql("SELECT * FROM dates", con)
date_list = df_dates['일자'].to_list()

DB에 날짜 Data만 저장한 테이블이 있고, 날짜를 포함한 Fundamental을 저장한 테이블이 각각 있다.

 

Fundamental에서 날짜 컬럼만 불러와서 리스트로 만들려고 하니 그 테이블 자체가 무거워서 그런지 작동시간이 느렸다. 그래서 dates 테이블에서 날짜를 가져와서 리스트로 만들었다.

 


그 다음은 이 날짜 리스트를 년도별 리스트로 묶어주고, 다시 월별 리스트로 묶어주면 백테스트 기간 설정이 가능할 것 같다.

 

매월 첫째 또는 중간, 말일 등 내가 원하는 기간에 종목선정이 가능하고 거기에 따른 1년동안 수익률도 확인이 가능하다.

 

# 리스트를 연도별로 저장하기
year =[] #연도만 추출할 List - Step 1 , 2003, 2003, 2003,...
for y in date_list:
    year.append(y[:4])

우선 연도만 추출해서 리스트에 담는다. 2003, 2004,.... 이런식으로 하지만 실제 2003,,2003, 2003,... 이런식으로 중복값이 나온다.

new_y = [] #중복값 제거한 List, 2003, 2004, ...
for ny in year:
    if ny not in new_y:
        new_y.append(ny)

그래서 중목값을 제거했다. 그리고 new_y라는 새로운 변수에 리스트를 담는다.

 

# 연도별로 List 담기 [[20030103, 20030106,...],[20040103,..],...]
yearly_list=[]
for n, dy in enumerate(new_y):
    d_list = []
    for d in date_list:
        if dy == d[:4]:
            d_list.append(d)
    yearly_list.append(d_list)

그 다음에는 new_y 에 담긴 연도와 전체 날짜 리스트를 비교해서 연도별로 리스트를 분리해준다.

 

for 문에서 내가 왜 'enumerate'를 썼는지 모르겠다. 굳이 그럴필요가 없는 것 같은데...

 

# 월별로 List 담기 [[20030103,...],[20030203,...]..]
monthly_list = []
for dy in yearly_list:
 
    for m in range(113):  # 1월부터 12월까지
        m_list = []
        for y in dy: #[20030103, 20030104,...]
            if m == int(y[4:6]):
                m_list.append(y)
        monthly_list.append(m_list)

그리고 월별 리스트도 별도로 담는다. 방법은 같다. 1월~12월까지 반복문을 사용해서 달별로 리스트를 분리한다.

 

연도별 리스트와 월별 리스트가 백테스트 할때 둘다 필요할 것 같다.

 

결과는 위와 같이 출력이 된다.

 

전체 코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import sqlite3
import pandas as pd
 
#전역변수 선언
global df_data
global date_list
 
con = sqlite3.connect('krx_data.db')
df_dates = pd.read_sql("SELECT * FROM dates", con)
date_list = df_dates['일자'].to_list()
 
date = '20030103'
 
df = pd.read_sql("SELECT * FROM fundamental WHERE 일자==" + date, con)
 
# 리스트를 연도별로 저장하기
year =[] #연도만 추출할 List - Step 1 , 2003, 2003, 2003,...
for y in date_list:
    year.append(y[:4])
 
new_y = [] #중복값 제거한 List, 2003, 2004, ...
for ny in year:
    if ny not in new_y:
        new_y.append(ny)
 
# 연도별로 List 담기 [[20030103, 20030106,...],[20040103,..],...]
yearly_list=[]
for n, dy in enumerate(new_y):
    d_list = []
    for d in date_list:
        if dy == d[:4]:
            d_list.append(d)
    yearly_list.append(d_list)
 
# 월별로 List 담기 [[20030103,...],[20030203,...]..]
monthly_list = []
for dy in yearly_list:
 
    for m in range(113):  # 1월부터 12월까지
        m_list = []
        for y in dy: #[20030103, 20030104,...]
            if m == int(y[4:6]):
                m_list.append(y)
        monthly_list.append(m_list)
 
print(monthly_list)
cs

 

 

728x90
반응형

댓글