PYTHON/Back test

2.3 백테스팅하기 - 종목 선정하기 (1)

  • -

지난 게시글에서는 종목별 데이터들을 하나의 변수로 모아 종목별 변수들을 구축했으니, 이번 게시글에서는 그 종목별 변수들을 대상으로 백테스팅을 진행할 종목을 선정할 예정이다. 종목 선정 기준은 무엇으로 설정해야 할지에 대한 고민은 개개인 모두가 다르겠지만, 여러 가지 조건들을 설정해서 종목을 선정할 수 있다는 것만큼은 확실하다.

여기서 어떤 기준 하에 종목을 선정할 것인지와 같은 세부적인 기준들은 개개인이 설정할 일이고, 본인이 게시글 본문에서 사용하는 기준들은 모두 개인적인 기준이니 만큼 '이렇게 하면 수익이 나나?'하는 생각은 지양하고 읽어주길 바란다. 설령 이 기준이 수익이 날 수 있는 종목을 골라주는 기준이라 하더라도, 그를 바탕으로 거래를 해왔던 사람만 수익을 낼 수 있지 그렇지 않았던 사람이라면 수익을 낼 수 없다. 이 사실 하나 만큼은 모든 것을 걸고 장담할 수 있다.
※ 여태까지 한 번도 하지 않았던 말을 여기서 하는 이유는, 이륿 바탕으로 금전적 손실이 발생한 분에 대한 책임을 져드릴 수 없기 때문이다. 본인의 입장에선 아주 작은 일말의 희망을 갖고 후회활 행동을 하지 않는 사람이길 빌 뿐이다.

 

 

[파일명 : algorithm_1] 종목 선정 기준 설정해보기

본 예제에서 사용할 종목 선정 기준은 단순하다. 일단 선정 기준을 두 가지로 나누어서 종목을 선정할 예정이다.
※ 본인이 구축하고자 하는 시뮬레이션의 대상이 되는 종목을 선정할 본인만의 기준이 있다면 그걸 사용하자.

  • 고가 상승률 15% 이상
  • 거래량 500만주 이상
  • 거래대금 200억 이상

 

일단 첫 번째 선정 기준부터 작성해보도록 하자. 종목을 선정하는 함수는 def select_item()이라는 이름으로 제작할 예정인데, 여기서 주의해야 할 부분이 있다. 바로 이전 게시글에서 날짜를 계산하기 위해 제작했던 while문 하단에서 이 함수를 실행해야 한다는 것이다. 그 이유를 살펴보면 간단하다. 하루 동안 종목을 선정한 후에 다음 날로 넘어가서 다음 날의 종목을 선정해야 하기 때문이다. 
※ 추가된 코드 : 2번째 줄

while self.today <= end_date:
    self.select_item()
    self.today = calf.cal_addday(self.today, 1)

 

 


728x90

 

 

[파일명 : algorithm_1] 종목 선정 기준 코드 제작하기

종목 선정 기준을 설정하기 위해서는 일단 앞서 제작한 종목별 변수를 대상으로 for문을 실행해야 하는데, 이것 역시 상당히 간단하게 코드를 제작할 수 있다. 
※ 추가된 코드 : 1, 2번째 줄

def select_item(self):
    for i in globals():

 

하지만 위와 같이 작성할 경우에 발생하는 문제점이 있다면, 해당 파일에서 설정된 모든 전역변수가 모두 출력된다는 것이다. 따라서 여기서 종목별 변수만을 가져오기 위해서는 조건문을 통해 변수의 이름을 걸러내야 한다. 다행히도 종목별 변수의 이름에는 공통점들이 있다. 바로 맨 첫 번째 자리에는 's'라는 문자열이 온다는 것과 맨 끝 자리에는 '0'이라는 문자열이 온다는 것이다. 다시 말해, 모든 종목 코드들이 sXXXXX0과 같은 형태로 이루어져 있다는 것이다. 따라서 조건문을 아래와 같이 제작해주면   item_code  변수에는 's'를 제외한 종목코드만,   _day_dataframe  변수에는 종목코드의 주가 데이터를 저장할 수 있다.
※ 추가된 코드 : 4, 5번째 줄

def select_item(self):
    for i in globals():
        if str(i)[0] == 's' and str(i)[-1] == '0':
            item_code = i[1:]
            _day_dataframe = globals()[i]

 

그렇다면 이제 종목별 주가 데이터를 불러왔으니, 우리가 현재 조회하고 있는 일자(예를 들면 20210101)에 해당하는 주가 데이터를 가지고 와야 한다. 다시 말해, 2021년 1월 1일에 해당하는 거래량이나 저가 고가 등의 데이터를 가지고 와야만 상승률과 같은 종목 선정 기준을 적용할 수 있다는 것이다.
※ 추가된 코드 : 6번째 줄

def select_item(self):
    for i in globals():
        if str(i)[0] == 's' and str(i)[-1] == '0':
            item_code = i[1:]
            _day_dataframe = globals()[i]
            _today_volume = int(_day_dataframe.volume[(_day_dataframe['date'] == self.today)].to_list()[0])

6번째 줄의 코드를 보면 다소 복잡하게 이루어져있는 것 같지만 그 구조를 보면 의외로 간단하다. 대괄호 안에 있는   (_day_dataframe['date'] == self.today)   부분을 보면, _day_dataframe이라는 변수 안에 입력되어 있는 데이터프레임 형태의 데이터에서 칼럼명인 ['date']가 self.today와 같은 데이터열을 가리키는 것이다. 이제 그 앞 부분의   _day_dataframe.volume  을 보면 뒤의 대괄호 안에 있는 조건에 맞는 데이터열의 volume을 가리키는 것이다. 다시 말해,   _day_dataframe.volume[(_day_dataframe['date'] == self.today)]  라는 부분은 20210101의 거래량을 가져오라는 것이다. 그 맨 앞에 있는 int()는 기본적으로 문자열 타입의 자료형인 거래량 데이터를 숫자로 바꿔주기 위함이고, 맨 뒤에 있는 .to_list() 메서드는 가져온 데이터들을 리스트 형태로 바꾸어주라는 것이다. 맨 뒤에 보면 [0]이 있는데, 가져온 데이터를 리스트형태로 바꾼 후에 가장 맨 앞에 있는 데이터(거래량 데이터)를 대상으로 자료형을 숫자형으로 바꾸라는 코드인 것이다. 거래량 데이터는 숫자형 타입이어야만 대소를 비교할 수 있기 때문이다.

 

 


728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.