데이터 공부를 기록하는 공간

[파이썬 주식] 변동성돌파전략 - 4. 적정 k값은? 본문

STOCK/변동성돌파전략

[파이썬 주식] 변동성돌파전략 - 4. 적정 k값은?

BOTTLE6 2021. 1. 24. 20:51

변동성 돌파전략을 위한 조건은

1. 목표가 = 시가 + (전날 고가 - 전날 저가)*k

2. 목표가 > 3일 이동평균 종가

적정k값은 무엇인가?

1. 라이브러리 임포트

from pandas_datareader import data as pdr
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
import numpy as np
import time
from pykrx import stock
import seaborn as sns

import matplotlib
from matplotlib import font_manager, rc
import platform
try : 
    if platform.system() == 'Windows':
    # 윈도우인 경우
        font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
        rc('font', family=font_name)
    else:    
    # Mac 인 경우
        rc('font', family='AppleGothic')
except : 
    pass
matplotlib.rcParams['axes.unicode_minus'] = False   

2. 백테스트 함수 정의

def backtest(code, start='2020-01-01'):
    code = str(code)+".KS"

    df = pdr.get_data_yahoo(code, start=start)
    mean = []
    median = []
    std = []
    max_ = []
    min_ = []
    count=[]
    ret = []
    ks = np.arange(0,1,0.1)+0.1

    df['변동폭'] = df['High'] - df['Low']
    df['내일시가']=df['Open'].shift(-1)
    df['3MA'] = df['Close'].rolling(window=3).mean().shift(1)
    df['3std'] = df['Close'].rolling(window=3).std().shift(1)
    df['upper'] = df['3MA'] + df['3std']*2
    보유수익률 = df["Close"][-1]/df["Close"][0]
    for k in ks:

        df['목표가'] = df['Open']+(df['변동폭'].shift(1))*k
        cond = (df['목표가']<df['High']) & (df['목표가']>df['3MA']) #& (df['목표가']>df['upper'])

        df2=df[cond].copy()
        df2['수익률'] = df2['내일시가']/df2['목표가'] - 0.0032

        평균 = df2.수익률.mean()
        표준편차 = df2.수익률.std()
        중앙값 = df2.수익률.median()
        최대값 = df2.수익률.max()
        최소값 = df2.수익률.min()
        누적수익률 = df2.수익률.cumprod()[-1]
        count.append(df2.shape[0])
        mean.append(평균)
        median.append(중앙값)
        std.append(표준편차)
        max_.append(최대값)
        min_.append(최소값)
        ret.append(누적수익률)
    df= pd.DataFrame({"경우의수":count,"평균":mean,"중앙값":median,"표준편차":std,"최대값":max_,"최소값":min_,"누적수익률":ret},index=ks)
    df['lower']=df['평균']-df['표준편차']/df['경우의수']**(1/2)*1.96
    df['upper']=df['평균']+df['표준편차']/df['경우의수']**(1/2)*1.96
    print("보유수익률 : {:.2f}".format(보유수익률))
    lineplot(df,code)

    return df

3. 백테스트 결과 lineplot 정의 (2.보다 먼저 실행해야함)

def lineplot(df,title=""):
        plt.figure(figsize=(10,8))
        plt.title(title)
        plt.subplot(4,1,1)
        df.최대값.plot(c='red')
        df.최소값.plot(c='blue')
        #plt.title("최대vs최대")
        plt.legend()
        plt.subplot(4,1,2)
        df.평균.plot(c='green')
        df.중앙값.plot(c='orange')
        df['lower'].plot(c='b')
        df['upper'].plot(c='r')
        plt.fill_between(df.index, df['upper'],df['lower'],color='0.9')
        #plt.title("평균,중앙")
        #plt.legend(loc='best')
        plt.subplot(4,1,3)
        df.누적수익률.plot.bar()
        #plt.title("누적수익률")
        plt.legend()
        plt.subplot(4,1,4)
        df.경우의수.plot.bar()
        plt.legend()
        #plt.title("경우의수")

4. 백테스트 실행

종목은 지난시간 찾았던 종목을 기준으로 수행

기간은 1년(2020.01.01

)과 3개월(2020.11.01

)

① NH투자증권

df = backtest("005940",start='2020-01-01')
df

df 는 k값에 따라 통계값을 산출한 결과를 보여준다.

아래는 시각화.

df = backtest("005940",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))

일단 2020.01.01부터 현재 2021.01.22일까지를 기준으로

2020.01.01월 100만원 매수하였으면 지금까지 보유하였을 경우 현재 가치는 93만원

k=0.5로 1년동안 감시하여 첫 금액 100만원으로 변동성돌파를 하였을 경우 158만원이 되며,

k=1인 경우 128만원이 된다.

누적 수익률만 보았을 때는 0.5일 경우가 가장 수익률이 좋으며, 1년 중 약 71번의 매수/매도를 수행한다.

수익률의 평균은 신뢰구간 95.4% 하한값은 0.8일때 1.001778로 가장 높다

df = backtest("005940",start='2020-11-01')
df

df = backtest("005940",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))

2020.11.01부터 3개월 테스트를 다시 해보았을 때, 변동성 돌파전략은 보유 수익률을 이기지 못한다.

보유수익률은 118%임에 비해 111%(k=0.5), 106%(k=1)로 저조하다.

② 현대리바트

2020.01.01~

df = backtest("079430",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

보유수익률 121%에 비해 변동성수익률은 172%(k=0.5) 변동성 돌파전략이 더 좋음을 알 수 있다.

다만, k=0.2일때 수익률이 가장 높지만 수익률 최소값은 92.5%로 최소로, 변동성이 매우 크다.

그럼에도 불구하고 신뢰구간 95.4%에 대해 수익률 평균값은 0.2일 때, lower값이 1.002065로 가장 높게 나타난다.

df = backtest("079430",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

3개월 테스트 결과, k=0.6일때 가장 높은 누적수익률과 lower 값을 보여준다.

③ 미원상사

df = backtest("002840",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

보유 수익률보다 변동성 돌파전략 수익률이 낮다.

보유수익률이 더 좋은 종목이어서 그런지

lower값이 모두 1보다 크다.

df = backtest("002840",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

④ SK증권

2020.01.01~

df = backtest("001510",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

2020.11.01~

df = backtest("001510",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

⑤ 휴켐스

2020.01.01~

df = backtest("069260",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

2020.11.01~

df = backtest("069260",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

⑥ 현대글로비스

2020.01.01~

df = backtest("086280",start='2020-01-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

2020.11.01~

df = backtest("086280",start='2020-11-01')
print("누적수익률 : {:.2f}(k=0.5)".format(df.loc[0.5,'누적수익률']))
print("누적수익률 : {:.2f}(k=1.0)".format(df.loc[1,'누적수익률']))
df

5. 느낀점

종목(ex : 미원상사는 -)에 따라

검토기간(1년 vs 3개월)에 따라

k값에 따라 수익률이 달라질 수 있다.

앞선 종목으로 일주일간 거래테스트를 진행해보겠지만 수익률이 어떻게 될지 확신이 서지 않는다.

종목에 대해 주기적으로 변경을 실시해주어야겠다.

Comments