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

[파이썬 주식] 변동성돌파전략 - 1. 매도시점 = 당일 종가? 익일 시가? 본문

STOCK/변동성돌파전략

[파이썬 주식] 변동성돌파전략 - 1. 매도시점 = 당일 종가? 익일 시가?

BOTTLE6 2021. 1. 23. 21:12

변동성 돌파전략

변동성 돌파전략 나만의 맞춤 알고리즘 만들기 

 

1. 당일 종가매도 vs 익일 시가매도 

2. 매수조건에 알맞는 종목 선정?

 

당일 종가매도 vs 익일 시가매도

  ▶ (결과) 익일 시가 매도

 

(백테스트 조건)

k=0.5

종목 = ['삼성전자', '현대차', '네이버', '대한항공','신풍제약']

 

[라이브러리 임포트]

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   

 

[백테스트 함수 설정]

def backtest(code, k, start='2020-01-01'):
    code = str(code)+".KS"
    df=pd.DataFrame()
    df = pdr.get_data_yahoo(code, start)
    #df
    df['변동폭'] = df['High'] - df['Low']
    df['목표가'] = df['Open'] + df['변동폭'].shift(1)*k
    df['어제종가'] = df['Close'].shift(1)
    df['내일시가'] = df['Open'].shift(-1)
    df['어제거래량'] = df['Volume'].shift(1)
    df['그제거래량'] = df['Volume'].shift(2)
    df['시가-어제종가'] = df['Open']-df['어제종가']
    df['갭상승률'] = df['시가-어제종가']/df['어제종가']
    df['어제거래변동률'] = df['어제거래량'] / df['그제거래량']
    df['MA3_yes'] = df['Close'].rolling(window=3).mean().shift(1)
    df['std3_yes'] = df['Close'].rolling(window=3).std().shift(1)
    df['upper'] = df['MA3_yes']+2*df['std3_yes']
    
    period = df.shape[0] # 기간수
    cond = ( df['High'] > df['목표가'] ) & ( df['목표가'] > df['MA3_yes'] ) &(df['목표가'] > df['upper'])
    df=df[cond]
    num_of_cond = df.shape[0] # 조건만족 수
    df['수익률'] = df['내일시가']/df['목표가'] - 0.0032
    df['수익률_당일'] = df['Close']/df['목표가'] - 0.0032
    df['승패'] = np.where(df['수익률']>1, 1, 0)
    df=df.iloc[:-2]
    승률 = df['승패'].value_counts()[1] / len(df['승패'])
    기간수익률 = df.수익률.cumprod().iloc[-1]
    N = (df.index[-1] - df.index[0]).days / 252
    CAGR = (기간수익률 ** (1/N))-1
    print("종목명 : ", code)
    print("조건 만족 횟수 : {}".format(num_of_cond))
    print("조건 만족 비율 : {:.2f}%".format(num_of_cond/period*100))
    print("조건 승률 : {:.2f}%".format(승률*100))
    print("검토기간 보유 수익률 : {:.2f}%".format((df['Close'][-1]/df['Close'][0]-1)*100))
    print("검토기간 Volatility 수익률 : {:.2f}%".format((df.수익률.cumprod()[-1]-1)*100))
    print("검토기간 Volatility_당일 수익률 : {:.2f}%".format((df.수익률_당일.cumprod()[-1]-1)*100))
    print("연 환산 수익률 CAGR : {:.2f}%".format(CAGR*100))
    print("최대 수익률 : {:.2f}%".format((df.loc[df.수익률.idxmax()].수익률-1)*100),df.수익률.idxmax())
    print("최대 손해율 : {:.2f}%".format((df.loc[df.수익률.idxmin()].수익률-1)*100),df.수익률.idxmin())
    print("-"*50)
    '''
    plt.figure(figsize=(8,8))
    plt.subplot(4,1,1)
    df.Close.plot(color='green')
    df.upper.plot(color='black',style='-')
    plt.subplot(4,1,2)
    df.수익률.plot(color='blue')
    df.수익률.cumprod().plot(color='red')
    df.수익률_당일.cumprod().plot(color='orange',style='-')
    plt.subplot(4,1,3)
    df.수익률.plot.hist(bins=50,color='red')
    plt.subplot(4,1,4)
    df.iloc[-10:].수익률.plot.hist(bins=50,color='blue')
    plt.title("최근10개")
    '''
    return df

[백테스트 실행]

# 익일시가매도? 당일종가매도?
# 2020-01-01~ ,k=0.5일 때 현재까지 다음 5가지 종목의 수익률 비교
codes = ['005930','005380','035420','003490','019170']
for code in codes:
    df = backtest(code,k=0.5,start='2020-01-01')
    time.sleep(1)

[백테스트 결과]

종목명 :  005930.KS
조건 만족 횟수 : 28
조건 만족 비율 : 10.65%
조건 승률 : 50.00%
검토기간 보유 수익률 : 39.43%
검토기간 Volatility 수익률 : 20.77%
검토기간 Volatility_당일 수익률 : 6.49%
연 환산 수익률 CAGR : 14.46%
최대 수익률 : 6.68% 2020-06-03 00:00:00
최대 손해율 : -2.55% 2020-11-24 00:00:00
--------------------------------------------------
종목명 :  005380.KS
조건 만족 횟수 : 33
조건 만족 비율 : 12.55%
조건 승률 : 61.29%
검토기간 보유 수익률 : 80.43%
검토기간 Volatility 수익률 : 33.82%
검토기간 Volatility_당일 수익률 : 11.78%
연 환산 수익률 CAGR : 22.83%
최대 수익률 : 7.66% 2020-03-24 00:00:00
최대 손해율 : -4.80% 2020-07-24 00:00:00
--------------------------------------------------
종목명 :  035420.KS
조건 만족 횟수 : 40
조건 만족 비율 : 15.21%
조건 승률 : 47.37%
검토기간 보유 수익률 : 70.05%
검토기간 Volatility 수익률 : -15.49%
검토기간 Volatility_당일 수익률 : -16.63%
연 환산 수익률 CAGR : -10.75%
최대 수익률 : 7.70% 2021-01-08 00:00:00
최대 손해율 : -9.47% 2020-03-20 00:00:00
--------------------------------------------------
종목명 :  003490.KS
조건 만족 횟수 : 41
조건 만족 비율 : 15.59%
조건 승률 : 64.10%
검토기간 보유 수익률 : 20.63%
검토기간 Volatility 수익률 : 79.86%
검토기간 Volatility_당일 수익률 : -17.90%
연 환산 수익률 CAGR : 49.81%
최대 수익률 : 17.56% 2020-11-09 00:00:00
최대 손해율 : -9.52% 2020-08-07 00:00:00
--------------------------------------------------
종목명 :  019170.KS
조건 만족 횟수 : 42
조건 만족 비율 : 15.97%
조건 승률 : 55.00%
검토기간 보유 수익률 : 1960.09%
검토기간 Volatility 수익률 : 319.26%
검토기간 Volatility_당일 수익률 : 95.89%
연 환산 수익률 CAGR : 210.27%
최대 수익률 : 37.15% 2020-02-05 00:00:00
최대 손해율 : -12.45% 2020-03-13 00:00:00
--------------------------------------------------

백테스트 결과, 

보유수익률보다는 좋지 않지만, 

Volatility 수익률 (=익일시가 매도) 가 

Volatility_당일 수익률(=당일종가 매도) 매도 보다는 수익률이 좋다. 

 

앞으론 익일 시가 매도를 기준으로 백테스트 진행해보자.

Comments