[일상] 이베스트 증권 API를 이용한 자동매매(2)

과거 거래 데이터를 받은 후 전략에 대하여 test를 해 봅니다.

일단 적용해볼 전략은 정액투자법입니다.
정액투자법은 몇 번 소개해 드렸는데요. 특정 종목의 현재 가치를 일정하게 유지하는 전략입니다. 주가가 오르면 그만큼 팔고, 내리면 더 사는 방법으로 아주 간단합니다. 매매 시기도 원하는대로 하면 됩니다. 매일 종가에 해도 되고 주말에 해도 되고, 월말에 해도 됩니다.

시스템트레이딩으로 정액투자법 전략으로 매매를 하는 것으로 가정해보겠습니다. 따라서 매매하는 시기는 별도로 없고 가격을 확인하는 주기에 따라서 조건을 만족하면 자동으로 매매가 되는 방식을 가정하겠습니다.


엑셀에 저장된 과거 주가 데이터를 읽은 후 해당 데이터를 처리하는 좋은 방법이 없는지 찾다보니 Pandas라는 좋은 패키지가 있는 것을 발견했습니다. 그래서 이번 프로젝트는 Pandas를 이용하여 개발을 진행합니다.

pandas API 문서는 아래 사이트를 참고하시면 됩니다.

https://pandas.pydata.org/docs/reference/index.html

우선 pandas를 이용하여 excel 데이터를 읽어옵니다. 이 데이터는 올해 KODEX200 30분 데이터입니다.

아주 간단하군요. 명령어 하나면 됩니다. 그후 일자를 index로 설정합니다.


import pandas as pd
import json
import numpy as np

# daily
df = pd.read_excel(".\\069500-20200101-20200403.xlsx")  
df = df.set_index('date')

시뮬레이션에 사용할 데이터 값, 초기 투입 자금, 매도 조건, 매수 조건을 설정합니다.

### init
init_invest = 1000000
sell_perc = 1.02  # 2%이상이면 매도
buy_perc = 0.98  # 2%이하이면 매수
code = '069500'  # kodex200

1/2일 종가를 최초 매수 가격으로 정하고 매입 수량을 계산합니다.

init_qty = init_invest / df.iloc[0]['close']

pandas 패키지는 저장된 데이터를 다루는데 유용한 것으로 보입니다. column이나 row를 추가하는 것은 문제가 없지만 특정 cell의 값을 변경하는 것은 어렵네요. 방법이 있을 것 같지만 찾는데 너무 시간이 많이 걸려서 일단 list로 계산을 한 후 pandas에 column을 추가하는 형식으로 개발을 진행했습니다.

매매가 발생할 때 변하는 값은 보유수량(qty), 현재가치(cur_value), 매도수량(sell_qty), 매도금액(sell_amount), 매수수량(buy_qty), 매수금액(buy_amount)입니다. 이에 대응하는 list를 만든 후 계산을 합니다.

그리고 어떤 가격으로 매매 결정을 할 것인지도 정해야 하는데, 일단 봉 종가(close) 가격으로 매매를 하는 것으로 가정하겠습니다.

qty = []
cur_value = []
sell_qty = []
sell_amount = []
buy_qty = []
buy_amount = []

pre_qty = init_qty

for i in range(0,len(df)) :
    tuple = df.iloc[i]
    # sell 조건
    if tuple['close']*pre_qty > init_invest * sell_perc :
        sell_vol = (tuple['close']*pre_qty-init_invest)/tuple['close']  # close가격으로 판다
        new_vol = pre_qty - sell_vol
        pre_qty = new_vol
        qty.append(new_vol)
        cur_value.append(new_vol * tuple['close'])
        sell_qty.append(sell_vol)
        sell_amount.append(sell_vol*tuple['close'])
        buy_qty.append(0)
        buy_amount.append(0)
    elif tuple['close']*pre_qty < init_invest * buy_perc :
        buy_vol = (init_invest-tuple['close']*pre_qty)/tuple['close']  # close가격으로 판다
        new_vol = pre_qty + buy_vol
        pre_qty = new_vol
        qty.append(new_vol)
        cur_value.append(new_vol*tuple['close'])
        sell_qty.append(0)
        sell_amount.append(0)
        buy_qty.append(buy_vol)
        buy_amount.append(buy_vol*tuple['close'])
    else :
        qty.append(pre_qty)
        cur_value.append(pre_qty * tuple['close'])
        sell_qty.append(0)
        sell_amount.append(0)
        buy_qty.append(0)
        buy_amount.append(0)

과거 데이터에 대하여 이 루프를 돌고 나면 거래 이력이 각각의 list에 정리가 됩니다. 이 값들을 pandas에 추가합니다.

df['qty'] = qty
df['cur_value'] = cur_value
df['sell_qty'] = sell_qty
df['sell_amount'] = sell_amount
df['buy_qty'] = buy_qty
df['buy_amount'] = buy_amount

매매 결과를 정리해서 출력해줍니다. 매도한 누적 금액(수익), 매수한 누적금액(추가 투자), 매매 횟수 등

profit = df['sell_amount'].sum()  #매도한 누적 금액(수익)
print(profit)
additional_inv = df['buy_amount'].sum()
print(additional_inv)
print("initial: ",  format(int(init_invest), ",d"))
print("additional inv :", format(int(additional_inv),",d"))

num_buy = len(df[df['buy_amount']>0])
num_sell = len(df[df['sell_amount']>0])

print("# trading: buy ",  format(int(num_buy), ",d"), "sell :", format(int(num_sell), ",d"))

최종 거래 데이터를 기반으로 현재까지의 수익률을 구해봅니다.

# 최근 거래데이터로 현 자산 구하기
tuple = df.iloc[len(df)-1]
cur_total = tuple['close'] * pre_qty
diff = cur_total - additional_inv - init_invest + profit
print("profit: ",  format(int(profit), ",d"), "earning :", format(diff/(additional_inv+init_invest)*100, "4.2f"),"%")

그리고 그 결과를 excel 파일에 기록합니다.

df.to_excel('.\\{}.xlsx'.format(code))

pandas를 사용해보니, 조건에 맞는 데이터 처리하는데 아주 좋은 것 같습니다. 블로그에 나오는 다른 시스템트레이딩 프로그램에서도 많이 사용을 하더군요. pandas 좀 더 공부해봐야 할 것 같습니다.

시뮬레이션 결과입니다.

올해 KODEX200 30분 데이타를 기반으로 +- 2%에 매매하는 정액투자법으로 투자를 한 결과 -5.66% 정도의 수익률을 거두고 있습니다. 올 1/2일 종가가 29,465원이고 4/3일 종가가 23,600원입니다. 매매를 하지 않고 계속 들고 있었다면 약 -20% 정도 손실이 발생했습니다. 이에 반해 정액투자법으로 지속적으로 매매를 하니 손실이 많이 줄어들었군요. 물론 484,563원이 추가로 투입되었기 때문에 이런 수익률이 가능했을 것 같습니다.


매매 수수료, 슬리피지 등 추가로 고려해야할 사항들이 더 있지만 일단 대략적인 결과를 확인하는데는 충분할 것 같습니다. 그리고 매매 시점을 결정하는 %에 따라 수익률이 달라질 수 있습니다. 다음에는 % 별로 어떤 차이가 있는지 확인해보겠습니다.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

JCAR 4월 구독보팅입니다.

성투하세요